CI/CD et Agents

Intégrer CI/CD avec le développement assisté par IA

Ce chapitre explore comment combiner la puissance des agents de code avec l’automatisation CI/CD pour créer un workflow robuste.

La CI comme filet de sécurité

Quand vous vibe codez, la CI/CD devient votre garde-fou :

Vous → Agent → Code généré → Push → CI vérifie
                                      │
                              ┌───────┴───────┐
                              │               │
                           ✅ Pass         ❌ Fail
                              │               │
                           Merge          Fix & retry

Pourquoi c’est crucial

  1. L’agent peut introduire des bugs subtils que vous ne détectez pas à la relecture
  2. Les tests automatisés vérifient ce que l’œil humain peut manquer
  3. La cohérence est garantie même quand vous “Accept All”
  4. La documentation : les workflows CI documentent vos standards

Architecture recommandée

Pipeline standard pour vibe coders

# .github/workflows/ci.yml
name: Vibe Coder CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  # Stage 1: Vérifications rapides
  quick-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npm run typecheck

      - name: Format check
        run: npm run format:check

  # Stage 2: Tests
  test:
    needs: quick-checks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm test -- --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  # Stage 3: Build
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - uses: actions/upload-artifact@v4
        with:
          name: build
          path: dist/

  # Stage 4: Déploiement (si main)
  deploy:
    if: github.ref == 'refs/heads/main'
    needs: build
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: build
          path: dist/

      - name: Deploy
        run: echo "Deploying..."

Workflows spécialisés pour l’IA

Détection de gros changements

Alerter quand un agent a fait des modifications massives :

# .github/workflows/large-diff-alert.yml
name: Large Diff Alert

on:
  pull_request:

jobs:
  check-diff:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Calculate diff size
        id: diff
        run: |
          STATS=$(git diff --shortstat origin/${{ github.base_ref }}...HEAD)
          INSERTIONS=$(echo "$STATS" | grep -oP '\d+(?= insertion)' || echo 0)
          DELETIONS=$(echo "$STATS" | grep -oP '\d+(?= deletion)' || echo 0)
          TOTAL=$((INSERTIONS + DELETIONS))
          echo "total=$TOTAL" >> $GITHUB_OUTPUT
          echo "insertions=$INSERTIONS" >> $GITHUB_OUTPUT
          echo "deletions=$DELETIONS" >> $GITHUB_OUTPUT

      - name: Comment on large diffs
        if: steps.diff.outputs.total > 500
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `⚠️ **Large diff detected**

              This PR contains significant changes:
              - ➕ ${{ steps.diff.outputs.insertions }} insertions
              - ➖ ${{ steps.diff.outputs.deletions }} deletions
              - 📊 Total: ${{ steps.diff.outputs.total }} lines changed

              Please review carefully, especially if this code was AI-generated.`
            });

Vérification des dépendances nouvelles

# .github/workflows/new-deps.yml
name: New Dependencies Check

on:
  pull_request:

jobs:
  check-deps:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Check for new dependencies
        id: deps
        run: |
          # Compare package.json
          if git diff origin/${{ github.base_ref }}...HEAD -- package.json | grep -q '"dependencies"\|"devDependencies"'; then
            echo "changed=true" >> $GITHUB_OUTPUT

            # Extract new packages
            NEW_DEPS=$(git diff origin/${{ github.base_ref }}...HEAD -- package.json | grep "^\+" | grep -oP '"\w[\w-]*":' | tr -d '":' | sort -u)
            echo "new_deps<<EOF" >> $GITHUB_OUTPUT
            echo "$NEW_DEPS" >> $GITHUB_OUTPUT
            echo "EOF" >> $GITHUB_OUTPUT
          else
            echo "changed=false" >> $GITHUB_OUTPUT
          fi

      - name: Audit new dependencies
        if: steps.deps.outputs.changed == 'true'
        run: npm audit

      - name: Comment about new deps
        if: steps.deps.outputs.changed == 'true'
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `📦 **New dependencies detected**

              The following packages have been added or modified:
              \`\`\`
              ${{ steps.deps.outputs.new_deps }}
              \`\`\`

              Please verify these are legitimate and necessary.`
            });

Scan de code sensible

# .github/workflows/security-scan.yml
name: Security Scan

on:
  pull_request:
  push:
    branches: [main]

jobs:
  secrets-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: TruffleHog Scan
        uses: trufflesecurity/trufflehog@main
        with:
          path: ./
          base: ${{ github.event.repository.default_branch }}
          head: HEAD
          extra_args: --only-verified

  codeql:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: javascript

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3

  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/dependency-review-action@v4

Intégration avec les agents

Workflow déclenché par label

Permet de déclencher des actions via des labels sur les issues/PRs :

# .github/workflows/ai-review.yml
name: AI Code Review

on:
  pull_request:
    types: [labeled]

jobs:
  ai-review:
    if: github.event.label.name == 'ai-review'
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get diff
        id: diff
        run: |
          DIFF=$(git diff origin/${{ github.base_ref }}...HEAD)
          echo "diff<<EOF" >> $GITHUB_OUTPUT
          echo "$DIFF" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: AI Review
        uses: actions/github-script@v7
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        with:
          script: |
            const { execSync } = require('child_process');

            // Appel à l'API Claude (exemple simplifié)
            const review = execSync(`
              curl -s https://api.anthropic.com/v1/messages \
                -H "x-api-key: $ANTHROPIC_API_KEY" \
                -H "content-type: application/json" \
                -d '{
                  "model": "claude-3-sonnet-20240229",
                  "max_tokens": 1024,
                  "messages": [{
                    "role": "user",
                    "content": "Review this code diff and provide constructive feedback:\\n${{ steps.diff.outputs.diff }}"
                  }]
                }'
            `).toString();

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## AI Code Review\\n\\n${review}`
            });

Documentation auto-générée

# .github/workflows/auto-docs.yml
name: Auto Documentation

on:
  push:
    branches: [main]
    paths:
      - 'src/**'

jobs:
  update-docs:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: pip install pdoc llm llm-claude-3

      - name: Generate API docs
        run: pdoc --html src/ -o docs/api/

      - name: Generate README sections
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          # Générer la section "Features" basée sur le code
          llm -m claude-3-haiku "Based on the code in src/, list the main features of this project in markdown bullet points" > docs/features.md

      - name: Commit docs
        run: |
          git config user.name 'github-actions[bot]'
          git config user.email 'github-actions[bot]@users.noreply.github.com'
          git add docs/
          git diff --staged --quiet || git commit -m "docs: auto-update documentation [skip ci]"
          git push

Bonnes pratiques CI/CD pour le vibe coding

1. Fail fast

Mettez les vérifications rapides en premier :

jobs:
  lint:
    # 30 secondes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    needs: lint  # N'exécute que si lint passe
    # 5 minutes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  e2e:
    needs: test  # N'exécute que si test passe
    # 15 minutes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run e2e

2. Parallélisation

jobs:
  lint: ...
  typecheck: ...
  test-unit: ...

  # Ces jobs tournent en parallèle

  build:
    needs: [lint, typecheck, test-unit]
    # Ne tourne qu'après les 3

3. Caching agressif

- uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      node_modules
      ~/.cache/Cypress
    key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }}

4. Notifications

- name: Notify on failure
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: failure
    channel: '#ci-alerts'
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Métriques et observabilité

Tracking de la couverture

- name: Tests with coverage
  run: npm test -- --coverage

- name: Upload to Codecov
  uses: codecov/codecov-action@v4
  with:
    fail_ci_if_error: true

Temps de build

- name: Build timing
  run: |
    START=$(date +%s)
    npm run build
    END=$(date +%s)
    echo "Build took $((END-START)) seconds"

Dashboard de santé

Créez un badge dans votre README :

![CI](https://github.com/user/repo/workflows/CI/badge.svg)
![Coverage](https://codecov.io/gh/user/repo/branch/main/graph/badge.svg)

Prochain chapitre : Sécurité.