Claude-skill-registry cicd-setup

Create and configure CI/CD pipelines with security-first best practices. Triggers on requests to set up CI/CD, add GitHub Actions, create pipelines, automate testing/deployment, configure workflows, add continuous integration, or automate releases.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cicd-setup" ~/.claude/skills/majiayu000-claude-skill-registry-cicd-setup && rm -rf "$T"
manifest: skills/data/cicd-setup/SKILL.md
source content

CI/CD Setup

Create secure, production-ready CI/CD pipelines following 2025-2026 best practices.

Workflow

1. Detect Platform and Stack

Run these Glob patterns to identify the project:

Platform detection:
- .github/workflows/*.yml → GitHub Actions
- .gitlab-ci.yml → GitLab CI
- .circleci/config.yml → CircleCI

Stack detection:
- package.json, package-lock.json, yarn.lock, pnpm-lock.yaml → Node.js
- Cargo.toml, Cargo.lock → Rust
- go.mod, go.sum → Go
- pyproject.toml, requirements.txt, setup.py → Python
- Dockerfile, docker-compose.yml → Docker

2. Generate Workflows

Based on detected stack, create:

  1. CI workflow (
    .github/workflows/ci.yml
    ) - lint, test, build
  2. Dependabot config (
    .github/dependabot.yml
    ) - dependency updates
  3. CD workflow (if deployment needed) - release/deploy

3. Document Setup

After creating workflows, list:

  • Required secrets (if any)
  • Required repository settings
  • How to verify it works

Security Requirements (Non-Negotiable)

Pin Actions to Full SHA

After the 2025 tj-actions and reviewdog supply chain attacks, NEVER use mutable tags:

# WRONG - tag can be hijacked
- uses: actions/checkout@v4

# CORRECT - immutable SHA
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

To find current SHAs:

gh api repos/actions/checkout/releases/latest --jq '.tag_name'
then check the commit.

Use OIDC Instead of Long-Lived Secrets

Eliminate stored credentials with OIDC:

permissions:
  id-token: write
  contents: read

steps:
  - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
    with:
      role-to-assume: arn:aws:iam::ACCOUNT:role/GitHubActionsRole
      aws-region: us-east-1
      # No AWS_ACCESS_KEY_ID needed - OIDC provides short-lived tokens

Minimal Permissions

Always declare explicit permissions:

permissions:
  contents: read      # Only what's needed
  # Default is read-all for GITHUB_TOKEN if not specified

Protect Against pull_request_target

NEVER checkout PR code in

pull_request_target
workflows - this gives untrusted code access to secrets:

# DANGEROUS - attacker can access secrets via PR code
on: pull_request_target
steps:
  - uses: actions/checkout@SHA
    with:
      ref: ${{ github.event.pull_request.head.sha }}  # BAD

# SAFE - use pull_request instead (no secrets access, read-only token)
on: pull_request

Dependabot Configuration

Always include GitHub Actions in Dependabot:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      actions:
        patterns: ["*"]

  # Add for your package manager
  - package-ecosystem: "npm"  # or pip, cargo, gomod
    directory: "/"
    schedule:
      interval: "weekly"

CI Workflow Template

name: CI

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

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      # Add setup step for your language (see patterns below)

      - name: Lint
        run: # lint command

      - name: Test
        run: # test command

Language Setup Patterns

Node.js

- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
  with:
    node-version-file: '.nvmrc'
    cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test

Python

- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
  with:
    python-version-file: '.python-version'
    cache: 'pip'
- run: pip install -e ".[dev]"
- run: ruff check .
- run: pytest

Rust

- uses: dtolnay/rust-toolchain@56f84321dbccf38fb67ce29ab63e4754056677e0 # stable
  with:
    toolchain: stable
    components: clippy, rustfmt
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- run: cargo fmt --check
- run: cargo clippy -- -D warnings
- run: cargo test

Go

- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
  with:
    go-version-file: 'go.mod'
- run: go vet ./...
- run: go test -race ./...

Common Pitfalls

MistakeFix
Using
@v4
tags
Pin to full SHA with version comment
Storing AWS keys as secretsUse OIDC with
id-token: write
No timeout on jobsAdd
timeout-minutes: 15
(or appropriate)
Running on every pushAdd path filters for docs-only changes
Self-hosted runners on public reposUse GitHub-hosted or private repos only
pull_request_target
with checkout
Use
pull_request
trigger instead

See

references/advanced-patterns.md
for supply chain security (SLSA, SBOM, signing), reusable workflows, and monorepo patterns.

Output Checklist

After setup, verify:

  • All actions pinned to SHA with version comment
  • permissions:
    block explicitly set
  • concurrency:
    prevents duplicate runs
  • timeout-minutes:
    set on all jobs
  • Dependabot configured for actions AND dependencies
  • No long-lived credentials (use OIDC where possible)
  • Tests pass locally before pushing workflow