Ci Cd Pipeline Builder
npx machina-cli add skill alirezarezvani/claude-skills/ci-cd-pipeline-builder --openclawCI/CD Pipeline Builder
Tier: POWERFUL
Category: Engineering
Domain: DevOps / Automation
Overview
Analyzes your project stack and generates production-ready CI/CD pipeline configurations for GitHub Actions, GitLab CI, and Bitbucket Pipelines. Handles matrix testing, caching strategies, deployment stages, environment promotion, and secret management — tailored to your actual tech stack.
Core Capabilities
- Stack detection — reads
package.json,Dockerfile,pyproject.toml,go.mod, etc. - Pipeline generation — GitHub Actions, GitLab CI, Bitbucket Pipelines
- Matrix testing — multi-version, multi-OS, multi-environment
- Smart caching — npm, pip, Docker layer, Gradle, Maven
- Deployment stages — build → test → staging → production with approvals
- Environment promotion — automatic on green tests, manual gate for production
- Secret management — patterns for GitHub Secrets, GitLab CI Variables, Vault, AWS SSM
When to Use
- Starting a new project and need a CI/CD baseline
- Migrating from one CI platform to another
- Adding deployment stages to an existing pipeline
- Auditing a slow pipeline and optimizing caching
- Setting up environment promotion with manual approval gates
Workflow
Step 1 — Stack Detection
Ask Claude to analyze your repo:
Analyze my repo and generate a GitHub Actions CI/CD pipeline.
Check: package.json, Dockerfile, .nvmrc, pyproject.toml, go.mod
Claude will inspect:
| File | Signals |
|---|---|
package.json | Node version, test runner, build tool |
.nvmrc / .node-version | Exact Node version |
Dockerfile | Base image, multi-stage build |
pyproject.toml | Python version, test runner |
go.mod | Go version |
vercel.json | Vercel deployment config |
k8s/ or helm/ | Kubernetes deployment |
Complete Example: Next.js + Vercel
# .github/workflows/ci.yml
name: CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
PNPM_VERSION: '8'
jobs:
lint-typecheck:
name: Lint & Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
test:
name: Test (Node ${{ matrix.node }})
runs-on: ubuntu-latest
strategy:
matrix:
node: ['18', '20', '22']
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Run tests with coverage
run: pnpm test:ci
env:
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
name: Build
runs-on: ubuntu-latest
needs: [lint-typecheck, test]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
env:
NEXT_PUBLIC_API_URL: ${{ vars.NEXT_PUBLIC_API_URL }}
- uses: actions/upload-artifact@v4
with:
name: build-${{ github.sha }}
path: .next/
retention-days: 7
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment:
name: staging
url: https://staging.myapp.com
steps:
- uses: actions/checkout@v4
- uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://myapp.com
steps:
- uses: actions/checkout@v4
- uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Complete Example: Python + AWS Lambda
# .github/workflows/deploy.yml
name: Python Lambda CI/CD
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- run: pip install -r requirements-dev.txt
- run: pytest tests/ -v --cov=src --cov-report=xml
- run: mypy src/
- run: ruff check src/ tests/
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- run: pip install bandit safety
- run: bandit -r src/ -ll
- run: safety check
package:
needs: [test, security]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Build Lambda zip
run: |
pip install -r requirements.txt --target ./package
cd package && zip -r ../lambda.zip .
cd .. && zip lambda.zip -r src/
- uses: actions/upload-artifact@v4
with:
name: lambda-${{ github.sha }}
path: lambda.zip
deploy-staging:
needs: package
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/download-artifact@v4
with:
name: lambda-${{ github.sha }}
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- run: |
aws lambda update-function-code \
--function-name myapp-staging \
--zip-file fileb://lambda.zip
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/download-artifact@v4
with:
name: lambda-${{ github.sha }}
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- run: |
aws lambda update-function-code \
--function-name myapp-production \
--zip-file fileb://lambda.zip
VERSION=$(aws lambda publish-version \
--function-name myapp-production \
--query 'Version' --output text)
aws lambda update-alias \
--function-name myapp-production \
--name live \
--function-version $VERSION
Complete Example: Docker + Kubernetes
# .github/workflows/k8s-deploy.yml
name: Docker + Kubernetes
on:
push:
branches: [main]
tags: ['v*']
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image-digest: ${{ steps.push.outputs.digest }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=sha,prefix=sha-
- name: Build and push
id: push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-staging:
needs: build-push
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- uses: azure/setup-kubectl@v3
- name: Set kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG_STAGING }}" | base64 -d > /tmp/kubeconfig
echo "KUBECONFIG=/tmp/kubeconfig" >> $GITHUB_ENV
- name: Deploy
run: |
kubectl set image deployment/myapp \
myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build-push.outputs.image-digest }} \
-n staging
kubectl rollout status deployment/myapp -n staging --timeout=5m
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: azure/setup-kubectl@v3
- name: Set kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG_PROD }}" | base64 -d > /tmp/kubeconfig
echo "KUBECONFIG=/tmp/kubeconfig" >> $GITHUB_ENV
- name: Canary deploy
run: |
kubectl set image deployment/myapp-canary \
myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build-push.outputs.image-digest }} \
-n production
kubectl rollout status deployment/myapp-canary -n production --timeout=5m
sleep 120
kubectl set image deployment/myapp \
myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build-push.outputs.image-digest }} \
-n production
kubectl rollout status deployment/myapp -n production --timeout=10m
GitLab CI Equivalent
# .gitlab-ci.yml
stages: [lint, test, build, deploy-staging, deploy-production]
variables:
NODE_VERSION: "20"
DOCKER_BUILDKIT: "1"
.node-cache: &node-cache
cache:
key:
files: [pnpm-lock.yaml]
paths:
- node_modules/
- .pnpm-store/
lint:
stage: lint
image: node:${NODE_VERSION}-alpine
<<: *node-cache
script:
- corepack enable && pnpm install --frozen-lockfile
- pnpm lint && pnpm typecheck
test:
stage: test
image: node:${NODE_VERSION}-alpine
<<: *node-cache
parallel:
matrix:
- NODE_VERSION: ["18", "20", "22"]
script:
- corepack enable && pnpm install --frozen-lockfile
- pnpm test:ci
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
deploy-staging:
stage: deploy-staging
environment:
name: staging
url: https://staging.myapp.com
only: [develop]
script:
- npx vercel --token=$VERCEL_TOKEN
deploy-production:
stage: deploy-production
environment:
name: production
url: https://myapp.com
only: [main]
when: manual
script:
- npx vercel --prod --token=$VERCEL_TOKEN
Secret Management Patterns
GitHub Actions — Secret Hierarchy
Repository secrets → all branches
Environment secrets → only that environment
Organization secrets → all repos in org
Fetching from AWS SSM at runtime
- name: Load secrets from SSM
run: |
DB_URL=$(aws ssm get-parameter \
--name "/myapp/production/DATABASE_URL" \
--with-decryption \
--query 'Parameter.Value' --output text)
echo "DATABASE_URL=$DB_URL" >> $GITHUB_ENV
env:
AWS_REGION: eu-west-1
HashiCorp Vault integration
- uses: hashicorp/vault-action@v2
with:
url: ${{ secrets.VAULT_ADDR }}
token: ${{ secrets.VAULT_TOKEN }}
secrets: |
secret/data/myapp/prod DATABASE_URL | DATABASE_URL ;
secret/data/myapp/prod API_KEY | API_KEY
Caching Cheat Sheet
| Stack | Cache key | Cache path |
|---|---|---|
| npm | package-lock.json | ~/.npm |
| pnpm | pnpm-lock.yaml | ~/.pnpm-store |
| pip | requirements.txt | ~/.cache/pip |
| poetry | poetry.lock | ~/.cache/pypoetry |
| Docker | SHA of Dockerfile | GHA cache (type=gha) |
| Go | go.sum | ~/go/pkg/mod |
Common Pitfalls
- Secrets in logs — never
echo $SECRET; use::add-mask::$SECRETif needed - No concurrency limits — add
concurrency:to cancel stale runs on PR push - Skipping
--frozen-lockfile— lockfile drift breaks reproducibility - No rollback plan — test
kubectl rollout undoorvercel rollbackbefore you need it - Mutable image tags — never use
latestin production; tag by git SHA - Missing environment protection rules — set required reviewers in GitHub Environments
Best Practices
- Fail fast — lint/typecheck before expensive test jobs
- Artifact immutability — Docker image tagged by git SHA
- Environment parity — same image through all envs, config via env vars
- Canary first — 10% traffic + error rate check before 100%
- Pin action versions —
@v4not@main - Least privilege — each job gets only the IAM scopes it needs
- Notify on failure — Slack webhook for production deploy failures
Source
git clone https://github.com/alirezarezvani/claude-skills/blob/main/engineering/ci-cd-pipeline-builder/SKILL.mdView on GitHub Overview
Analyzes your project stack and generates production-ready CI/CD pipeline configurations for GitHub Actions, GitLab CI, and Bitbucket Pipelines. It accounts for matrix testing, caching strategies, deployment stages, environment promotion, and secret management tailored to your tech stack.
How This Skill Works
The tool performs stack detection by reading files like package.json, Dockerfile, pyproject.toml, and go.mod to infer tooling and versions. It then generates ready-to-use YAML configurations for GitHub Actions, GitLab CI, or Bitbucket Pipelines, with support for matrix testing, smart caching, deployment stages, and secure secret handling.
When to Use It
- Starting a new project and need a CI/CD baseline
- Migrating from one CI platform to another
- Adding deployment stages to an existing pipeline
- Auditing a slow pipeline and optimizing caching
- Setting up environment promotion with manual approval gates
Quick Start
- Step 1: Analyze my repo and detect stack (e.g., package.json, Dockerfile, go.mod, pyproject.toml)
- Step 2: Generate CI/CD configs for GitHub Actions, GitLab CI, or Bitbucket Pipelines with matrix testing and caching
- Step 3: Commit the generated YAML, run a test pipeline, and adjust deployment gates and secrets as needed
Best Practices
- Ensure stack detection reads key files (package.json, Dockerfile, pyproject.toml, go.mod) to infer versions accurately
- Leverage matrix testing to cover multi-version, multi-OS, and multi-environment scenarios
- Apply smart caching (npm, pip, Docker layer, Gradle, Maven) to reduce build times
- Define deployment stages (build → test → staging → production) with clear approval gates
- Use robust secret management patterns for GitHub Secrets, GitLab CI Variables, Vault, and AWS SSM
Example Use Cases
- Next.js app with GitHub Actions implementing matrix Node versions and a Vercel deployment step
- Python service using Docker and pyproject.toml configured in GitLab CI with caching
- Node monorepo pipeline across multiple services with GitHub Actions matrix jobs
- Go microservice pipeline using Bitbucket Pipelines with multi-stage deployment
- Java project (Gradle) featuring build, test, cache optimization, and staging/production gates