ci-cd
📋 Copy All GitHub Actions Commands
📄 Generate GitHub Actions PDF Guide
GitHub Actions Cheatsheet
Installation & Setup
GitHub CLI (gh)
Platform
Command
Ubuntu/Debian
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \| sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \| sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh
Fedora/RHEL
sudo dnf install gh
Arch Linux
sudo pacman -S github-cli
macOS (Homebrew)
brew install gh
Windows (Chocolatey)
choco install gh
Windows (WinGet)
winget install --id GitHub.cli
Self-Hosted Runner Setup
Platform
Setup Commands
Linux
mkdir actions-runner && cd actions-runner && curl -o actions-runner-linux-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz && tar xzf ./actions-runner-linux-x64-2.311.0.tar.gz
macOS
mkdir actions-runner && cd actions-runner && curl -o actions-runner-osx-x64-2.311.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-osx-x64-2.311.0.tar.gz && tar xzf ./actions-runner-osx-x64-2.311.0.tar.gz
Windows
mkdir actions-runner; cd actions-runner; Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-win-x64-2.311.0.zip -OutFile actions-runner-win-x64-2.311.0.zip
Platform
Command
Linux/macOS (curl)
curl https://raw.githubusercontent.com/nektos/act/master/install.sh \| sudo bash
Homebrew
brew install act
Go
go install github.com/nektos/act@latest
Windows (Chocolatey)
choco install act-cli
Windows (Scoop)
scoop install act
Basic GitHub CLI Commands
Command
Description
gh run list
List all workflow runs in the repository
gh run view <run-id>
View details of a specific workflow run
gh run watch <run-id>
Watch a workflow run in real-time
gh run view <run-id> --log
View logs for a specific workflow run
gh run download <run-id>
Download artifacts from a workflow run
gh workflow list
List all workflows in the repository
gh workflow view <workflow-name>
View details of a specific workflow
gh workflow enable <workflow-name>
Enable a disabled workflow
gh workflow disable <workflow-name>
Disable a workflow
gh workflow run <workflow-name>
Manually trigger a workflow
gh workflow run <workflow-name> -f key=value
Trigger workflow with input parameters
gh run cancel <run-id>
Cancel a running workflow
gh run rerun <run-id>
Rerun a completed workflow
gh run rerun <run-id> --failed
Rerun only failed jobs in a workflow
gh auth login
Authenticate GitHub CLI with your account
Self-Hosted Runner Management
Command
Description
./config.sh --url https://github.com/ORG/REPO --token TOKEN
Configure a new self-hosted runner
sudo ./svc.sh install
Install runner as a system service (Linux/macOS)
sudo ./svc.sh start
Start the runner service
sudo ./svc.sh stop
Stop the runner service
sudo ./svc.sh status
Check runner service status
sudo ./svc.sh uninstall
Uninstall runner service
./config.sh remove --token TOKEN
Remove runner from repository
./run.sh
Run the runner interactively (not as service)
gh api repos/:owner/:repo/actions/runners
List all self-hosted runners via API
gh api -X DELETE repos/:owner/:repo/actions/runners/RUNNER_ID
Remove runner via API
Local Testing with Act
Command
Description
act -l
List all workflows and jobs available locally
act
Run the default event (push) locally
act push
Run workflows triggered by push event
act pull_request
Run workflows triggered by pull request event
act -j job-name
Run a specific job by name
act -s GITHUB_TOKEN=token
Run with a secret value
act -s SECRET_NAME
Prompt for secret value interactively
act --secret-file .secrets
Load secrets from a file
act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04
Use specific Docker image for runner
act -n
Dry run - show what would be executed
act -v
Verbose output for debugging
act --container-architecture linux/amd64
Specify container architecture
act -W .github/workflows/ci.yml
Run specific workflow file
act --env-file .env
Load environment variables from file
Advanced GitHub CLI Commands
Command
Description
gh run list --workflow=ci.yml
List runs for a specific workflow
gh run list --branch=main --limit=20
List runs for specific branch with limit
gh run view --log-failed
View only failed job logs
gh run view --job=12345
View specific job within a run
gh workflow run deploy.yml -f environment=production -f version=1.2.3
Trigger workflow with multiple inputs
gh api repos/:owner/:repo/actions/runs/:run_id/logs
Download run logs via API
gh api repos/:owner/:repo/actions/workflows
List workflows via API
gh api repos/:owner/:repo/actions/secrets
List repository secrets
gh secret set SECRET_NAME < secret.txt
Set a repository secret from file
gh secret set SECRET_NAME --body "value"
Set a repository secret from string
gh secret list
List all repository secrets
gh secret remove SECRET_NAME
Remove a repository secret
gh api repos/:owner/:repo/actions/caches
List workflow caches
gh api -X DELETE repos/:owner/:repo/actions/caches/:cache_id
Delete a specific cache
gh run download <run-id> -n artifact-name
Download specific artifact by name
Workflow File Structure
Basic Workflow Template
name : CI Pipeline
# Trigger configuration
on :
push :
branches : [ main , develop ]
paths :
- 'src/**'
- '**.js'
pull_request :
branches : [ main ]
workflow_dispatch : # Manual trigger
inputs :
environment :
description : 'Environment to deploy'
required : true
default : 'staging'
# Environment variables
env :
NODE_VERSION : '18'
CACHE_KEY : v1
# Jobs definition
jobs :
build :
runs-on : ubuntu-latest
timeout-minutes : 30
steps :
- name : Checkout code
uses : actions/checkout@v4
with :
fetch-depth : 0
- name : Setup Node.js
uses : actions/setup-node@v4
with :
node-version : ${{ env.NODE_VERSION }}
cache : 'npm'
- name : Install dependencies
run : npm ci
- name : Run tests
run : npm test
env :
CI : true
- name : Build application
run : npm run build
Matrix Strategy
jobs :
test :
runs-on : ${{ matrix.os }}
strategy :
matrix :
os : [ ubuntu-latest , windows-latest , macos-latest ]
node-version : [ 16 , 18 , 20 ]
include :
- os : ubuntu-latest
node-version : 20
experimental : true
exclude :
- os : macos-latest
node-version : 16
fail-fast : false
max-parallel : 3
steps :
- uses : actions/checkout@v4
- uses : actions/setup-node@v4
with :
node-version : ${{ matrix.node-version }}
- run : npm test
Conditional Execution
jobs :
deploy :
runs-on : ubuntu-latest
if : github.ref == 'refs/heads/main' && github.event_name == 'push'
steps :
- name : Deploy to staging
if : contains(github.event.head_commit.message, '[staging]')
run : ./deploy.sh staging
- name : Deploy to production
if : startsWith(github.ref, 'refs/tags/v')
run : ./deploy.sh production
- name : Conditional step with multiple conditions
if : |
success() &&
github.actor == 'dependabot[bot]' &&
contains(github.event.pull_request.labels.*.name, 'automerge')
run : echo "Auto-merging PR"
Caching Configuration
steps :
# Cache npm dependencies
- name : Cache node modules
uses : actions/cache@v3
with :
path : ~/.npm
key : ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys : |
${{ runner.os }}-node-
# Cache pip dependencies
- name : Cache pip
uses : actions/cache@v3
with :
path : ~/.cache/pip
key : ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys : |
${{ runner.os }}-pip-
# Cache Gradle dependencies
- name : Cache Gradle
uses : actions/cache@v3
with :
path : |
~/.gradle/caches
~/.gradle/wrapper
key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
# Cache Docker layers
- name : Cache Docker layers
uses : actions/cache@v3
with :
path : /tmp/.buildx-cache
key : ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys : |
${{ runner.os }}-buildx-
Artifacts Management
jobs :
build :
runs-on : ubuntu-latest
steps :
- name : Build application
run : npm run build
# Upload artifacts
- name : Upload build artifacts
uses : actions/upload-artifact@v3
with :
name : build-output
path : |
dist/
build/
!dist/**/*.map
retention-days : 30
if-no-files-found : error
# Upload test results
- name : Upload test results
if : always()
uses : actions/upload-artifact@v3
with :
name : test-results-${{ matrix.os }}
path : test-results/
deploy :
needs : build
runs-on : ubuntu-latest
steps :
# Download artifacts
- name : Download build artifacts
uses : actions/download-artifact@v3
with :
name : build-output
path : ./artifacts
- name : Deploy artifacts
run : ./deploy.sh ./artifacts
Environment and Secrets
jobs :
deploy :
runs-on : ubuntu-latest
environment :
name : production
url : https://example.com
env :
NODE_ENV : production
API_URL : https://api.example.com
steps :
- name : Deploy with secrets
run : |
echo "Deploying to $NODE_ENV"
./deploy.sh
env :
DEPLOY_KEY : ${{ secrets.DEPLOY_KEY }}
AWS_ACCESS_KEY_ID : ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name : Use GitHub token
run : |
gh api user
env :
GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
Composite Actions
File: .github/actions/setup-project/action.yml
name : 'Setup Project'
description : 'Setup Node.js and install dependencies'
inputs :
node-version :
description : 'Node.js version'
required : false
default : '18'
cache-key :
description : 'Cache key prefix'
required : false
default : 'v1'
outputs :
cache-hit :
description : 'Whether cache was hit'
value : ${{ steps.cache.outputs.cache-hit }}
runs :
using : 'composite'
steps :
- name : Setup Node.js
uses : actions/setup-node@v4
with :
node-version : ${{ inputs.node-version }}
- name : Cache dependencies
id : cache
uses : actions/cache@v3
with :
path : node_modules
key : ${{ inputs.cache-key }}-${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- name : Install dependencies
if : steps.cache.outputs.cache-hit != 'true'
run : npm ci
shell : bash
Using composite action:
jobs :
build :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- name : Setup project
uses : ./.github/actions/setup-project
with :
node-version : '20'
cache-key : 'v2'
- name : Build
run : npm run build
Reusable Workflows
File: .github/workflows/reusable-deploy.yml
name : Reusable Deploy Workflow
on :
workflow_call :
inputs :
environment :
required : true
type : string
version :
required : false
type : string
default : 'latest'
secrets :
deploy-key :
required : true
outputs :
deployment-url :
description : "Deployment 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
- name : Deploy
id : deploy
run : |
./deploy.sh ${{ inputs.environment }} ${{ inputs.version }}
echo "url=https://${{ inputs.environment }}.example.com" >> $GITHUB_OUTPUT
env :
DEPLOY_KEY : ${{ secrets.deploy-key }}
Calling reusable workflow:
jobs :
deploy-staging :
uses : ./.github/workflows/reusable-deploy.yml
with :
environment : staging
version : '1.2.3'
secrets :
deploy-key : ${{ secrets.STAGING_DEPLOY_KEY }}
deploy-production :
needs : deploy-staging
uses : ./.github/workflows/reusable-deploy.yml
with :
environment : production
version : '1.2.3'
secrets :
deploy-key : ${{ secrets.PROD_DEPLOY_KEY }}
Common Workflow Triggers
Trigger
Description
Example
push
On push to branches
on: push: branches: [main]
pull_request
On PR events
on: pull_request: types: [opened, synchronize]
workflow_dispatch
Manual trigger
on: workflow_dispatch: inputs: ...
schedule
Cron schedule
on: schedule: - cron: '0 0 * * *'
release
On release events
on: release: types: [published]
issues
On issue events
on: issues: types: [opened, labeled]
issue_comment
On issue comments
on: issue_comment: types: [created]
repository_dispatch
External webhook
on: repository_dispatch: types: [deploy]
workflow_run
After another workflow
on: workflow_run: workflows: [CI]
pull_request_target
PR from forks (careful!)
on: pull_request_target
Context Variables
Context
Description
Example Usage
github.actor
User who triggered workflow
${{ github.actor }}
github.event_name
Event that triggered workflow
${{ github.event_name }}
github.ref
Branch or tag ref
${{ github.ref }}
github.sha
Commit SHA
${{ github.sha }}
github.repository
Owner/repo name
${{ github.repository }}
github.workspace
Workspace directory path
${{ github.workspace }}
runner.os
Operating system
${{ runner.os }}
runner.temp
Temp directory path
${{ runner.temp }}
secrets.GITHUB_TOKEN
Auto-generated token
${{ secrets.GITHUB_TOKEN }}
env.VAR_NAME
Environment variable
${{ env.NODE_VERSION }}
matrix.value
Matrix value
${{ matrix.node-version }}
needs.job.outputs.var
Output from previous job
${{ needs.build.outputs.version }}
steps.step_id.outputs.var
Output from step
${{ steps.build.outputs.artifact }}
job.status
Job status
${{ job.status }}
Common Use Cases
Use Case 1: Node.js CI/CD Pipeline
name : Node.js CI/CD
on :
push :
branches : [ main ]
pull_request :
branches : [ main ]
jobs :
test :
runs-on : ubuntu-latest
strategy :
matrix :
node-version : [ 16 , 18 , 20 ]
steps :
- 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 linter
run : npm run lint
- name : Run tests
run : npm test -- --coverage
- name : Upload coverage
uses : codecov/codecov-action@v3
with :
files : ./coverage/lcov.info
build :
needs : test
runs-on : ubuntu-latest
if : github.event_name == 'push'
steps :
- uses : actions/checkout@v4
- uses : actions/setup-node@v4
with :
node-version : '18'
cache : 'npm'
- run : npm ci
- run : npm run build
- name : Upload build artifacts
uses : actions/upload-artifact@v3
with :
name : dist
path : dist/
deploy :
needs : build
runs-on : ubuntu-latest
if : github.ref == 'refs/heads/main'
environment :
name : production
url : https://example.com
steps :
- name : Download artifacts
uses : actions/download-artifact@v3
with :
name : dist
path : dist/
- name : Deploy to production
run : |
# Deploy commands here
echo "Deploying to production..."
Use Case 2: Docker Build and Push
name : Docker Build and Push
on :
push :
branches : [ main ]
tags : [ 'v*' ]
env :
REGISTRY : ghcr.io
IMAGE_NAME : ${{ github.repository }}
jobs :
build-and-push :
runs-on : ubuntu-latest
permissions :
contents : read
packages : write
steps :
- name : Checkout code
uses : actions/checkout@v4
- name : Set up Docker Buildx
uses : docker/setup-buildx-action@v3
- name : Log in to Container Registry
uses : docker/login-action@v3
with :
registry : ${{ env.REGISTRY }}
username : ${{ github.actor }}
password : ${{ secrets.GITHUB_TOKEN }}
- name : Extract metadata
id : meta
uses : docker/metadata-action@v5
with :
images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags : |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name : Build and push
uses : docker/build-push-action@v5
with :
context : .
push : true
tags : ${{ steps.meta.outputs.tags }}
labels : ${{ steps.meta.outputs.labels }}
cache-from : type=gha
cache-to : type=gha,mode=max
Use Case 3: Multi-Cloud Deployment
```yaml
name: Multi-Cloud Deploy
on:
workflow_dispatch:
inputs:
environment:
type: choice
description: 'Deployment environment'
options:
- staging
- production
required: true
jobs:
deploy-aws:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment }}
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-