GitHub Actions Tutorial — Act (Local Testing)
Act — Local Testing
act runs your GitHub Actions workflows locally using Docker. Instead of pushing to GitHub, waiting for runners, and reading logs remotely — you test on your machine in seconds.
Installation
# macOS
brew install act
# Linux (prebuilt binary)
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Windows (scoop)
scoop install act
Requirement: Docker must be running.
Basic Usage
# Run the default event (push) for all workflows
act
# Run a specific event
act pull_request
# Run a specific workflow
act -W .github/workflows/ci.yml
# Run a specific job
act -j test
# List all jobs (dry run)
act -l
Image Sizes
First run, act asks you to choose a runner image:
| Image | Size | Contents |
|---|---|---|
| Micro | ~200 MB | Minimal (Node.js only) |
| Medium | ~500 MB | Common tools (git, curl, jq) |
| Large | ~18 GB | Full ubuntu-latest equivalent |
# Use medium image (good balance)
act -P ubuntu-latest=catthehacker/ubuntu:act-latest
# Use large image for full compatibility
act -P ubuntu-latest=catthehacker/ubuntu:full-latest
Passing Secrets
# From command line
act -s MY_SECRET=value123
# From a .secrets file
act --secret-file .secrets
.secrets file:
GITHUB_TOKEN=ghp_xxxxx
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
Important: Add .secrets to .gitignore.
Passing Variables and Inputs
# Environment variables
act --env MY_VAR=value
# From an .env file
act --env-file .env
# Workflow dispatch inputs
act workflow_dispatch --input name=value
Limitations
| Feature | Status in act |
|---|---|
actions/checkout |
✅ Works |
actions/cache |
⚠️ Partial (uses local cache) |
docker/build-push-action |
⚠️ Needs Docker-in-Docker |
services: |
⚠️ Partial support |
matrix: |
✅ Works |
| OIDC tokens | ❌ Not supported |
GITHUB_TOKEN permissions |
❌ Must pass manually |
| Windows/macOS runners | ❌ Linux only |
Practical Workflow
# 1. Edit workflow locally
vim .github/workflows/ci.yml
# 2. Test with act
act -j test --verbose
# 3. Fix issues
# 4. Push when passing
git push
This loop is much faster than the push → wait → check → fix cycle.
Common Mistakes
| Mistake | Fix |
|---|---|
| Docker not running | Start Docker Desktop or sudo systemctl start docker |
Action needs GITHUB_TOKEN |
Pass with -s GITHUB_TOKEN=ghp_xxx |
| Image too small | Use medium or large image |
act is slow |
Use smaller image or --reuse to keep containers |
Quick Reference
| Command | Purpose |
|---|---|
act |
Run push event |
act pull_request |
Run PR event |
act -j <job> |
Run specific job |
act -l |
List all jobs |
act -s KEY=VAL |
Pass secret |
act --env-file .env |
Pass env file |
act -n |
Dry run (no execution) |
act --verbose |
Verbose output |
← Previous: Common Errors
Next: Reading Logs →