CI/CD pipeline design: GitHub Actions, GitLab CI, multi-stage Docker builds, image scanning, SBOM attestation (Cosign keyless), and environment promotion. Layered by complexity — Level 0 (all projects), Level 1 (containerized), Level 2 (Kubernetes). GitOps and Kubernetes deployment patterns in references/gitops-kubernetes.md.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add irahardianto/antigravity-setup --skill ci-cd --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ci Cd?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/irahardianto-ci-cd)More formats (shields.io, HTML) on the badges page.
---
name: ci-cd
description: >-
CI/CD pipeline design: GitHub Actions, GitLab CI, multi-stage Docker builds, image
scanning, SBOM attestation (Cosign keyless), and environment promotion. Layered by
complexity — Level 0 (all projects), Level 1 (containerized), Level 2 (Kubernetes).
GitOps and Kubernetes deployment patterns in references/gitops-kubernetes.md.
paths:
- "**/.github/workflows/*.yml"
- "**/.github/workflows/*.yaml"
- "**/Dockerfile"
- "**/docker-compose*.yml"
- "**/docker-compose*.yaml"
- "**/.gitlab-ci.yml"
- "**/Jenkinsfile"
- "**/.circleci/config.yml"
- "**/.circleci/config.yaml"
- "**/azure-pipelines.yml"
- "**/azure-pipelines.yaml"
---
## CI/CD Principles
> **Agent scope:** This rule applies when writing CI/CD manifests
> (Dockerfile, docker-compose, GitHub Actions, GitLab CI, etc.).
> It is layered by deployment complexity — apply only the levels relevant to the project.
---
### Deployment Complexity Levels
| Level | Applies When | Key Additions |
|-------|-------------|---------------|
| **0 — All projects** | Always | Lint, test, security scan, secrets management |
| **1 — Containerized** | Docker image is the artifact | Multi-stage build, image scan, SBOM attestation |
| **2 — Orchestrated** | Kubernetes or managed container platform | Deployment strategies, GitOps |
Load supplementary rules when reaching Level 2:
- Deployment strategies + GitOps → **references/gitops-kubernetes.md**
---
### Level 0 — Universal Pipeline Design
**Pipeline Stages (in order):**
1. **Lint** — static analysis, formatting checks
2. **Build** — compile, bundle, generate artifacts
3. **Unit Test** — fast tests with mocked dependencies
4. **Integration Test** — tests against real dependencies (Testcontainers)
5. **Security Scan** — dependency audit, SAST, secrets detection
6. **Deploy** — push to target environment
**Rules:**
- **Fail fast** — run cheapest checks first (lint before build, build before test)
- **Pipeline must be deterministic** — same input = same output, every time
- **Keep pipelines under 15 minutes** — optimize slow stages
- **Never skip failing steps** — fix the pipeline, don't bypass it
- **Build once, deploy many** — same artifact promotes through all environments
---
### Level 0 — Deploy Target Examples
The deploy stage varies by target. The pipeline stages before it are identical.
**Docker Compose (local / staging):**
```bash
docker compose up --build
```
**Cloud Run:**
```bash
gcloud run deploy myapp \
--image gcr.io/project/myapp:$GIT_SHA \
--region us-central1
```
**Vercel (frontend SPA):**
```bash
vercel deploy --prod
```
**Kubernetes:**
Use GitOps — see **references/gitops-kubernetes.md**.
---
### Level 0 — Manifest Patterns
#### GitHub Actions
```yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod # Pin via go.mod
cache: true # Cache dependencies
- run: gofumpt -l -e -d .
- run: go vet ./...
- run: staticcheck ./...
test:
needs: lint # Fail fast: lint before test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- run: go test -race -cover ./...
security:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan for secrets
uses: trufflesecurity/trufflehog@v3 # Pin to release tag
- name: Audit dependencies
run: go run golang.org/x/vuln/cmd/govulncheck@latest ./...
```
**Rules:**
- Pin action versions (`@v4`, not `@latest` or `@main`)
- Use `needs:` to enforce stage ordering
- Cache dependencies (`cache: true` in setup actions)
- Use `go-version-file` / `node-version-file` instead of hardcoding versions
- Never put secrets in workflow files — use `${{ secrets.NAME }}`
---
### Level 1 — Containerized Projects
#### Dockerfile (Multi-Stage Build)
```dockerfile
# Stage 1: Build
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download # Cache dependencies
COPY . .
RUN CGO_ENABLED=0 go build -o /bin/api ./cmd/api
# Stage 2: Runtime (minimal image)
FROM gcr.io/distroless/static-debian12
COPY --from=builder /bin/api /bin/api
EXPOSE 8080
CMD ["/bin/api"]
```
**Rules:**
- Always use multi-stage builds (build → runtime)
- Pin base image versions (never use `:latest`)
- Copy dependency files first, then source (layer caching)
- Use minimal runtime images (distroless, alpine, scratch)
- Never copy `.env`, secrets, or `.git` into images
#### Docker Compose (Local Development)
```yaml
services:
backend:
build:
context: ./apps/backend # Path per project-structure.md
ports:
- "8080:8080"
env_file: .env # Environment config
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16-alpine # Pin versions
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
```
**Rules:**
- Always define health checks for dependencies
- Use `depends_on` with `condition: service_healthy`
- Pin all image versions
- Use volumes for persistent data
- Never hardcode credentials — use env_file or environment variables
#### Image Scan + SBOM Attestation
After building and pushing a container image, scan it and attach a signed SBOM attestation.
**Preferred approach: Cosign keyless signing (no key management required)**
Cosign integrates with your CI provider's OIDC token (GitHub Actions, GitLab CI) to sign
images and attestations without storing or rotating cryptographic keys. The signature is
anchored to a transparency log (Rekor), making it auditable and policy-enforceable.
```yaml
build:
needs: security
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write # Required for Cosign keyless signing
steps:
- uses: actions/checkout@v4
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Build and push image
id: build
run: |
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Scan container image
run: |
trivy image \
--severity HIGH,CRITICAL \
--exit-code 1 \
ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Generate SBOM
run: |
syft ghcr.io/${{ github.repository }}:${{ github.sha }} \
-o cyclonedx-json > sbom.json
- name: Attest SBOM to image (keyless, OIDC-backed)
run: |
cosign attest \
--predicate sbom.json \
--type cyclonedx \
ghcr.io/${{ github.repository }}:${{ github.sha }}
# Cosign uses the GitHub Actions OIDC token automatically.
# No COSIGN_PASSWORD or secret keys required.
```
**How the SBOM travels with the image:**
The SBOM attestation is stored as an OCI reference in the same container registry alongside
the image digest. It requires no additional infrastructure — any registry that supports OCI
artifacts (ghcr.io, Google Artifact Registry, AWS ECR, Docker Hub) works out of the box.
To verify the attestation at any time:
```bash
cosign verify-attestation \
--type cyclonedx \
ghcr.io/org/app@sha256:<digest>
```
**Use ORAS instead of Cosign when:**
- You need to attach arbitrary supply chain artifacts (scan reports, provenance JSON, build logs)
that go beyond what Cosign's attestation model covers.
- `oras attach ghcr.io/org/app@sha256:<digest> scan-report.json`
**Rules:**
- Prefer Cosign keyless signing — eliminates secret key management overhead
- SBOM is attached to the image in the OCI registry — not stored as a CI artifact
- Scan BEFORE attesting — the SBOM reflects the scanned image
- For non-containerized apps (Vercel, Netlify frontend), use `npm audit`/`yarn audit` instead;
no SBOM attachment applies
---
### Deployment vs Release (Feature Flags)
Code deployment and feature release are separate concerns. When the PRD or technical
architecture explicitly requires gradual rollout, A/B testing, or kill switches, feature
flags can decouple them.
> **Agent rule:** Do NOT implement feature flags unless explicitly required by the
> PRD or technical architecture document. See **@.agents/skills/feature-flags/SKILL.md** for
> implementation guidance when they are required.
---
### Environment Promotion
```
dev → staging → production
```
- **Dev:** Deployed on every push to feature branch
- **Staging:** Deployed on merge to main/develop
- **Production:** Deployed via manual approval or automated release
**Rules:**
- Same artifacts promote through environments (build once, deploy many)
- Environment-specific config via environment variables, not build flags
- Never deploy directly to production without staging validation
---
### CI/CD Checklist
**Always (all projects):**
- [ ] Pipeline stages run in correct order (lint → build → test → security → deploy)?
- [ ] All versions pinned (base images, CI actions, tool versions)?
- [ ] Dependency caching enabled?
- [ ] No secrets in config files (use env vars or secrets manager)?
- [ ] Secret scanning in CI?
- [ ] Health checks defined for all service dependencies?
- [ ] Pipeline completes in under 15 minutes?
**If building container images (Level 1):**
- [ ] Multi-stage Docker builds used?
- [ ] Container image scanned for HIGH/CRITICAL CVEs?
- [ ] SBOM generated and attested to image via Cosign (keyless)?
**If deploying to Kubernetes (Level 2):**
- [ ] Deployment strategy defined (blue-green, canary, or rolling)?
- [ ] GitOps in place — no direct `kubectl apply` in production?
- [ ] Secrets reference external store, not plaintext in git?
- See **references/gitops-kubernetes.md** for full checklist
**If feature flags are required by PRD/architecture:**
- [ ] Flag infrastructure specified in tech architecture document?
- [ ] Every flag has an owner and expiry date?
- See **@.agents/skills/feature-flags/SKILL.md** for full checklist
---
### Related Principles
- Code Idioms and Conventions @code-idioms-and-conventions.md (validation before ship)
- Security Mandate @security-mandate.md (secrets management)
- Security Principles @security-principles.md (image scanning, SBOM)
- Git Workflow Principles @git-workflow-principles.md (branch strategy)
- Project Structure @project-structure.md (service paths)
- Testing Strategy @testing-strategy.md (unit and integration test stages)
- GitOps + Kubernetes Deployment references/gitops-kubernetes.md
- Feature Flags @.agents/skills/feature-flags/SKILL.md
- Rule Priority @.agents/rules/rule-priority.md
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!