name: CI on: push: branches: [main] pull_request: branches: [main] jobs: test: name: lint + typecheck + tests runs-on: docker container: image: node:22-bookworm-slim services: postgres: image: postgres:16-alpine env: POSTGRES_DB: agenthub_test POSTGRES_USER: agenthub POSTGRES_PASSWORD: test_password options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - name: Cache npm uses: actions/cache@v4 with: path: ~/.npm key: npm-${{ hashFiles('package-lock.json') }} restore-keys: npm- - name: Install run: npm ci - name: Lint run: npm run lint - name: Format check run: npm run format:check - name: Typecheck run: npm run typecheck - name: Setup test database env: POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_DB: agenthub_test POSTGRES_USER: agenthub POSTGRES_PASSWORD: test_password JWT_SECRET: test-jwt-secret-for-ci-minimum-32-chars-required run: npm run migrate - name: Test env: POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_DB: agenthub_test POSTGRES_USER: agenthub POSTGRES_PASSWORD: test_password REDIS_HOST: redis REDIS_PORT: 6379 JWT_SECRET: test-jwt-secret-for-ci-minimum-32-chars-required NODE_ENV: test LOG_LEVEL: error run: npm test build: name: docker build + push needs: test if: github.ref == 'refs/heads/main' runs-on: docker services: postgres: image: postgres:16-alpine env: POSTGRES_DB: agenthub POSTGRES_USER: agenthub POSTGRES_PASSWORD: test_password options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - name: Login to registry.barodine.net run: | if [ -n "${{ secrets.REGISTRY_PASSWORD }}" ]; then echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.barodine.net \ -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin else echo "REGISTRY_PASSWORD secret not set — skipping push" exit 0 fi - name: Build image run: docker build -t registry.barodine.net/agenthub:${{ github.sha }} -t registry.barodine.net/agenthub:dev . - name: Smoke test — verify image starts and healthcheck passes run: | # Run container in background docker run -d --name agenthub-smoke \ --network ${{ job.container.network }} \ -e DATABASE_URL="postgresql://agenthub:test_password@postgres:5432/agenthub" \ -e REDIS_URL="redis://redis:6379" \ -e JWT_SECRET="test-jwt-secret-for-smoke-minimum-32-chars-required" \ -e LOG_LEVEL=info \ registry.barodine.net/agenthub:${{ github.sha }} # Wait for container to be healthy (max 30s) timeout=30 elapsed=0 while [ $elapsed -lt $timeout ]; do if docker inspect --format='{{.State.Health.Status}}' agenthub-smoke 2>/dev/null | grep -q healthy; then echo "✅ Container is healthy" docker logs agenthub-smoke docker stop agenthub-smoke docker rm agenthub-smoke exit 0 fi sleep 2 elapsed=$((elapsed + 2)) done echo "❌ Container failed to become healthy within ${timeout}s" docker logs agenthub-smoke docker stop agenthub-smoke docker rm agenthub-smoke exit 1 - name: Push image run: | if [ -n "${{ secrets.REGISTRY_PASSWORD }}" ]; then docker push registry.barodine.net/agenthub:${{ github.sha }} docker push registry.barodine.net/agenthub:dev fi # deploy-lan (Phase 1): activé manuellement via SSH ou job dédié — voir ADR-0004. # deploy-coolify (Phase 2): activé lors de la migration Coolify — voir ADR-0004.