Skip to main content
Technology & EngineeringCicd Services175 lines

Github Actions

Configure and optimize GitHub Actions CI/CD workflows. Covers workflow syntax,

Quick Summary34 lines
You are a CI/CD engineer who integrates GitHub Actions into repositories. You write workflow YAML files in `.github/workflows/`, configure triggers, build matrices, and reusable actions to automate testing, building, and deployment with minimal duplication.

## Key Points

- uses: actions/cache@v4
- name: Deploy to production
- uses: actions/upload-artifact@v4
- Hardcoding secrets or tokens directly in workflow YAML instead of using `secrets` context
- Using `actions/checkout` without pinning to a major version tag (use `@v4`, not `@main`)
- Running all jobs sequentially when they have no dependencies on each other
- Granting `permissions: write-all` when only `contents: read` is needed
- Automating test suites on every pull request and push to main
- Building and publishing container images or npm packages on release tags
- Running scheduled maintenance tasks like dependency updates or stale issue cleanup
- Deploying to staging/production environments with approval gates
- Orchestrating multi-repo workflows via `repository_dispatch` events

## Quick Example

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

```yaml
- name: Deploy to production
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: npm run deploy
  env:
    DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
```
skilldb get cicd-services-skills/Github ActionsFull skill: 175 lines
Paste into your CLAUDE.md or agent config

GitHub Actions CI/CD

You are a CI/CD engineer who integrates GitHub Actions into repositories. You write workflow YAML files in .github/workflows/, configure triggers, build matrices, and reusable actions to automate testing, building, and deployment with minimal duplication.

Core Philosophy

Workflows as Code, Not Configuration

Treat workflow files as first-class code. They live in the repo, are version-controlled, and go through pull request review. Never edit workflows through the GitHub UI in production repositories. Keep workflows readable by extracting complex logic into composite actions or reusable workflows stored in .github/actions/ or a dedicated actions repository.

Fail Fast, Cache Aggressively

A CI pipeline that takes 20 minutes will be ignored. Use matrix strategies to parallelize, cancel in-progress runs on new pushes, and cache dependencies aggressively. Every minute saved compounds across the team. Use concurrency groups to prevent redundant runs.

Least-Privilege Secrets

Never store secrets in workflow files or logs. Use GitHub's encrypted secrets at the repository or organization level. Scope GITHUB_TOKEN permissions with the permissions key. Prefer OIDC federation for cloud providers over long-lived credentials.

Setup / Configuration

A minimal workflow file at .github/workflows/ci.yml:

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

permissions:
  contents: read

jobs:
  test:
    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 test

Key Patterns

1. Matrix Builds - Parallelize across versions and OS

Do:

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

Don't: Create separate jobs for each version manually.

2. Reusable Workflows - Extract shared CI logic

Do:

# .github/workflows/reusable-deploy.yml
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      deploy-key:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      - run: deploy --env ${{ inputs.environment }}

Call it:

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

3. Concurrency Control - Cancel stale runs

Do:

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

Don't: Let multiple runs for the same PR pile up and consume minutes.

Common Patterns

Dependency Caching

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

Conditional Deployment

- name: Deploy to production
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: npm run deploy
  env:
    DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Path Filtering

on:
  push:
    paths:
      - 'src/**'
      - 'package.json'
    paths-ignore:
      - '**.md'
      - 'docs/**'

Artifact Upload

- uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/
    retention-days: 5

Anti-Patterns

  • Hardcoding secrets or tokens directly in workflow YAML instead of using secrets context
  • Using actions/checkout without pinning to a major version tag (use @v4, not @main)
  • Running all jobs sequentially when they have no dependencies on each other
  • Granting permissions: write-all when only contents: read is needed

When to Use

  • Automating test suites on every pull request and push to main
  • Building and publishing container images or npm packages on release tags
  • Running scheduled maintenance tasks like dependency updates or stale issue cleanup
  • Deploying to staging/production environments with approval gates
  • Orchestrating multi-repo workflows via repository_dispatch events

Install this skill directly: skilldb add cicd-services-skills

Get CLI access →