Install
$ agentstack add skill-kid-sid-claude-spellbook-ci-cd ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →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.
Write a review
Versions
- v0.1.0 Imported from the upstream source.