ci-cd-pipeline-patterns

CI/CD Pipeline Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ci-cd-pipeline-patterns" with this command: npx skills add manutej/luxor-claude-marketplace/manutej-luxor-claude-marketplace-ci-cd-pipeline-patterns

CI/CD Pipeline Patterns

A comprehensive skill for designing, implementing, and optimizing CI/CD pipelines using GitHub Actions and modern DevOps practices. Master workflow automation, testing strategies, deployment patterns, and release management for continuous software delivery.

When to Use This Skill

Use this skill when:

  • Setting up continuous integration and deployment pipelines for projects

  • Automating build, test, and deployment workflows

  • Implementing multi-environment deployment strategies (staging, production)

  • Managing release automation and versioning

  • Configuring matrix builds for multi-platform testing

  • Securing CI/CD pipelines with secrets and OIDC

  • Optimizing pipeline performance with caching and parallelization

  • Building containerized applications with Docker in CI

  • Deploying to cloud platforms (AWS, Azure, GCP, Vercel, Netlify)

  • Implementing infrastructure as code with Terraform/CloudFormation

  • Setting up monorepo CI/CD patterns

  • Creating reusable workflow templates and custom actions

  • Implementing deployment strategies (blue-green, canary, rolling)

  • Automating changelog generation and semantic versioning

  • Integrating quality gates and code coverage checks

Core Concepts

CI/CD Fundamentals

Continuous Integration (CI): Automatically building and testing code changes as developers commit to the repository.

Continuous Deployment (CD): Automatically deploying code changes to production after passing tests.

Continuous Delivery: Keeping code in a deployable state, with manual approval for production deployment.

GitHub Actions Architecture

GitHub Actions provides event-driven automation directly integrated with your repository.

Workflows

YAML files in .github/workflows/ that define automated processes:

name: CI Pipeline on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build project run: npm run build

Key Components:

  • name: Human-readable workflow name

  • on: Events that trigger the workflow (push, pull_request, schedule, workflow_dispatch)

  • jobs: Collection of steps that run in sequence or parallel

  • runs-on: The runner environment (ubuntu-latest, windows-latest, macos-latest)

Jobs

Groups of steps executed on the same runner:

jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm test

deploy: needs: test # Runs after 'test' job completes runs-on: ubuntu-latest steps: - run: npm run deploy

Job Features:

  • needs: Define job dependencies (sequential execution)

  • if: Conditional execution based on expressions

  • strategy: Matrix builds for multiple configurations

  • outputs: Share data between jobs

  • environment: Deployment environments with protection rules

Steps

Individual tasks within a job:

steps:

  • name: Checkout code uses: actions/checkout@v4

  • name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'

  • name: Install dependencies run: npm ci

  • name: Run tests run: npm test

Step Types:

  • uses: Run a pre-built action from marketplace or repository

  • run: Execute shell commands

  • with: Provide inputs to actions

  • env: Set environment variables for the step

Actions

Reusable units of code that perform specific tasks:

Official Actions:

  • actions/checkout@v4 : Check out repository code

  • actions/setup-node@v4 : Setup Node.js environment

  • actions/cache@v4 : Cache dependencies

  • actions/upload-artifact@v4 : Upload build artifacts

  • actions/download-artifact@v4 : Download artifacts from previous jobs

Marketplace Actions:

  • docker/build-push-action@v5 : Build and push Docker images

  • aws-actions/configure-aws-credentials@v4 : Configure AWS credentials

  • codecov/codecov-action@v4 : Upload code coverage

  • google-github-actions/auth@v2 : Authenticate with Google Cloud

Secrets and Variables

Secrets: Encrypted sensitive data (API keys, credentials, tokens)

steps:

  • name: Deploy to production env: API_KEY: ${{ secrets.API_KEY }} DATABASE_URL: ${{ secrets.DATABASE_URL }} run: npm run deploy

Variables: Non-sensitive configuration data

env: NODE_ENV: ${{ vars.NODE_ENV }} API_ENDPOINT: ${{ vars.API_ENDPOINT }}

Secret Types:

  • Repository secrets: Available to all workflows in a repository

  • Environment secrets: Scoped to specific environments (production, staging)

  • Organization secrets: Shared across repositories in an organization

Artifacts

Files produced by workflows that can be downloaded or used by other jobs:

  • name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: dist-files path: dist/ retention-days: 7

  • name: Download artifacts uses: actions/download-artifact@v4 with: name: dist-files path: ./dist

Workflow Triggers

Event Triggers

Push Events:

on: push: branches: - main - develop - 'release/' paths: - 'src/' - 'package.json' tags: - 'v*'

Pull Request Events:

on: pull_request: types: [opened, synchronize, reopened] branches: - main paths-ignore: - 'docs/' - '.md'

Schedule (Cron):

on: schedule: - cron: '0 0 * * *' # Daily at midnight UTC - cron: '0 */6 * * *' # Every 6 hours

Manual Triggers (workflow_dispatch):

on: workflow_dispatch: inputs: environment: description: 'Environment to deploy to' required: true type: choice options: - staging - production version: description: 'Version to deploy' required: true type: string

Release Events:

on: release: types: [published, created, released]

Workflow Call (Reusable Workflows):

on: workflow_call: inputs: environment: required: true type: string secrets: api-key: required: true

Matrix Builds

Run jobs across multiple configurations in parallel:

jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] node-version: [18, 20, 22] include: - os: ubuntu-latest node-version: 20 coverage: true exclude: - os: macos-latest node-version: 18 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm test - if: matrix.coverage run: npm run coverage

Matrix Features:

  • Parallel execution: All combinations run simultaneously

  • include: Add specific configurations

  • exclude: Remove specific combinations

  • fail-fast: Stop all jobs if one fails (default: true)

  • max-parallel: Limit concurrent jobs

Caching Strategies

Speed up workflows by caching dependencies:

Node.js Caching:

  • uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' # Automatically caches npm dependencies

Custom Caching:

  • uses: actions/cache@v4 with: path: | ~/.npm ~/.cache node_modules key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node-

Docker Layer Caching:

  • uses: docker/build-push-action@v5 with: context: . cache-from: type=gha cache-to: type=gha,mode=max

Testing Strategies in CI

Unit Testing

Fast, isolated tests for individual components:

jobs: unit-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'

  - name: Install dependencies
    run: npm ci

  - name: Run unit tests
    run: npm run test:unit -- --coverage

  - name: Upload coverage
    uses: codecov/codecov-action@v4
    with:
      files: ./coverage/coverage-final.json
      flags: unit-tests
      token: ${{ secrets.CODECOV_TOKEN }}

Integration Testing

Test interactions between components and services:

jobs: integration-tests: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_PASSWORD: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432

  redis:
    image: redis:7
    options: >-
      --health-cmd "redis-cli ping"
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5
    ports:
      - 6379:6379

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Run database migrations
    env:
      DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
    run: npm run migrate

  - name: Run integration tests
    env:
      DATABASE_URL: postgresql://postgres:postgres@localhost:5432/testdb
      REDIS_URL: redis://localhost:6379
    run: npm run test:integration

End-to-End Testing

Test complete user workflows:

jobs: e2e-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Build application
    run: npm run build

  - name: Install Playwright browsers
    run: npx playwright install --with-deps

  - name: Run E2E tests
    run: npm run test:e2e

  - name: Upload test results
    if: always()
    uses: actions/upload-artifact@v4
    with:
      name: playwright-report
      path: playwright-report/
      retention-days: 30

Performance Testing

Benchmark and performance regression testing:

jobs: performance-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Build for production
    run: npm run build

  - name: Run Lighthouse CI
    uses: treosh/lighthouse-ci-action@v11
    with:
      urls: |
        http://localhost:3000
        http://localhost:3000/dashboard
      uploadArtifacts: true
      temporaryPublicStorage: true

  - name: Run load tests
    run: npm run test:load

Code Quality and Linting

Enforce code standards and quality gates:

jobs: code-quality: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Run ESLint
    run: npm run lint

  - name: Run Prettier check
    run: npm run format:check

  - name: Run TypeScript check
    run: npm run type-check

  - name: Run security audit
    run: npm audit --audit-level=moderate

  - name: SonarCloud Scan
    uses: SonarSource/sonarcloud-github-action@master
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

Deployment Patterns

Blue-Green Deployment

Zero-downtime deployment by maintaining two identical environments:

jobs: deploy-blue-green: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Deploy to Green environment
    run: |
      # Deploy new version to green environment
      ./deploy.sh green

  - name: Run smoke tests on Green
    run: |
      # Verify green environment is healthy
      curl -f https://green.example.com/health

  - name: Switch traffic to Green
    run: |
      # Update load balancer to point to green
      aws elbv2 modify-rule --rule-arn $RULE_ARN \
        --actions Type=forward,TargetGroupArn=$GREEN_TG

  - name: Monitor Green environment
    run: |
      # Monitor for 5 minutes
      ./monitor.sh green 300

  - name: Rollback if needed
    if: failure()
    run: |
      # Switch back to blue
      aws elbv2 modify-rule --rule-arn $RULE_ARN \
        --actions Type=forward,TargetGroupArn=$BLUE_TG

Canary Deployment

Gradual rollout to a subset of users:

jobs: canary-deployment: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Deploy canary (10% traffic)
    run: |
      kubectl set image deployment/app app=myapp:${{ github.sha }}
      kubectl scale deployment/app-canary --replicas=1
      kubectl annotate service app-service \
        traffic-split='{"canary": 10, "stable": 90}'

  - name: Monitor canary metrics
    run: |
      # Monitor error rates, latency for 15 minutes
      ./monitor-canary.sh 900

  - name: Increase canary traffic (50%)
    run: |
      kubectl annotate service app-service \
        traffic-split='{"canary": 50, "stable": 50}' --overwrite

  - name: Monitor again
    run: ./monitor-canary.sh 600

  - name: Full rollout (100%)
    run: |
      kubectl set image deployment/app-stable app=myapp:${{ github.sha }}
      kubectl scale deployment/app-canary --replicas=0

  - name: Rollback canary
    if: failure()
    run: |
      kubectl scale deployment/app-canary --replicas=0

Rolling Deployment

Sequential update of instances:

jobs: rolling-deployment: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Deploy with rolling update
    run: |
      kubectl set image deployment/app \
        app=myapp:${{ github.sha }} \
        --record

  - name: Wait for rollout to complete
    run: |
      kubectl rollout status deployment/app --timeout=10m

  - name: Verify deployment
    run: |
      kubectl get pods -l app=myapp
      curl -f https://api.example.com/health

  - name: Rollback on failure
    if: failure()
    run: |
      kubectl rollout undo deployment/app

Multi-Environment Deployment

Deploy to staging, then production with approvals:

jobs: deploy-staging: runs-on: ubuntu-latest environment: name: staging url: https://staging.example.com steps: - uses: actions/checkout@v4 - name: Deploy to staging run: ./deploy.sh staging

deploy-production: needs: deploy-staging runs-on: ubuntu-latest environment: name: production url: https://example.com steps: - uses: actions/checkout@v4 - name: Deploy to production run: ./deploy.sh production

Security Best Practices

Secret Management

Using GitHub Secrets:

steps:

  • name: Configure AWS credentials 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: us-east-1

Environment-Scoped Secrets:

jobs: deploy: environment: production # Uses production-scoped secrets steps: - name: Deploy env: API_KEY: ${{ secrets.PRODUCTION_API_KEY }} run: ./deploy.sh

OIDC (OpenID Connect)

Authenticate without long-lived credentials:

jobs: deploy: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@v4

  - name: Configure AWS credentials (OIDC)
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
      aws-region: us-east-1

  - name: Deploy to AWS
    run: aws s3 sync ./dist s3://my-bucket

Google Cloud OIDC:

  • name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/pool/providers/provider' service_account: 'github-actions@project.iam.gserviceaccount.com'

Secure Workflows

Restrict permissions:

permissions: contents: read # Read repository contents pull-requests: write # Comment on PRs id-token: write # OIDC token generation actions: read # Read workflow runs

Pin action versions to SHA:

Less secure (tag can be moved)

  • uses: actions/checkout@v4

More secure (immutable SHA)

  • uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

Prevent script injection:

Vulnerable to injection

  • run: echo "Hello ${{ github.event.issue.title }}"

Safe approach

  • run: echo "Hello $TITLE" env: TITLE: ${{ github.event.issue.title }}

Docker in CI/CD

Building Docker Images

jobs: build-docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v3

  - name: Login to Docker Hub
    uses: docker/login-action@v3
    with:
      username: ${{ secrets.DOCKER_USERNAME }}
      password: ${{ secrets.DOCKER_PASSWORD }}

  - name: Extract metadata
    id: meta
    uses: docker/metadata-action@v5
    with:
      images: myorg/myapp
      tags: |
        type=ref,event=branch
        type=ref,event=pr
        type=semver,pattern={{version}}
        type=semver,pattern={{major}}.{{minor}}
        type=sha,prefix={{branch}}-

  - name: Build and push
    uses: docker/build-push-action@v5
    with:
      context: .
      platforms: linux/amd64,linux/arm64
      push: true
      tags: ${{ steps.meta.outputs.tags }}
      labels: ${{ steps.meta.outputs.labels }}
      cache-from: type=gha
      cache-to: type=gha,mode=max

Multi-Stage Docker Builds

Build stage

FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build

Production stage

FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY package*.json ./ EXPOSE 3000 CMD ["npm", "start"]

Container Scanning

  • name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: 'myorg/myapp:${{ github.sha }}' format: 'sarif' output: 'trivy-results.sarif'

  • name: Upload Trivy results to GitHub Security uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif'

Release Automation

Semantic Versioning

Automatically version releases based on commit messages:

jobs: release: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 with: fetch-depth: 0

  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Semantic Release
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
    run: npx semantic-release

Configuration (.releaserc.json):

{ "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", "@semantic-release/npm", "@semantic-release/github", ["@semantic-release/git", { "assets": ["CHANGELOG.md", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" }] ] }

Changelog Generation

  • name: Generate changelog uses: mikepenz/release-changelog-builder-action@v4 with: configuration: '.github/changelog-config.json' outputFile: 'CHANGELOG.md' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  • name: Create GitHub Release uses: ncipollo/release-action@v1 with: tag: ${{ steps.version.outputs.tag }} name: Release ${{ steps.version.outputs.tag }} bodyFile: 'CHANGELOG.md' artifacts: 'dist/*'

Release Notes Automation

  • name: Build Release Notes id: release_notes uses: mikepenz/release-changelog-builder-action@v4 with: configurationJson: | { "categories": [ { "title": "## 🚀 Features", "labels": ["feature", "enhancement"] }, { "title": "## 🐛 Fixes", "labels": ["bug", "fix"] }, { "title": "## 📝 Documentation", "labels": ["documentation"] } ] } env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Monorepo CI/CD Patterns

Path-Based Triggers

Run workflows only when specific packages change:

name: Frontend CI on: push: paths: - 'packages/frontend/**' - 'package.json' - 'pnpm-lock.yaml'

jobs: test-frontend: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Test frontend run: pnpm --filter frontend test

Affected Package Detection

jobs: detect-changes: runs-on: ubuntu-latest outputs: affected: ${{ steps.affected.outputs.packages }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0

  - name: Detect affected packages
    id: affected
    run: |
      # Use tools like Nx or Turborepo to detect changes
      AFFECTED=$(npx nx affected:apps --base=origin/main --plain)
      echo "packages=$AFFECTED" >> $GITHUB_OUTPUT

test-affected: needs: detect-changes runs-on: ubuntu-latest strategy: matrix: package: ${{ fromJson(needs.detect-changes.outputs.affected) }} steps: - uses: actions/checkout@v4 - name: Test ${{ matrix.package }} run: npm run test --workspace=${{ matrix.package }}

Turborepo CI

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'

  - name: Install dependencies
    run: npm ci

  - name: Build with Turborepo
    run: npx turbo build --cache-dir=.turbo

  - name: Cache Turbo
    uses: actions/cache@v4
    with:
      path: .turbo
      key: ${{ runner.os }}-turbo-${{ github.sha }}
      restore-keys: |
        ${{ runner.os }}-turbo-

Performance Optimization

Parallel Job Execution

jobs:

These jobs run in parallel

lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run lint

unit-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run test:unit

build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run build

This job waits for all above to complete

deploy: needs: [lint, unit-test, build] runs-on: ubuntu-latest steps: - run: npm run deploy

Conditional Job Execution

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run build

deploy-staging: needs: build if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest steps: - run: ./deploy.sh staging

deploy-production: needs: build if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - run: ./deploy.sh production

Dependency Caching

steps:

Node.js with npm

  • uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'

Python with pip

  • uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip'

Ruby with bundler

  • uses: ruby/setup-ruby@v1 with: ruby-version: '3.2' bundler-cache: true

Go modules

  • uses: actions/setup-go@v5 with: go-version: '1.21' cache: true

Reusable Workflows

Creating Reusable Workflows

.github/workflows/reusable-deploy.yml

name: Reusable Deploy Workflow

on: workflow_call: inputs: environment: required: true type: string version: required: false type: string default: 'latest' secrets: deploy-key: required: true outputs: deployment-url: description: "URL of the deployment" value: ${{ jobs.deploy.outputs.url }}

jobs: deploy: runs-on: ubuntu-latest environment: ${{ inputs.environment }} outputs: url: ${{ steps.deploy.outputs.url }} steps: - uses: actions/checkout@v4

  - name: Deploy
    id: deploy
    env:
      DEPLOY_KEY: ${{ secrets.deploy-key }}
    run: |
      ./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
      echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT

Calling Reusable Workflows

.github/workflows/main.yml

name: Main Pipeline

on: [push]

jobs: deploy-staging: uses: ./.github/workflows/reusable-deploy.yml with: environment: staging version: ${{ github.sha }} secrets: deploy-key: ${{ secrets.STAGING_DEPLOY_KEY }}

deploy-production: needs: deploy-staging uses: ./.github/workflows/reusable-deploy.yml with: environment: production version: ${{ github.sha }} secrets: deploy-key: ${{ secrets.PRODUCTION_DEPLOY_KEY }}

Infrastructure as Code

Terraform Deployment

jobs: terraform: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Setup Terraform
    uses: hashicorp/setup-terraform@v3
    with:
      terraform_version: 1.7.0

  - name: Terraform Format
    run: terraform fmt -check

  - name: Terraform Init
    run: terraform init
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

  - name: Terraform Validate
    run: terraform validate

  - name: Terraform Plan
    run: terraform plan -out=tfplan
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

  - name: Terraform Apply
    if: github.ref == 'refs/heads/main'
    run: terraform apply -auto-approve tfplan
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

AWS CloudFormation

jobs: deploy-cloudformation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Configure AWS credentials
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
      aws-region: us-east-1

  - name: Deploy CloudFormation stack
    run: |
      aws cloudformation deploy \
        --template-file infrastructure/template.yml \
        --stack-name my-app-stack \
        --parameter-overrides \
          Environment=production \
          Version=${{ github.sha }} \
        --capabilities CAPABILITY_IAM

Best Practices

Workflow Organization

  • Separate concerns: Different workflows for CI, CD, and scheduled tasks

  • Use descriptive names: Clear workflow and job names

  • Organize with directories: Group related workflows

  • Version control: Track workflow changes like code

Efficiency

  • Cache dependencies: Reduce build times significantly

  • Parallel execution: Run independent jobs simultaneously

  • Conditional runs: Skip unnecessary jobs

  • Matrix strategies: Test multiple configurations efficiently

  • Artifact reuse: Share build outputs between jobs

Security

  • Minimize permissions: Use least-privilege principle

  • Use OIDC: Avoid long-lived credentials

  • Secret rotation: Regularly update secrets

  • Pin dependencies: Use specific versions or SHAs

  • Scan for vulnerabilities: Automated security checks

Reliability

  • Timeout settings: Prevent hanging jobs

  • Retry logic: Handle transient failures

  • Failure notifications: Alert on critical failures

  • Rollback mechanisms: Quick recovery from failed deployments

  • Health checks: Verify deployments before marking complete

Observability

  • Detailed logging: Clear, actionable logs

  • Status checks: Prevent merging failing builds

  • Deployment tracking: Know what's deployed where

  • Metrics collection: Track pipeline performance

  • Audit trails: Track who deployed what and when

Failure Handling

Retry Failed Steps

steps:

  • name: Deploy with retry uses: nick-fields/retry-action@v2 with: timeout_minutes: 10 max_attempts: 3 retry_wait_seconds: 30 command: npm run deploy

Continue on Error

jobs: test: runs-on: ubuntu-latest steps: - name: Run optional check continue-on-error: true run: npm run optional-check

  - name: Run required tests
    run: npm test

Conditional Cleanup

steps:

  • name: Deploy id: deploy run: ./deploy.sh

  • name: Rollback on failure if: failure() && steps.deploy.conclusion == 'failure' run: ./rollback.sh

  • name: Cleanup if: always() run: ./cleanup.sh

Advanced Patterns

Dynamic Matrix Generation

jobs: generate-matrix: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - uses: actions/checkout@v4 - id: set-matrix run: | # Generate matrix based on project structure MATRIX=$(find packages -maxdepth 1 -type d -not -name packages |
jq -R -s -c 'split("\n")[:-1]') echo "matrix=$MATRIX" >> $GITHUB_OUTPUT

test: needs: generate-matrix runs-on: ubuntu-latest strategy: matrix: package: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} steps: - uses: actions/checkout@v4 - run: npm test --workspace=${{ matrix.package }}

Composite Actions

Create reusable action combinations:

.github/actions/setup-project/action.yml

name: 'Setup Project' description: 'Setup Node.js and install dependencies' inputs: node-version: description: 'Node.js version' required: false default: '20' runs: using: 'composite' steps: - uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} cache: 'npm'

- run: npm ci
  shell: bash

- run: npm run build
  shell: bash

Usage:

steps:

  • uses: actions/checkout@v4
  • uses: ./.github/actions/setup-project with: node-version: '20'

Self-Hosted Runners

jobs: deploy: runs-on: [self-hosted, linux, production] steps: - uses: actions/checkout@v4 - name: Deploy to production run: ./deploy.sh

Benefits:

  • Custom hardware/software requirements

  • Faster builds (pre-cached dependencies)

  • Access to internal networks

  • Cost savings for high-volume CI/CD

Platform-Specific Deployments

Vercel Deployment

jobs: deploy-vercel: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Deploy to Vercel
    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'

Netlify Deployment

jobs: deploy-netlify: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Build
    run: npm run build

  - name: Deploy to Netlify
    uses: nwtgck/actions-netlify@v3
    with:
      publish-dir: './dist'
      production-branch: main
      github-token: ${{ secrets.GITHUB_TOKEN }}
      deploy-message: 'Deploy from GitHub Actions'
    env:
      NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
      NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

AWS ECS Deployment

jobs: deploy-ecs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Configure AWS credentials
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
      aws-region: us-east-1

  - name: Login to Amazon ECR
    id: login-ecr
    uses: aws-actions/amazon-ecr-login@v2

  - name: Build and push Docker image
    env:
      ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
      ECR_REPOSITORY: my-app
      IMAGE_TAG: ${{ github.sha }}
    run: |
      docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
      docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

  - name: Update ECS service
    run: |
      aws ecs update-service \
        --cluster my-cluster \
        --service my-service \
        --force-new-deployment

Kubernetes Deployment

jobs: deploy-k8s: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Setup kubectl
    uses: azure/setup-kubectl@v3
    with:
      version: 'v1.28.0'

  - name: Configure kubeconfig
    run: |
      echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yml
      echo "KUBECONFIG=$(pwd)/kubeconfig.yml" >> $GITHUB_ENV

  - name: Deploy to Kubernetes
    run: |
      kubectl set image deployment/myapp \
        myapp=myregistry/myapp:${{ github.sha }}
      kubectl rollout status deployment/myapp

Skill Version: 1.0.0 Last Updated: October 2025 Skill Category: DevOps, CI/CD, Automation, Deployment Compatible With: GitHub Actions, Docker, Kubernetes, AWS, Azure, GCP, Vercel, Netlify

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

docker-compose-orchestration

No summary provided by upstream source.

Repository SourceNeeds Review
General

postgresql-database-engineering

No summary provided by upstream source.

Repository SourceNeeds Review
General

jest-react-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

ui-design-patterns

No summary provided by upstream source.

Repository SourceNeeds Review