GitHub Actions is a declarative continuous integration and continuous delivery (CI/CD) platform integrated into GitHub that enables automated testing, building, linting, and deployment via YAML workflows.
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform natively integrated into the GitHub developer ecosystem. It allows engineering teams to automate software development lifecycles directly from repository events—such as code pushes, pull requests, issue creations, scheduled cron triggers, and release publications. Workflow pipelines are declared as YAML files located in the repository's .github/workflows/ directory, orchestrating automated testing, code linting, security audits, container builds, and production deployments.
Validate and format your CI/CD workflow YAML files with our client-side GitHub Actions YAML Validator, convert pipeline configs with our YAML Converter, and test schedule expressions using the Cron Parser.
| Property | Details |
|---|---|
| Configuration Directory | .github/workflows/ (for workflows) or repository root/subfolder (for action.yml) |
| Configuration Grammar | YAML 1.2 (Strict 2-space indentation; tabs prohibited) |
| Official Runners | ubuntu-latest (Ubuntu 24.04/22.04 LTS), macos-latest (Apple Silicon M-series), windows-latest |
| Self-Hosted Runners | Custom Linux, macOS, and Windows VMs/bare-metal machines registered via runner tokens |
| Expression Syntax | ${{ <expression> }} with built-in functions (hashFiles(), toJSON(), contains(), always()) |
| Action Types | JavaScript actions (node20), Docker container actions, and Composite actions (runs.using: composite) |
| Security Standards | OIDC federation (id-token: write), secret masking, and granular GITHUB_TOKEN permissions |
GitHub Actions structures automation around a four-tier operational hierarchy:
┌─────────────────────────────────────────────────────────┐
│ Workflow (.github/workflows/ci.yml) │
│ Triggered by events: [push, pull_request, schedule] │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Job 1: Lint & Typecheck (runs-on: ubuntu-latest) │ │
│ │ ├─ Step 1: actions/checkout@v4 │ │
│ │ ├─ Step 2: actions/setup-node@v4 │ │
│ │ └─ Step 3: npm run lint │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Job 2: Test Matrix (needs: [Job 1]) │ │
│ │ ├─ Matrix: [Node 20, Node 22] × [Ubuntu, macOS] │ │
│ │ └─ Steps: npm ci -> npm test │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
.github/workflows/*.yml.push, pull_request, workflow_dispatch, repository_dispatch).needs: key.run:) or reusable packaged actions (uses:).name: Production CI/CD Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# Least-privilege permissions
permissions:
contents: read
pull-requests: write
# Prevent redundant builds on rapid pushes
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test & Lint Matrix
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
node-version: ['20', '22']
timeout-minutes: 15
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Run Test Suite
run: npm test
deploy:
name: Deploy to Production
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 20
environment:
name: production
url: https://wtool.dev
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Deploy Application
env:
DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_KEY }}
run: |
echo "Deploying release to production environment..."
./scripts/deploy.sh
Engineering teams modularize and share automation using two primary patterns:
| Dimension | Composite Actions (action.yml) |
Reusable Workflows (on: workflow_call) |
|---|---|---|
| Scope | Packaged sequence of steps running inside a single job | Complete workflow containing one or more jobs |
| Declaration | runs.using: 'composite' in action.yml |
on: workflow_call in .github/workflows/*.yml |
| Runner Environment | Inherits host runner from calling job | Declares its own runs-on per internal job |
| Secrets Access | Passed via step with: or env: inputs |
Passed via workflow secrets: or secrets: inherit |
| Primary Use Case | Reusable multi-step toolchain setups (e.g. install, cache, configure) | Standardized organizational compliance, test matrices, and multi-environment deployment pipelines |
@v4) can be moved upstream. Pin to complete 40-character Git commit SHAs (e.g., uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11) to prevent supply chain tampering.run: echo "${{ github.event.issue.title }}" is vulnerable to shell script injection. Always pass context data into intermediate environment variables (env: TITLE: ${{ github.event.issue.title }}).permissions: contents: read to restrict the automatically generated GITHUB_TOKEN, avoiding default write access.permissions: id-token: write) to assume short-lived IAM roles in AWS, GCP, or Azure without saving permanent API keys.You can validate workflows locally in your browser using our free GitHub Actions YAML Validator. It checks official JSON schemas, highlights syntax errors, checks for cyclic job dependencies, and verifies security best practices.
GitHub deprecated ::set-output due to command injection vulnerabilities. Modern workflows write outputs using the runner environment file: echo "key=value" >> $GITHUB_OUTPUT.
Inside if: conditionals, GitHub Actions evaluates statements as expressions automatically (e.g., if: github.event_name == 'push'). Wrapping expressions in ${{ ... }} inside if: is redundant and can cause parsing anomalies with complex boolean logic.
Free, browser-based utilities to test, generate, and inspect GitHub Actions (CI/CD & Workflow Automation) payloads directly.
Validate, format and summarize GitHub Actions workflow YAML files against official schemas.
Convert between JSON and YAML with validation, formatting, and multi-document support.
Parse, validate, explain, and build cron expressions with next run times and visual timeline.
Lint, validate, format, and optimize Dockerfiles with Hadolint-compatible rules, security checks, and multi-stage analysis.
Visually resolve Git merge conflicts by picking current, incoming, or both versions.
Parse, validate, and convert .env files between JSON, YAML, Docker, and Kubernetes formats.