| name | ci-cd-pipeline |
| description | CI/CD pipeline patterns for GitHub Actions and GitLab CI. Activates when editing .github/workflows/*, .gitlab-ci.yml, or when auditing or debugging a pipeline. Use when this capability is needed. |
| metadata | {"author":"felixhennequin-gif"} |
CI/CD pipelines (GitHub Actions + GitLab CI)
Focused on the four rules that matter in real pipelines. Syntax details live in the upstream docs — this file only captures the conventions teams get wrong by default.
Rules
- Build once, deploy many. Produce one artifact tagged with the commit SHA, then promote it across environments. Rebuilding per environment is how staging and prod drift.
- Idempotence. Same commit → same artifact. Use
npm ci / pip install --require-hashes / cargo build --locked, pin Docker base images to an explicit version, and pin third-party actions by full 40-char SHA (not @v4, not @main).
- Fail fast under 10 min. Run lint, unit tests, and security scans in parallel jobs. A sequential pipeline is the biggest avoidable latency in CI.
- Separate build from deploy. Two jobs, two responsibilities. The build job never touches deploy credentials.
GOOD vs BAD
- uses: actions/checkout@v4
- run: docker build -t my-app:staging .
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- run: docker build -t my-app:${{ github.sha }} .
Secrets and credentials
- Prefer OIDC over long-lived API keys (GitHub Actions → AWS/GCP/Azure role assumption, GitLab
id_tokens:).
- Scope secrets per environment:
environment: staging and environment: production get different secret stores.
- Never
echo $SECRET, never pass a secret as a CLI argument on a shared runner.
- The minimum-permissions default for a GitHub workflow is
permissions: contents: read. Add write scopes per-job only when they're needed.
Parallelism
- GitHub Actions: use
needs: to build a DAG. Jobs with needs: [] start immediately; jobs with needs: [lint, test] wait for both.
- GitLab CI:
needs: turns stages into a DAG (no longer strictly sequential). parallel: runs matrix variants side-by-side.
Pipeline audit checklist
Use this when reviewing an existing workflow:
Helper script
scripts/action-pin-check.sh <workflow.yml>... — scans workflows for uses: references that aren't full SHAs. Wire it into CI so SHA pinning is enforced, not aspirational.
Anti-patterns
- ❌
uses: foo/bar@v4 or @main — pin by SHA
- ❌
docker build -t my-app:staging and a separate my-app:prod build — build once, retag on promotion
- ❌
npm install in CI — use npm ci
- ❌
:latest or :lts image tags — pin to an exact version
- ❌ One giant sequential pipeline — split into parallel jobs with
needs:
- ❌ Production secrets exported in the build job — scope per environment
- ❌
echo $SECRET or secrets in set -x output — they end up in logs
References
Source: felixhennequin-gif/claude-code-config-template — distributed by TomeVault.