Local CI Testing - antimetal/system-agent GitHub Wiki
Local CI Testing
📚 This guide explains how to test GitHub Actions workflows locally using Act.
This guide explains how to test GitHub Actions workflows locally without pushing to GitHub using act
by nektos.
Installation
macOS (recommended)
brew install act
Linux
curl -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
Windows
scoop install act
# or
winget install nektos.act
Prerequisites
- Docker must be installed and running
- You must be in a Git repository with
.github/workflows/
directory
Basic Usage
List available workflows and jobs
# List all actions for all events
act -l
# Example output for this project:
# Stage Job ID Job name Workflow name Workflow file Events
# 0 claude-review claude-review Claude Code Review claude-code-review.yml pull_request
# 0 claude claude Claude Code claude.yml issue_comment,pull_request_review_comment,issues,pull_request_review
# 0 create-linear-issue create-linear-issue Linear Sync linear-sync.yml issues
# 0 update-linear-issue update-linear-issue Linear Sync linear-sync.yml issues
Run workflows
# Run the default (push) event
act
# Run a specific event (e.g., pull_request)
act pull_request
# Run a specific job
act -j claude-review
# Dry run (show what would be executed without running)
act -n
# Verbose output for debugging
act -v
Testing Specific Workflows in This Project
1. Testing Claude Code Review Workflow
# Simulate a pull request event
act pull_request -j claude-review
# With secrets (create .secrets file first)
act pull_request -j claude-review --secret-file .secrets
2. Testing Claude Code Workflow
# Simulate an issue comment event
act issue_comment -j claude
# Simulate a pull request review comment
act pull_request_review_comment -j claude
3. Testing Linear Sync Workflow
# Simulate issue opened event
act issues -j create-linear-issue --eventpath test-events/issue-opened.json
# Simulate issue closed event
act issues -j update-linear-issue --eventpath test-events/issue-closed.json
Configuration
.actrc
file for default settings
1. Create # .actrc
-P ubuntu-latest=catthehacker/ubuntu:act-latest
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
-P ubuntu-20.04=catthehacker/ubuntu:act-20.04
--container-architecture linux/amd64
.secrets
file for API keys
2. Create # .secrets (add to .gitignore!)
ANTHROPIC_API_KEY=your-api-key-here
LINEAR_API_TOKEN=your-linear-token-here
3. Create test event payloads
mkdir -p test-events
# Example: test-events/issue-opened.json
cat > test-events/issue-opened.json << 'EOF'
{
"action": "opened",
"issue": {
"number": 1,
"title": "Test Issue",
"body": "This is a test issue body",
"html_url": "https://github.com/antimetal/system-agent/issues/1"
}
}
EOF
Tips for Testing
1. Use Medium-sized Docker Images
When first running act
, choose the medium-sized image (~500MB) for faster downloads and sufficient functionality.
2. Test Individual Jobs
Instead of running entire workflows, test specific jobs:
act -j job-name
3. Use Environment Variables
# Pass environment variables
act -e MY_VAR=value
# Use .env file
act --env-file .env.test
4. Debug with Verbose Output
act -v pull_request
5. Skip Specific Steps
Use conditional expressions in your workflow:
- name: Deploy
if: ${{ !env.ACT }} # Skip when running locally with act
run: ./deploy.sh
Limitations
- Services: Docker services defined in workflows are not fully supported
- Workflow dispatch inputs: Limited support for workflow_dispatch events
- GitHub-specific features: Some GitHub-specific APIs and contexts may not work
- Performance: Local runs may be slower than GitHub's hosted runners
Example Commands for This Project
# Test Claude code review on a simulated PR
act pull_request -j claude-review --secret-file .secrets
# Test Linear sync when an issue is opened
act issues -j create-linear-issue --secret LINEAR_API_TOKEN=$LINEAR_TOKEN --var LINEAR_TEAM_ID=team-123
# Dry run to see what would execute
act -n -l
# Run with custom Docker image
act -P ubuntu-latest=myimage:latest
Adding to Makefile
Consider adding these commands to your Makefile:
.PHONY: test-actions
test-actions: ## Test GitHub Actions locally with act
@command -v act >/dev/null 2>&1 || { echo "act is not installed. Run: brew install act"; exit 1; }
act -l
.PHONY: test-claude-review
test-claude-review: ## Test Claude code review workflow
act pull_request -j claude-review --secret-file .secrets
.PHONY: test-linear-sync
test-linear-sync: ## Test Linear sync workflow
act issues -j create-linear-issue --secret-file .secrets
Best Practices
- Keep secrets local: Never commit
.secrets
or.env
files - Test before pushing: Run
act
before pushing workflow changes - Use event payloads: Create realistic test event JSON files
- Document requirements: Note which secrets/vars each workflow needs
- Version control test files: Keep test event payloads in
test-events/