| name | github-actions |
| description | Write and modify GitHub Actions workflows and custom actions. Covers CI/CD, workflow triggers, jobs, steps, secrets, runners, matrix builds, caching, artifacts, environments, and reusable workflows. |
| allowed-tools | Read Edit Write Grep Glob Bash |
GitHub Actions Skill
This skill helps write and modify GitHub Actions workflows and custom actions.
Workflow Basics
Workflows are YAML files stored in .github/workflows/. They define automated processes triggered by events.
Minimal Workflow Structure
name: CI
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- run: echo "Hello"
Triggers (on:)
Common Events
on: push
on: [push, pull_request]
on:
push:
branches: [main, 'releases/**']
paths: ['src/**']
pull_request:
types: [opened, synchronize]
workflow_dispatch:
inputs:
environment:
description: 'Deploy target'
required: true
type: choice
options: [dev, staging, prod]
schedule:
- cron: '0 0 * * *'
Key Events Reference
| Event | Use Case |
|---|
push | Commits pushed to branches/tags |
pull_request | PR opened, updated, closed |
pull_request_target | PR from fork (runs in base context) |
workflow_dispatch | Manual trigger with inputs |
workflow_call | Reusable workflow |
schedule | Cron-based scheduling |
release | Release published/created |
workflow_run | After another workflow completes |
Jobs
Job Dependencies and Outputs
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.value }}
steps:
- id: version
run: echo "value=1.0.0" >> "$GITHUB_OUTPUT"
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Deploying ${{ needs.build.outputs.version }}"
Job Conditions
jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
Matrix Strategy
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20]
exclude:
- os: windows-latest
node: 18
include:
- os: ubuntu-latest
node: 20
coverage: true
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
Steps
Using Actions
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@8f4b7f84...
- uses: ./.github/actions/my-action
- uses: docker://alpine:3.8
Running Commands
steps:
- run: npm install
- run: |
echo "Multi-line"
echo "commands"
shell: bash
working-directory: ./app
Step Conditions
steps:
- run: echo "Always runs"
if: always()
- run: echo "On failure"
if: failure()
- run: echo "Main branch only"
if: github.ref == 'refs/heads/main'
- run: echo "Not cancelled"
if: ${{ !cancelled() }}
Expressions and Contexts
Expression Syntax
Use ${{ expression }} to evaluate expressions. In if: conditions, ${{ }} is optional.
Common Contexts
| Context | Description |
|---|
github.* | Workflow run info (ref, sha, actor, repository) |
env.* | Environment variables |
vars.* | Repository/org variables |
secrets.* | Secrets |
steps.<id>.outputs.* | Step outputs |
needs.<job>.outputs.* | Job outputs |
matrix.* | Matrix values |
runner.* | Runner info (os, arch) |
Useful Expressions
${{ github.event_name }}
${{ github.ref_name }}
${{ github.sha }}
${{ github.actor }}
${{ github.ref == 'refs/heads/main' }}
${{ contains(github.event.head_commit.message, '[skip ci]') }}
${{ startsWith(github.ref, 'refs/tags/') }}
${{ github.head_ref || github.run_id }}
${{ toJSON(github.event) }}
${{ fromJSON(needs.job1.outputs.matrix) }}
Built-in Functions
| Function | Example |
|---|
contains(search, item) | contains(github.event.issue.labels.*.name, 'bug') |
startsWith(str, value) | startsWith(github.ref, 'refs/tags/') |
endsWith(str, value) | endsWith(github.repository, '-demo') |
format(str, ...) | format('Hello {0}', github.actor) |
join(array, sep) | join(matrix.os, ', ') |
toJSON(value) | toJSON(steps.test.outputs) |
fromJSON(str) | fromJSON(needs.setup.outputs.matrix) |
hashFiles(path) | hashFiles('**/package-lock.json') |
Secrets and Variables
Accessing Secrets
steps:
- run: echo "Token: $TOKEN"
env:
TOKEN: ${{ secrets.MY_TOKEN }}
- uses: some-action@v1
with:
api-key: ${{ secrets.API_KEY }}
Environment Variables
env:
NODE_ENV: production
jobs:
build:
env:
CI: true
steps:
- run: echo $MY_VAR
env:
MY_VAR: value
Setting Outputs
steps:
- id: set-output
run: echo "result=success" >> "$GITHUB_OUTPUT"
- run: echo "${{ steps.set-output.outputs.result }}"
Runners
Common labels: ubuntu-latest, windows-latest, macos-latest. Self-hosted: runs-on: [self-hosted, linux, x64]. See references/RUNNERS.md for full specs.
Permissions
permissions:
contents: read
pull-requests: write
id-token: write
permissions: {}
Concurrency
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Artifacts and Caching
Upload/Download Artifacts
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
- uses: actions/download-artifact@v4
with:
name: build-output
Dependency Caching
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
Environments
jobs:
deploy:
environment:
name: production
url: https://example.com
runs-on: ubuntu-latest
Reusable Workflows
Calling a Reusable Workflow
jobs:
call-workflow:
uses: owner/repo/.github/workflows/reusable.yml@main
with:
input1: value
secrets:
token: ${{ secrets.TOKEN }}
Creating a Reusable Workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
token:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"
env:
TOKEN: ${{ secrets.token }}
Common Patterns
Checkout and Setup
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
Conditional on File Changes
on:
push:
paths:
- 'src/**'
- '!src/**/*.md'
Run on Tag Push
on:
push:
tags:
- 'v*'
Workflow Commands Quick Reference
echo "name=value" >> "$GITHUB_OUTPUT"
echo "VAR_NAME=value" >> "$GITHUB_ENV"
echo "### Build Results :rocket:" >> "$GITHUB_STEP_SUMMARY"
echo "| Test | Status |" >> "$GITHUB_STEP_SUMMARY"
echo "| --- | --- |" >> "$GITHUB_STEP_SUMMARY"
echo "| Unit | Passed |" >> "$GITHUB_STEP_SUMMARY"
echo "/path/to/tool" >> "$GITHUB_PATH"
echo "::error file=app.js,line=10::Something failed"
echo "::warning::Deprecation notice"
echo "::notice::FYI message"
echo "::add-mask::$SECRET_VALUE"
See references/WORKFLOW-COMMANDS.md for full details including ::group::, ::debug::, multiline values, and GITHUB_STATE.
Key Limits
| Limit | Value |
|---|
| Workflow run time | 35 days |
| Job execution time | 6 hours (self-hosted: unlimited) |
| Matrix combinations | 256 per workflow |
| Concurrent jobs (Free) | 20 (macOS: 5) |
| Concurrent jobs (Team/Enterprise) | 60 (macOS: 5) |
| Workflow file size | 512 KB |
| Caches total per repo | 10 GB |
| Artifact retention | 90 days (configurable) |
| Log retention | 400 days (configurable to 90) |
See references/LIMITS.md for full limits including API rates and storage quotas.
Troubleshooting
- Workflow not triggering: Check branch/path filters, verify file is in
.github/workflows/
- Permission denied: Add required
permissions: block
- Secret not found: Verify secret name matches exactly (case-sensitive)
- Step output empty: Ensure using
>> "$GITHUB_OUTPUT" (not deprecated set-output)
- Matrix job failing: Check
exclude/include syntax and values
- Debug logging: Re-run workflow with
ACTIONS_RUNNER_DEBUG: true or ACTIONS_STEP_DEBUG: true
References
Core:
references/WORKFLOW-SYNTAX.md - Full workflow YAML syntax
references/EXPRESSIONS.md - Contexts, functions, operators
references/TRIGGERS.md - Event types and filtering
references/WORKFLOW-COMMANDS.md - GITHUB_OUTPUT, GITHUB_ENV, annotations, job summaries
references/LIMITS.md - Time limits, quotas, rate limits by plan
Build and deploy:
references/ACTIONS.md - Creating custom actions (JS, Docker, composite)
references/RUNNERS.md - Runner specs, self-hosted configuration
references/PATTERNS.md - Common workflow patterns
references/LANGUAGE-CI.md - CI setup per language (Node, Python, Java, Go, Rust, Ruby, .NET, Swift)
references/PUBLISHING.md - Publish to npm, PyPI, Docker Hub, GHCR, Maven Central
references/CLOUD-DEPLOYMENTS.md - Deploy to AWS, Azure, GCP with OIDC
Security and ops:
references/SECURITY.md - Secrets, OIDC (AWS/Azure/GCP), attestations, script injection
references/MIGRATION.md - Migrate from Jenkins, Travis CI, CircleCI, GitLab, Azure DevOps
references/ENTERPRISE.md - ARC, runner groups, larger runners, billing, private networking