AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Ci Cd

skill-kid-sid-claude-spellbook-ci-cd · by kid-sid

Use when setting up or debugging GitHub Actions pipelines — adding quality gates, configuring OIDC cloud auth, building matrix test runs, publishing artifacts to GHCR/PyPI/npm, or promoting builds from staging to production.

No reviews yet
0 installs
36 views
0.0% view→install

Install

$ agentstack add skill-kid-sid-claude-spellbook-ci-cd

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-kid-sid-claude-spellbook-ci-cd)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Ci Cd? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

CI/CD with GitHub Actions

A complete reference for building robust, secure, and efficient CI/CD pipelines using GitHub Actions, covering everything from workflow anatomy to multi-environment deployment promotion.

When to Activate

  • Creating or modifying a GitHub Actions workflow
  • Adding a quality gate (coverage, lint, security scan) to a pipeline
  • Setting up CD with environment promotion from staging to production
  • Optimizing a slow CI pipeline with caching or parallelism
  • Publishing a Docker image, Python package, or npm package from CI
  • Configuring secrets and OIDC-based cloud authentication

Workflow Anatomy

Every GitHub Actions workflow is defined in .github/workflows/*.yml. Understanding the core building blocks is essential before composing pipelines.

Triggers

| Trigger | Use Case | |-----------------------|-------------------------------------------------------| | push | Run on commits to specified branches or tags | | pull_request | Run on PR open, sync, or reopen | | workflow_dispatch | Manual trigger with optional input parameters | | schedule | Cron-based triggers (e.g., nightly security scans) | | workflow_call | Reusable workflow called by another workflow |

Jobs

  • Jobs run in parallel by default unless needs: is specified.
  • Use needs: [job-a, job-b] to declare dependencies; a job waits for all listed jobs to succeed.
  • Each job runs in a fresh virtual machine (or container).

Steps

  • uses: — invokes a reusable action from the marketplace or a local path.
  • run: — executes a shell command directly on the runner.
  • Steps within a job share the same filesystem and runner environment.

Key Contexts

| Context | What It Provides | |-------------|----------------------------------------------------------| | github | Repo name, SHA, ref, event name, actor, run ID | | secrets | Encrypted secret values; never printed in logs | | env | Environment variables set at workflow, job, or step level| | matrix | Current values from the strategy matrix | | job | Current job status, container info |

Expression Syntax

All dynamic values use ${{ expression }} syntax:

if: github.ref == 'refs/heads/main'
run: echo "SHA is ${{ github.sha }}"
env:
  BRANCH: ${{ github.ref_name }}

Minimal Workflow Skeleton

name: CI
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: make test

Standard Pipeline Structure

The canonical stage sequence moves from fast feedback (lint) to slower gates (security), then publishing.

lint → test → build → security-scan → publish

Job Dependency Graph

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lint
        run: make lint

  test:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test
        run: make test

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: make build

  security-scan:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Security scan
        run: make scan

  publish:
    needs: [build, security-scan]
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Publish
        run: make publish

fail-fast Behavior

| Setting | When to Use | |-----------------------|--------------------------------------------------------------| | fail-fast: true (default) | Sequential stage pipelines — stop early on first failure | | fail-fast: false | Matrix builds — collect all results before deciding |

Use fail-fast: false in matrix strategies so you see failures across all OS/version combinations rather than stopping at the first one.


Dependency Caching

Caching package manager dependencies is the single highest-impact optimization for CI speed. The key strategy: hash the lockfile so the cache automatically invalidates when dependencies change.

Cache Key Strategy

cache-key = runner-os + lockfile-hash
restore-key = runner-os (fallback to most recent cache)

Python

- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'  # built-in caching, hashes requirements*.txt

For more control with pyproject.toml:

- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

Node.js

- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'  # hashes package-lock.json automatically

For pnpm or yarn, set cache: 'pnpm' or cache: 'yarn' respectively.

Go

- uses: actions/setup-go@v5
  with:
    go-version: '1.22'
    cache: true  # caches $GOPATH/pkg/mod and build cache

Cache Hit Rate Tips

  • Always commit lockfiles (package-lock.json, poetry.lock, go.sum) to the repository.
  • Use hashFiles('**/package-lock.json') to scope cache keys to the exact dependency set.
  • Restore keys act as fallbacks: a partial hit is better than no cache.

Matrix Builds

Matrix builds let a single job definition run across multiple configurations (language versions, operating systems) in parallel.

Matrix Strategy

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.11', '3.12', '3.13']
        os: [ubuntu-latest, windows-latest]
        include:
          - python-version: '3.12'
            os: ubuntu-latest
            publish: true      # custom flag for conditional steps
        exclude:
          - python-version: '3.11'
            os: windows-latest  # skip known unsupported combo
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: pip
      - run: pytest
      - name: Publish (only from designated matrix entry)
        if: matrix.publish == true
        run: make publish

Matrix Reference

| Feature | Syntax | Purpose | |-----------------|------------------------------------------------|------------------------------------------| | Access value | ${{ matrix.python-version }} | Use current dimension value in steps | | include | Adds extra key-value pairs to specific entries | Inject flags or override runner for one combo | | exclude | Removes specific combinations | Skip known broken or unnecessary combos | | fail-fast | false on matrix | See all failures, not just first |


Quality Gates

Coverage Threshold

Fail the build if coverage drops below the required threshold.

- name: Run tests with coverage
  run: pytest --cov=src --cov-report=xml --cov-fail-under=80

- name: Upload coverage report
  uses: codecov/codecov-action@v4
  with:
    file: ./coverage.xml
    fail_ci_if_error: true

For Node.js with Jest:

- name: Run tests with coverage
  run: jest --coverage --coverageThreshold='{"global":{"lines":80}}'

Inline Lint Annotations with reviewdog

reviewdog posts lint results as PR review comments, making issues visible without reading raw logs.

- uses: reviewdog/action-flake8@v3
  with:
    reporter: github-pr-review
    level: warning
- uses: reviewdog/action-eslint@v1
  with:
    reporter: github-pr-review
    eslint_flags: '--ext .js,.ts src/'

Branch Protection Rules

Configure these in GitHub Settings → Branches, not in workflow YAML:

  • Required status checks: list every CI job name that must pass before merge.
  • Required approvals: minimum 1 reviewer for main.
  • Dismiss stale approvals: re-approval required after new commits are pushed.
  • Require branches to be up to date: prevents merging outdated branches.

Security Scanning

- name: Python dependency audit
  run: pip-audit

- name: Node audit
  run: npm audit --audit-level=high

- name: Go vulnerability check
  run: govulncheck ./...

For container scanning, integrate Trivy:

- uses: aquasecurity/trivy-action@master
  with:
    image-ref: ghcr.io/${{ github.repository }}:${{ github.sha }}
    severity: 'CRITICAL,HIGH'
    exit-code: '1'

Secrets and Environment Variables

Contexts

env:
  APP_ENV: production                    # plain env var (visible in logs)
  DB_HOST: ${{ vars.DB_HOST }}           # repository variable (not secret, visible)
  API_KEY: ${{ secrets.API_KEY }}        # encrypted secret (masked in logs)

Variable Scoping

| Scope | Set In | Available To | |------------|-------------------------------------------|-------------------------------| | Workflow | Top-level env: block | All jobs and steps | | Job | env: under a specific job | All steps in that job | | Step | env: under a specific step | That step only | | Repository | GitHub Settings → Secrets and Variables | All workflows in the repo | | Environment| GitHub Settings → Environments | Jobs using that environment |

$GITHUB_TOKEN Permissions

Declare only what the job requires (principle of least privilege):

permissions:
  contents: read       # read repo files
  packages: write      # push to GHCR
  id-token: write      # request OIDC token for cloud auth
  pull-requests: write # post PR comments
  checks: write        # create check runs

Set permissions: {} at the workflow level, then grant specific permissions per job to minimize blast radius.

OIDC for Cloud Auth (No Long-Lived Credentials)

OIDC eliminates the need to store cloud credentials as GitHub secrets. The cloud provider verifies the workflow's identity token and grants temporary credentials.

AWS:

- uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789:role/github-actions
    aws-region: us-east-1

Requires an IAM role with a trust policy that allows token.actions.githubusercontent.com as an OIDC provider.

Google Cloud:

- uses: google-github-actions/auth@v2
  with:
    workload_identity_provider: projects/123/locations/global/workloadIdentityPools/my-pool/providers/github
    service_account: deployer@my-project.iam.gserviceaccount.com

Requires a Workload Identity Pool configured in GCP with a GitHub OIDC provider binding.

Azure:

- uses: azure/login@v2
  with:
    client-id: ${{ secrets.AZURE_CLIENT_ID }}
    tenant-id: ${{ secrets.AZURE_TENANT_ID }}
    subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

Uses federated credentials on the Azure App Registration — no client secret stored.


CD and Environment Promotion

The standard promotion pattern: build once, deploy to staging automatically, then gate production behind a manual approval.

Staging → Production Pipeline

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build artifact
        run: make build
      - uses: actions/upload-artifact@v4
        with:
          name: app-artifact
          path: dist/

  deploy-staging:
    environment: staging
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: app-artifact
          path: dist/
      - name: Deploy to staging
        run: ./scripts/deploy.sh staging

  smoke-test:
    runs-on: ubuntu-latest
    needs: deploy-staging
    steps:
      - name: Run smoke tests against staging
        run: ./scripts/smoke-test.sh https://staging.example.com

  deploy-production:
    environment: production   # required reviewers configured in GitHub Settings
    runs-on: ubuntu-latest
    needs: smoke-test
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: app-artifact
          path: dist/
      - name: Deploy to production
        run: ./scripts/deploy.sh production
      - name: Notify on failure
        if: failure()
        run: ./scripts/notify-failure.sh "${{ job.status }}"

Environment Protection Configuration

Set these in GitHub Settings → Environments, not in YAML:

| Setting | Recommended Value | |----------------------------|------------------------------------------------| | Required reviewers | 1–2 senior engineers for production | | Wait timer | Optional: 5–10 min buffer before deployment | | Deployment branches | Limit to main branch only | | Environment secrets | Prod credentials scoped here, not at repo level|

Deployment Status

Use job.status in post-deploy notifications:

- name: Notify Slack
  if: always()
  uses: slackapi/slack-github-action@v1
  with:
    payload: '{"text": "Deploy to production: ${{ job.status }}"}'
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Artifact and Package Publishing

Docker Image to GHCR

jobs:
  publish-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/metadata-action@v5
        id: meta
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=sha,prefix=,suffix=,format=short
            type=ref,event=branch
            type=semver,pattern={{version}}

      - uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.ref == 'refs/heads/main' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Always tag images with the commit SHA. Never use latest as the only tag in production.

PyPI with Trusted Publishing (No Token Needed)

Configure a Trusted Publisher in PyPI project settings pointing to this repository and workflow, then:

jobs:
  publish-pypi:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # required for trusted publishing
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install build
      - run: python -m build
      - uses: pypa/gh-action-pypi-publish@release/v1
        with:
          repository-url: https://upload.pypi.org/legacy/
          # For pre-release testing:
          # repository-url: https://test.pypi.org/legacy/

npm Publish

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https:/

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kid-sid](https://github.com/kid-sid)
- **Source:** [kid-sid/claude-spellbook](https://github.com/kid-sid/claude-spellbook)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.