CI/CD avec GitHub Actions
Guide des pipelines d'integration continue et de deploiement continu.
Vue d'ensemble
Pipeline principal
Jobs
| Job | Description | Bloquant |
|---|---|---|
| lint | ESLint + Prettier | Oui |
| test | Unit tests + coverage | Oui |
| build | TypeScript compilation | Oui |
| security | npm audit (high/critical) | Oui |
| monitoring | Config validation | Oui |
| codeql | SAST analysis | Oui |
| license-check | License compliance | Oui |
| quality-gate | Final check | Oui |
Configuration
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
lint:
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 lint:check
- run: npm run format:check
test:
runs-on: ubuntu-latest
needs: lint
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: test
ports:
- 5432:5432
redis:
image: redis:7-alpine
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run prisma:generate
- run: npm run test:cov
- uses: codecov/codecov-action@v3
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run build
security:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
quality-gate:
runs-on: ubuntu-latest
needs: [lint, test, build, security]
steps:
- run: echo "All checks passed"
Pre-commit Hooks
Husky Configuration
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
npx tsc --noEmit
lint-staged
// package.json
{
"lint-staged": {
"*.ts": ["eslint --fix", "prettier --write"],
"*.json": ["prettier --write"]
}
}
Commit Message Validation
Les messages de commit suivent la convention Conventional Commits :
# .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx commitlint --edit $1
Format
<type>(<scope>): <subject>
# Types: feat, fix, docs, test, refactor, perf, ci, chore
# Scopes: auth, users, movies, series, news, livetv, radio, podcasts, replays, events, streaming
# Exemples
feat(news): add article CRUD endpoints
fix(auth): resolve token expiration issue
test(news): add unit tests for NewsService
docs(readme): update installation guide
Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
groups:
development:
patterns:
- '@types/*'
- '*eslint*'
- '*prettier*'
- '*jest*'
nestjs:
patterns:
- '@nestjs/*'
prisma:
patterns:
- 'prisma'
- '@prisma/*'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
- package-ecosystem: 'docker'
directory: '/'
schedule:
interval: 'weekly'
Deploy Staging
Le deploiement staging est declenche automatiquement sur push vers develop :
# .github/workflows/deploy-staging.yml
name: Deploy Staging
on:
push:
branches: [develop]
jobs:
deploy:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build -t $REGISTRY/mytv-api:staging .
docker push $REGISTRY/mytv-api:staging
- name: Deploy to K8s
run: |
kubectl apply -k k8s/overlays/staging/
Deploy Production
Le deploiement production est declenche sur push vers main ou creation de tag :
# .github/workflows/deploy-prod.yml
name: Deploy Production
on:
push:
branches: [main]
tags: ['v*']
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build -t $REGISTRY/mytv-api:${{ github.ref_name }} .
docker push $REGISTRY/mytv-api:${{ github.ref_name }}
- name: Deploy with Helm
run: |
helm upgrade mytv-api ./helm/mytv-api \
--set image.tag=${{ github.ref_name }} \
-f helm/values-prod.yaml
Secrets GitHub
| Secret | Description |
|---|---|
DOCKER_REGISTRY | URL du registry |
DOCKER_USERNAME | Username registry |
DOCKER_PASSWORD | Password registry |
KUBECONFIG | Config Kubernetes |
CODECOV_TOKEN | Token Codecov |
Bonnes pratiques
- Fail fast - Executer lint avant tests pour detecter les erreurs rapidement
- Cache dependencies - Utiliser le cache npm de GitHub Actions
- Parallel jobs - Executer les jobs independants en parallele quand possible
- Environment protection - Activer les protections d'environnement pour la production
- Semantic versioning - Utiliser des tags
v*.*.*pour les releases - Branch protection - Configurer les regles de protection sur
mainetdevelop