Skip to main content

GitHub Actions Skill

GitHub Actions Skill

When to Use This Skill

Use this skill when implementing github actions patterns in your codebase.

How to Use This Skill

  1. Review the patterns and examples below
  2. Apply the relevant patterns to your implementation
  3. Follow the best practices outlined in this skill

Comprehensive CI/CD automation with GitHub Actions including workflow optimization, matrix strategies, reusable workflows, and security best practices.

Workflow Structure

Basic Workflow Template

name: CI Pipeline

on:
push:
branches: [main, develop]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production

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

permissions:
contents: read
pull-requests: write

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Build
run: make build

Matrix Strategies

Multi-Platform Matrix

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

Dynamic Matrix Generation

jobs:
prepare:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: |
echo "matrix=$(jq -c . <<< '{"service":["api","web","worker"]}')" >> $GITHUB_OUTPUT

build:
needs: prepare
strategy:
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- run: echo "Building ${{ matrix.service }}"

Reusable Workflows

Caller Workflow

# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]

jobs:
deploy:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
version: ${{ github.sha }}
secrets: inherit

Reusable Workflow Definition

# .github/workflows/reusable-deploy.yml
name: Reusable Deploy

on:
workflow_call:
inputs:
environment:
required: true
type: string
version:
required: true
type: string
secrets:
DEPLOY_TOKEN:
required: true
outputs:
deploy_url:
description: 'Deployed URL'
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
- id: deploy
run: |
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT

Caching Strategies

Node.js Caching

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'

Custom Cache

- uses: actions/cache@v4
id: cache
with:
path: |
~/.cargo/bin/
~/.cargo/registry/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- if: steps.cache.outputs.cache-hit != 'true'
run: cargo build --release

Rust/Cargo Optimization

- uses: Swatinem/rust-cache@v2
with:
shared-key: "build"
cache-targets: true
cache-all-crates: true

Artifact Management

Upload/Download Artifacts

jobs:
build:
runs-on: ubuntu-latest
steps:
- run: make build
- uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
retention-days: 5
if-no-files-found: error

deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build-artifacts
path: dist/

Container Registry

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

Security Hardening

Minimal Permissions

permissions:
contents: read
packages: write
id-token: write # For OIDC

jobs:
deploy:
permissions:
contents: read
deployments: write

Secrets Management

env:
# Use environment secrets for sensitive values
DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
# Mask sensitive output
- run: |
echo "::add-mask::$SECRET_VALUE"
echo "Processing..."
env:
SECRET_VALUE: ${{ secrets.API_KEY }}

Dependency Review

- uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-3.0, AGPL-3.0

OIDC Authentication (No Long-Lived Secrets)

- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActions
aws-region: us-east-1

Performance Optimization

Job Parallelization

jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lint

test:
runs-on: ubuntu-latest
steps:
- run: npm test

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

Self-Hosted Runners

jobs:
build:
runs-on: [self-hosted, linux, x64, gpu]
steps:
- run: nvidia-smi
- run: make train

Conditional Steps

steps:
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: npm run deploy

- if: contains(github.event.pull_request.labels.*.name, 'skip-tests')
run: echo "Skipping tests"

- if: always()
run: npm run cleanup

Common Patterns

Pull Request Checks

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
- run: npm test
- uses: coverallsapp/github-action@v2

Scheduled Jobs

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

jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- run: ./scripts/cleanup-old-artifacts.sh

Release Workflow

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Environment Deployments

jobs:
deploy-staging:
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- run: deploy --env staging

deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: deploy --env production

Testing Workflows

Local Testing with act

# Install act
brew install act

# Run workflow locally
act push

# Run specific job
act -j build

# With secrets
act --secret-file .secrets

actionlint Validation

# Install
brew install actionlint

# Validate all workflows
actionlint

# Validate specific file
actionlint .github/workflows/ci.yml

Troubleshooting

Debug Mode

steps:
- run: |
echo "Event: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "SHA: ${{ github.sha }}"
env:
ACTIONS_STEP_DEBUG: true

Workflow Dispatch Debug

on:
workflow_dispatch:
inputs:
debug:
type: boolean
default: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- if: inputs.debug
run: env | sort

Usage Examples

Implement CI Pipeline

Apply github-actions skill to create comprehensive CI/CD pipeline with caching, matrix testing, and automated deployments

Optimize Existing Workflow

Apply github-actions skill to optimize workflow performance with parallelization, caching strategies, and conditional execution

Success Output

When successful, this skill MUST output:

✅ SKILL COMPLETE: github-actions

Completed:
- [x] Workflow file created/updated (.github/workflows/[name].yml)
- [x] Concurrency and permissions configured
- [x] Caching strategy implemented
- [x] Matrix strategy defined (if applicable)
- [x] Security hardening applied (minimal permissions, secret masking)
- [x] Workflow validated with actionlint

Outputs:
- .github/workflows/[workflow-name].yml
- Workflow validation: PASSED
- Estimated execution time: [X minutes]
- Cache hit ratio: [expected %]

Completion Checklist

Before marking this skill as complete, verify:

  • Workflow YAML syntax valid (no parsing errors)
  • Concurrency group configured to prevent duplicate runs
  • Permissions set to minimal required (not full access)
  • Caching configured for dependencies (npm, cargo, etc.)
  • Matrix strategy optimized (fail-fast: false for comprehensive testing)
  • Secrets properly masked (::add-mask:: for sensitive values)
  • Timeout configured on all jobs (prevent runaway workflows)
  • Workflow tested locally with act or validated with actionlint

Failure Indicators

This skill has FAILED if:

  • ❌ Workflow YAML contains syntax errors
  • ❌ No concurrency control (duplicate runs possible)
  • ❌ Permissions set to write-all or missing entirely
  • ❌ No caching configured for dependency installation
  • ❌ Secrets exposed in logs (not masked)
  • ❌ No timeout set on jobs (can run indefinitely)
  • ❌ Using deprecated actions (actions/checkout@v2 instead of @v4)
  • ❌ Workflow fails actionlint validation

When NOT to Use

Do NOT use this skill when:

  • Using GitLab CI/CD (use gitlab-ci-patterns instead)
  • Using CircleCI (use circleci-patterns instead)
  • Using Jenkins pipelines (use jenkins-patterns instead)
  • Building non-GitHub hosted projects (use platform-specific skill)
  • Creating complex multi-repo workflows (use composite-actions instead)

Use these alternatives instead:

  • For GitLab: gitlab-ci-patterns skill
  • For CircleCI: circleci-patterns skill
  • For Jenkins: jenkins-patterns skill
  • For composite actions: composite-actions-patterns skill

Anti-Patterns (Avoid)

Anti-PatternProblemSolution
Using :latest in Docker imagesVersion drift, unpredictable buildsPin to specific versions (ubuntu-22.04, node:20)
No cache invalidation strategyStale cache, wrong dependenciesUse cache keys with hashFiles()
Running tests sequentiallySlow CI pipelineParallelize with matrix or separate jobs
Hardcoded secrets in workflowSecurity breachUse ${{ secrets.NAME }}
No fail-fast in matrixWastes time on known failuresSet fail-fast: false only for comprehensive testing
Using deprecated actionsSecurity vulnerabilitiesUpdate to latest major version (@v4)
No workflow_dispatch triggerCannot manually triggerAdd workflow_dispatch for debugging
Ignoring actionlint warningsSubtle bugs, inefficienciesFix all actionlint warnings

Principles

This skill embodies:

  • #5 Eliminate Ambiguity - Clear job dependencies and explicit triggers
  • #6 Clear, Understandable, Explainable - Descriptive job names and step descriptions
  • #8 No Assumptions - Validate tool availability, check exit codes
  • #3 Keep It Simple - Reusable workflows over complex inline scripts
  • #2 First Principles - Security-first (minimal permissions, secret masking)

Security-First CI/CD: This skill enforces minimal permissions, OIDC authentication, and secret masking by default.

Integration Points

  • docker-build-patterns - Container image building
  • deployment-automation - Deployment workflows
  • testing-automation - Test execution in CI