ci-cd

SkillCloud & infra

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.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the ci-cd skill

What this skill tells your AI

The instructions your AI receives, as published by irahardianto/awesome-agv in .agents/skills/ci-cd/SKILL.md and read by ahel’s review.

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

LevelApplies WhenKey Additions
0 — All projectsAlwaysLint, test, security scan, secrets management
1 — ContainerizedDocker image is the artifactMulti-stage build, image scan, SBOM attestation
2 — OrchestratedKubernetes or managed container platformDeployment 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):

docker compose up --build

Cloud Run:

gcloud run deploy myapp \
  --image gcr.io/project/myapp:$GIT_SHA \
  --region us-central1

Vercel (frontend SPA):

vercel deploy --prod

Kubernetes: Use GitOps — see references/gitops-kubernetes.md.


Level 0 — Manifest Patterns

GitHub Actions
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)
# 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)
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.

  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:

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

Signals

GitHub stars
156
Forks
53
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
ci-cd-irahardianto
Source
github.com/irahardianto/awesome-agv