feat(ci): Setup CI workflow with code generation test suite #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Backend-CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v3 | |
| with: | |
| version: 9.10.0 | |
| - name: Get pnpm store directory | |
| id: pnpm-cache | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT | |
| - name: Setup pnpm cache | |
| if: false | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') || github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Install dependencies | |
| run: pnpm install | |
| - name: Install turbo | |
| run: pnpm add turbo@latest -g | |
| - name: Clean previous builds | |
| run: | | |
| rm -rf packages/*/dist | |
| rm -rf packages/*/node_modules/.cache | |
| - name: Build | |
| run: turbo build | |
| - name: Check files after build | |
| run: | | |
| find packages/backend/dist -type f | grep -i openai | |
| ls -la packages/backend/dist/config/provider || echo "Directory does not exist" | |
| - name: Debug module resolution | |
| run: | | |
| cd packages/ingester | |
| NODE_PATH=../.. node -e "try { const path = require.resolve('@cairo-coder/backend/config/provider/openai'); console.log('Module found at:', path); } catch(e) { console.log('Module not found:', e.message); console.log('Available modules:', require('fs').readdirSync('../backend/dist/config').join(', ')); }" | |
| - name: Create config file | |
| run: | | |
| mkdir -p packages/agents | |
| cat > packages/agents/config.toml << 'EOL' | |
| [API_KEYS] | |
| OPENAI = "${{ secrets.OPENAI }}" | |
| ANTHROPIC = "${{ secrets.ANTHROPIC }}" | |
| GEMINI = "${{ secrets.GEMINI }}" | |
| [VECTOR_DB] | |
| POSTGRES_USER = "${{ secrets.POSTGRES_USER }}" | |
| POSTGRES_HOST = "postgres" | |
| POSTGRES_ROOT_DB = "${{ secrets.POSTGRES_ROOT_DB }}" | |
| POSTGRES_PASSWORD = "${{ secrets.POSTGRES_PASSWORD }}" | |
| POSTGRES_PORT = "${{ secrets.POSTGRES_PORT }}" | |
| [GENERAL] | |
| PORT = 3001 | |
| SIMILARITY_MEASURE = "cosine" | |
| [HOSTED_MODE] | |
| DEFAULT_CHAT_PROVIDER = "gemini" | |
| DEFAULT_CHAT_MODEL = "Gemini Flash 2.5" | |
| DEFAULT_FAST_CHAT_PROVIDER = "gemini" | |
| DEFAULT_FAST_CHAT_MODEL = "Gemini Flash 2.5" | |
| DEFAULT_EMBEDDING_PROVIDER = "openai" | |
| DEFAULT_EMBEDDING_MODEL = "Text embedding 3 large" | |
| [VERSIONS] | |
| STARKNET_FOUNDRY = "0.37.0" | |
| SCARB = "2.9.2" | |
| EOL | |
| - name: Create env file | |
| run: | | |
| cat > .env << 'EOL' | |
| POSTGRES_USER = "${{ secrets.POSTGRES_USER }}" | |
| POSTGRES_HOST = "localhost" | |
| POSTGRES_ROOT_DB = "${{ secrets.POSTGRES_ROOT_DB }}" | |
| POSTGRES_PASSWORD = "${{ secrets.POSTGRES_PASSWORD }}" | |
| POSTGRES_PORT = "${{ secrets.POSTGRES_PORT }}" | |
| EOL | |
| - name: Run unit tests | |
| run: pnpm run test:unit | |
| - name: Build docker image | |
| run: docker build -t cairo-coder-backend:${{ github.sha }} -f backend.dockerfile . | |
| - name: Run backend and database integration tests | |
| run: | | |
| docker compose up -d postgres backend | |
| echo "Waiting for services to be ready..." | |
| sleep 20 | |
| chmod +x ./tests/integration-tests.sh | |
| chmod +x ./tests/database-connection.sh | |
| echo -e "\n=== Running basic integration tests ===" | |
| ./tests/integration-tests.sh | |
| INTEGRATION_RESULT=$? | |
| echo -e "\n=== Running database connection test via chat/completions endpoint ===" | |
| ./tests/database-connection.sh | |
| DB_CONNECTION_RESULT=$? | |
| if [ $INTEGRATION_RESULT -ne 0 ] || [ $DB_CONNECTION_RESULT -ne 0 ]; then | |
| echo "❌ Integration tests failed!" | |
| exit 1 | |
| else | |
| echo "✅ All integration tests passed!" | |
| fi | |
| - name: Build ingester image | |
| run: docker compose --profile ingester build ingester | |
| - name: Run data ingestion | |
| run: docker compose --profile ingester up -d ingester | |
| - name: Import snak repository | |
| run: | | |
| mkdir -p ./snak | |
| git clone https://github.com/KasarLabs/snak ./snak | |
| cd ./snak | |
| git checkout fix/server-for-reuse | |
| - name: Create snak env file | |
| run: | | |
| cd ./snak | |
| cat > .env << 'EOL' | |
| STARKNET_PUBLIC_ADDRESS="${{ secrets.STARKNET_PUBLIC_ADDRESS }}" | |
| STARKNET_PRIVATE_KEY="${{ secrets.STARKNET_PRIVATE_KEY }}" | |
| STARKNET_RPC_URL="${{ secrets.STARKNET_RPC_URL }}" | |
| AI_PROVIDER_API_KEY="${{ secrets.OPENAI }}" | |
| AI_MODEL="claude-3-5-sonnet-latest" | |
| AI_PROVIDER="anthropic" | |
| NODE_ENV="development" | |
| SERVER_API_KEY="${{ secrets.SNAK_SERVER_KEY }}" | |
| SERVER_PORT="${{ secrets.SNAK_SERVER_PORT }}" | |
| POSTGRES_USER="${{ secrets.POSTGRES_USER }}" | |
| POSTGRES_PASSWORD="${{ secrets.POSTGRES_PASSWORD }}" | |
| POSTGRES_ROOT_DB="${{ secrets.POSTGRES_ROOT_DB }}" | |
| POSTGRES_HOST="localhost" | |
| POSTGRES_PORT="${{ secrets.POSTGRES_PORT }}" | |
| CAIRO_UPLOAD_DIR="plugins/cairocoder/uploads/" | |
| CAIRO_GENERATION_API_URL="http://127.0.0.1:3001/chat/completions" | |
| EOL | |
| - name: Cache snak node modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: ./snak/node_modules | |
| key: ${{ runner.os }}-snak-modules-${{ hashFiles('./snak/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-snak-modules- | |
| - name: Install snak dependencies | |
| run: | | |
| cd ./snak | |
| pnpm install --filter="@snakagent/server..." | |
| - name: Start snak server | |
| run: | | |
| cd ./snak | |
| pnpm run build --filter="@snakagent/server..." && lerna run start --scope "@snakagent/server" & | |
| echo "Waiting for server to start..." | |
| sleep 30 | |
| - name: Create cairo code generation test env file | |
| run: | | |
| cd ./packages/agents | |
| cat > .env.test << 'EOL' | |
| API_KEY="${{ secrets.SNAK_SERVER_KEY }}" | |
| API_URL="http://localhost:${{ secrets.SNAK_SERVER_PORT }}" | |
| EOL | |
| - name: Run cairo code generation test | |
| run: | | |
| mkdir -p test-logs | |
| JEST_VERBOSE=true pnpm run test:code-quality -- --verbose 2>&1 | tee test-logs/test-output.log | |
| TEST_RESULT=$? | |
| pkill -f "start:server" || true | |
| if [ $TEST_RESULT -ne 0 ]; then | |
| echo "❌ Test de génération de code Cairo échoué! Détails:" | |
| echo "----------------------------------------------------" | |
| # Afficher les tests qui ont échoué | |
| echo -e "\n🔍 Tests échoués:" | |
| grep -A 5 "FAIL " test-logs/test-output.log || echo "Aucune information d'échec de test trouvée" | |
| # Afficher les erreurs détaillées | |
| echo -e "\n🛑 Détails des erreurs:" | |
| grep -A 20 -B 2 "Error:" test-logs/test-output.log || echo "Aucun détail d'erreur trouvé" | |
| # Afficher le résumé des tests | |
| echo -e "\n📊 Résumé des tests:" | |
| grep -A 5 "Test Suites:" test-logs/test-output.log || echo "Aucun résumé de test trouvé" | |
| # Échec explicite | |
| exit 1 | |
| else | |
| echo "✅ Test de génération de code Cairo réussi!" | |
| fi | |
| # - name: Push docker image | |
| # run: docker push ${{ github.repository }}:${{ github.sha }} |