agentsclimarketplace

Ci cd

Skill MARUCIE/openclaw-foundry/web/public/packs/spellbook-platform-engineer/skills/ci-cd

The curated AI Agent skill marketplace — 37K+ vetted skills, S/A/B/C ratings, deploy anywhere

Install
npx -y skills add MARUCIE/openclaw-foundry --skill ci-cd

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

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.

SKILL.md

23.2 KB, as published. Nobody here has run it

是什么

这是一份 CI/CD(持续集成与持续交付)流水线规范,覆盖 GitHub Actions 的触发、缓存、矩阵测试、质量门禁、跨环境晋升等关键节点,让团队从手工部署升级到一键发版,且每次发版都自带质量保障。

怎么用

  1. 新项目立项时,按本规范拷贝标准 workflow 模板,5 分钟内就能跑通最小可用的 CI(持续集成)流程。
  2. 给流水线加单元测试、覆盖率、安全扫描等质量门禁时,对照文档中的标准门禁清单逐项启用。
  3. 配置云上部署 OIDC(开放身份连接)认证时,遵循免长期密钥章节的步骤,避免把 access key 写进 secrets。
  4. 流水线变慢时,按缓存与并行小节先加 cache,再做 job 拆分,目标 P95 时长控制在 8 分钟内。
  5. 从测试环境晋升到生产环境时,必须走文档约定的多环境晋升流程,加 manual approval(人工审批)兜底。

架构图

flowchart LR
    A[Push 或 PR] --> B[Lint 与单测]
    B --> C[构建产物]
    C --> D[质量门禁]
    D --> E[测试环境部署]
    E --> F[人工审批晋升]

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

TriggerUse Case
pushRun on commits to specified branches or tags
pull_requestRun on PR open, sync, or reopen
workflow_dispatchManual trigger with optional input parameters
scheduleCron-based triggers (e.g., nightly security scans)
workflow_callReusable 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

ContextWhat It Provides
githubRepo name, SHA, ref, event name, actor, run ID
secretsEncrypted secret values; never printed in logs
envEnvironment variables set at workflow, job, or step level
matrixCurrent values from the strategy matrix
jobCurrent 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

SettingWhen to Use
fail-fast: true (default)Sequential stage pipelines — stop early on first failure
fail-fast: falseMatrix 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

FeatureSyntaxPurpose
Access value${{ matrix.python-version }}Use current dimension value in steps
includeAdds extra key-value pairs to specific entriesInject flags or override runner for one combo
excludeRemoves specific combinationsSkip known broken or unnecessary combos
fail-fastfalse on matrixSee 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

ScopeSet InAvailable To
WorkflowTop-level env: blockAll jobs and steps
Jobenv: under a specific jobAll steps in that job
Stepenv: under a specific stepThat step only
RepositoryGitHub Settings → Secrets and VariablesAll workflows in the repo
EnvironmentGitHub Settings → EnvironmentsJobs 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: [email protected]

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:

SettingRecommended Value
Required reviewers1–2 senior engineers for production
Wait timerOptional: 5–10 min buffer before deployment
Deployment branchesLimit to main branch only
Environment secretsProd 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://registry.npmjs.org'
      - run: npm ci
      - run: npm run build
      - run: npm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Complete Workflow Examples

Python Service

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

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip
      - run: pip install -e ".[dev]"
      - run: ruff check .
      - run: mypy src/
      - run: pytest --cov=src --cov-report=xml --cov-fail-under=80
      - run: pip-audit
      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml

TypeScript/Node Service

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

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test -- --coverage
      - run: npm audit --audit-level=high

Go Service

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

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'
          cache: true
      - run: go vet ./...
      - run: staticcheck ./...
      - run: go test -race -coverprofile=coverage.out ./...
      - run: go tool cover -func=coverage.out
      - run: govulncheck ./...

Decision Tables

Which Cache Approach to Use

LanguageRecommended ApproachLockfile to Hash
Pythonsetup-python built-in cache: piprequirements*.txt, pyproject.toml
Node.jssetup-node built-in cache: npm/pnpmpackage-lock.json, pnpm-lock.yaml
Gosetup-go built-in cache: truego.sum
Rustactions/cache on ~/.cargoCargo.lock
Java/Mavenactions/cache on ~/.m2pom.xml

When to Use OIDC vs Stored Secrets

Credential TypeUse OIDCUse Stored Secret
AWS IAM roleYesNo — OIDC is the standard
GCP service accountYesNo — Workload Identity preferred
Azure managed identityYesNo — Federated credentials preferred
NPM publish tokenNoYes — npm does not support OIDC
PyPI publish tokenNo (use Trusted Publishing)Only if Trusted Publishing unavailable
Third-party API keyNoYes

Trigger Selection Guide

ScenarioRecommended Trigger
Run CI on every PRpull_request targeting main
Deploy on merge to mainpush on main branch
Nightly dependency auditschedule with cron
Manual production deployworkflow_dispatch with input parameters
Shared CI logic across reposworkflow_call (reusable workflow)
Release on tag pushpush with tags: ['v*']

Red Flags

  • Storing cloud credentials as GitHub Secrets — long-lived access keys can be exfiltrated via PR log injection; use OIDC federated credentials (aws-actions/configure-aws-credentials) instead
  • Hardcoding runs-on: ubuntu-latest without version pinningubuntu-latest can shift to a new OS major version mid-project, silently changing available toolchains; pin to ubuntu-22.04 for stability
  • Single monolithic job with 20+ steps — any step failure retries the entire job from scratch; split into separate jobs with needs: so fast gates (lint) don't block slow ones (security scan)
  • Pushing to main without a required status check — branch protection "Required status checks" must be configured in GitHub Settings, not just in the YAML; YAML alone can be bypassed
  • Cache key without a lockfile hash — using key: ${{ runner.os }}-pip without hashFiles(...) causes stale caches after dependency updates, producing false green builds
  • Tagging Docker images with only latestlatest is overwritten on every build; a failed rollback cannot target a specific previous image; always add a commit SHA tag alongside latest
  • Using pull_request_target without careful filtering — this trigger runs in the context of the base branch and has access to secrets, making it exploitable by a forked PR that modifies the workflow
  • Skipping --cov-fail-under or equivalent threshold — coverage upload without a fail threshold lets coverage silently drop to zero; the gate must actively fail the build

Checklist

  • Workflow triggers cover both push to main and pull_request
  • Jobs run in correct dependency order using needs:
  • Package manager caching configured (pip/npm/go modules)
  • Lint, type-check, test, and security scan are all separate steps
  • Coverage threshold enforced (--cov-fail-under / --coverage)
  • $GITHUB_TOKEN permissions scoped to least privilege
  • Secrets accessed via ${{ secrets.X }} — never hardcoded
  • OIDC used for cloud credentials — no long-lived access keys stored as secrets
  • CD deploys to staging first; production requires approval via environment protection
  • Docker images tagged with commit SHA, not latest
  • Failed jobs produce clear error output; no silent failures
  • Pipeline completes in under 10 minutes on a typical PR

Gives 0 of the 12 instructions most ci cd skills give

Counted across 392 of the 394 authors here whose files we hold, read 2026-08-06

  • pin third-party actions to full commit SHAsin 33 of 392
  • cache dependencies appropriatelyin 24 of 392, across 12 files
  • optimize pipelines exceeding ten minutesin 20 of 392, across 6 files
  • enforce all quality gates before mergein 20 of 392, across 7 files
  • Configure branch protection rulesin 19 of 392, across 5 files
  • use environments for deployment trackingin 19 of 392, across 7 files
  • implement manual gates for productionin 19 of 392, across 7 files
  • implement security scanningin 18 of 392, across 5 files
  • fix failing code instead of disabling checksin 18 of 392, across 4 files
  • use CI/CD variables for secretsin 18 of 392, across 6 files
  • move checks upstream in the pipelinein 17 of 392, across 3 files
  • use specific image tagsin 17 of 392, across 5 files

Said here and by no other author read

  • keep P95 pipeline duration under eight minutes
  • commit dependency lockfiles to repository
  • fail builds when coverage drops below threshold

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.