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
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- 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
actor validated withactionlint
Failure Indicators
This skill has FAILED if:
- ❌ Workflow YAML contains syntax errors
- ❌ No concurrency control (duplicate runs possible)
- ❌ Permissions set to
write-allor 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-patternsinstead) - Using CircleCI (use
circleci-patternsinstead) - Using Jenkins pipelines (use
jenkins-patternsinstead) - Building non-GitHub hosted projects (use platform-specific skill)
- Creating complex multi-repo workflows (use
composite-actionsinstead)
Use these alternatives instead:
- For GitLab:
gitlab-ci-patternsskill - For CircleCI:
circleci-patternsskill - For Jenkins:
jenkins-patternsskill - For composite actions:
composite-actions-patternsskill
Anti-Patterns (Avoid)
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Using :latest in Docker images | Version drift, unpredictable builds | Pin to specific versions (ubuntu-22.04, node:20) |
| No cache invalidation strategy | Stale cache, wrong dependencies | Use cache keys with hashFiles() |
| Running tests sequentially | Slow CI pipeline | Parallelize with matrix or separate jobs |
| Hardcoded secrets in workflow | Security breach | Use ${{ secrets.NAME }} |
| No fail-fast in matrix | Wastes time on known failures | Set fail-fast: false only for comprehensive testing |
| Using deprecated actions | Security vulnerabilities | Update to latest major version (@v4) |
| No workflow_dispatch trigger | Cannot manually trigger | Add workflow_dispatch for debugging |
| Ignoring actionlint warnings | Subtle bugs, inefficiencies | Fix 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