| name | github-actions |
| description | GitHub Actions workflow generator — CI/CD pipelines, releases, Docker builds, reusable workflows, composite actions, dependabot. Use for .github/workflows/ generation, debugging, and security hardening. |
| when_to_use | Use when the user asks to 'create a CI pipeline', 'add GitHub Actions', 'set up CD', 'create a release workflow', 'build Docker in CI', 'fix my workflow', or mentions .github/workflows/, action.yml, dependabot.yml, workflow_dispatch, or CI/CD automation. Also trigger when debugging failing GitHub Actions runs. |
GitHub Actions Workflow Generator
Generate production-ready GitHub Actions workflow YAML files. Supports CI, CD, releases, Docker, reusable workflows, composite actions, and dependabot configs across multiple languages and frameworks.
Principles
- Secure by default: Pin actions to SHA, minimal permissions, no hardcoded secrets
- Cache everything: Dependencies, build artifacts, Docker layers — always cache
- Fail fast, fail clear: Matrix
fail-fast: true for CI, false for releases
- Concurrency control: Always add concurrency groups for push/PR workflows
- DRY workflows: Extract shared logic into reusable workflows or composite actions
MODE DETECTION (FIRST STEP)
Analyze the user's request to determine workflow type:
| Request Pattern | Mode | Jump To |
|---|
| "CI", "test", "lint", "check" | CI | Phase 1–5 |
| "deploy", "CD", "release to" | DEPLOY | Phase 1–5 |
| "release", "publish", "tag" | RELEASE | Phase 1–5 |
| "Docker", "container", "image" | DOCKER | Phase 1–5 |
| "reusable workflow", "shared workflow" | REUSABLE | Phase 1–5 |
| "composite action", "custom action" | COMPOSITE | Phase 1–5 |
| "dependabot", "renovate", "dependency updates" | DEPENDENCY | Phase 1–5 |
| "fix workflow", "workflow failing" | DEBUG | Debug Flow |
Phase 1: Project Detection (PARALLEL)
Execute ALL in parallel:
ls composer.json package.json pubspec.yaml go.mod Cargo.toml pyproject.toml setup.py requirements.txt Gemfile pom.xml build.gradle 2>/dev/null
ls artisan next.config.* nuxt.config.* angular.json vite.config.* 2>/dev/null
cat composer.json 2>/dev/null | head -20
cat package.json 2>/dev/null | head -20
ls .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null
ls .github/actions/*/action.yml 2>/dev/null
cat .github/dependabot.yml 2>/dev/null
ls .php-cs-fixer.dist.php phpstan.neon pint.json eslint.config.* .eslintrc* biome.json analysis_options.yaml .golangci.yml .flake8 pyproject.toml 2>/dev/null
ls Dockerfile docker-compose.yml docker-compose.yaml 2>/dev/null
Mandatory output:
PROJECT DETECTION
=================
Language: [PHP 8.x | Dart/Flutter | Node.js | Bun | Go | Python | Rust | Java | Multi-stack]
Framework: [Laravel | Next.js | Flutter | Express | FastAPI | None | ...]
Package manager: [composer | npm | pnpm | yarn | bun | pub | go mod | pip | cargo]
Linter: [pint | eslint | biome | golangci-lint | ruff | dart analyze | none]
Test runner: [phpunit | artisan test | jest | vitest | bun test | flutter test | go test | pytest]
Docker: [yes | no]
Existing workflows: [list or none]
Phase 2: Template Selection
Select the base template from references/language-templates.md based on detected stack. Read the reference file for the matching language section.
Multi-stack projects: Generate separate jobs per language within one workflow, using defaults.run.working-directory to isolate contexts.
Phase 3: Security Hardening
Apply ALL of these to every generated workflow. Read references/security-patterns.md for detailed patterns.
Non-negotiable rules:
- Pin actions to SHA —
uses: actions/checkout@<sha> with version comment
- Minimal permissions —
permissions: block on every workflow, default contents: read
- Concurrency groups — Prevent duplicate runs on force-push
- No inline secrets — Always
${{ secrets.NAME }}, never hardcoded
- Validate inputs —
workflow_dispatch inputs must have types and descriptions
Permission mapping:
| Operation | Required Permissions |
|---|
| Read code only | contents: read |
| Push commits | contents: write |
| Comment on PR | pull-requests: write |
| Create release | contents: write |
| Publish package | packages: write, id-token: write (OIDC) |
| Deploy Pages | pages: write, id-token: write |
| Upload coverage | contents: read (only) |
| Create check | checks: write |
| Security scan | security-events: write |
Phase 4: Workflow Generation (BLOCKING OUTPUT)
Present the complete workflow YAML. Consult references/workflow-syntax.md for exact syntax of triggers, expressions, contexts, and runners. Follow the structure order:
name:
on:
permissions:
concurrency:
env:
defaults:
jobs:
job-name:
runs-on:
timeout-minutes:
services:
strategy:
env:
steps:
Step ordering within a job:
1. Checkout code
2. Setup language runtime (with cache)
3. Install dependencies (cached)
4. Lint / static analysis
5. Build (if needed)
6. Test (with coverage)
7. Upload artifacts / coverage
8. Deploy / publish (conditional)
9. Notify (on failure)
Mandatory output:
Phase 5: Verification
After writing the workflow file:
- Validate YAML syntax —
yq eval '.' .github/workflows/<file>.yml > /dev/null
- Check action versions — verify SHA pins match expected versions
- Verify no hardcoded secrets — grep for patterns like
ghp_, sk-, Bearer
- Confirm permissions are minimal — no
write-all or missing permissions: block
- Test trigger logic — verify branch filters match project's branching strategy
Debug Flow
When fixing broken workflows:
- Read the workflow file
- Run
gh run list --workflow=<name>.yml --limit 5 to find recent failures
- Run
gh run view <id> --log-failed to get error details
- Classify: syntax error, action version issue, permission issue, runtime failure
- Fix and verify
Trigger Patterns
CI (push + PR)
on:
push:
branches: [main, master, develop]
pull_request:
branches: [main, master, develop]
CI with path filtering (monorepo)
on:
push:
branches: [main]
paths:
- 'packages/api/**'
- '.github/workflows/api-ci.yml'
pull_request:
paths:
- 'packages/api/**'
Deploy (manual + push)
on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
type: choice
options: [staging, production]
push:
branches: [main]
Release (tag)
on:
push:
tags: ['v*.*.*']
Scheduled
on:
schedule:
- cron: '0 4 * * 1'
Reusable (called by other workflows)
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
DEPLOY_KEY:
required: true
Concurrency Patterns
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
concurrency:
group: deploy-${{ inputs.environment }}
cancel-in-progress: false
Service Container Patterns
services:
postgres:
image: postgres:17
env:
POSTGRES_DB: testing
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready"
--health-interval=10s
--health-timeout=5s
--health-retries=5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=5
Artifact & Caching Patterns
- uses: actions/setup-node@<sha>
with:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: actions/cache@<sha>
with:
path: ~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: ${{ runner.os }}-pub-
- uses: actions/upload-artifact@<sha>
if: failure()
with:
name: test-results
path: test-results/
retention-days: 7
- uses: codecov/codecov-action@<sha>
with:
files: coverage/lcov.info
fail_ci_if_error: false
Matrix Strategies
strategy:
fail-fast: true
matrix:
node-version: [18, 20, 22]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20]
include:
- os: ubuntu-latest
node: 22
exclude:
- os: macos-latest
node: 18
Integration with Other Skills
- git-master: Commit workflow file changes following detected commit style. Use
git-master for the commit, not raw git commit.
- github-cli: Use
gh commands for workflow debugging (gh run view, gh run list), secret management (gh secret set), and variable management (gh variable set).
Anti-Patterns
- Unpinned actions (
uses: actions/checkout@v4) → Pin to SHA with version comment
- Missing
permissions: block → Always declare, default contents: read
- No concurrency group → Duplicate runs waste minutes
runs-on: ubuntu-latest without timeout-minutes → Set 15–30 min for CI
- Hardcoded versions in
run: steps → Use matrix or env vars
npm install instead of npm ci → Use lockfile-based install
- Missing
if: failure() on artifact upload → Only upload on failure
continue-on-error: true on tests → Tests must fail the build
write-all permissions → Declare only what's needed
--force in deploy scripts → Use --force-with-lease or idempotent deploys
References
For detailed guidance on specific topics, read references/ when needed:
| Topic | File | Covers |
|---|
| YAML syntax | workflow-syntax.md | Top-level keys, triggers, jobs, steps, expressions, contexts, runners, composite actions |
| Language templates | language-templates.md | PHP/Laravel, Dart/Flutter, Node.js/Bun, Go, Python, Docker, multi-stack, dependabot |
| Security patterns | security-patterns.md | Action pinning, permissions, secrets, injection prevention, OIDC, supply chain, checklist |