Run Your GitHub Actions Locally with Act: Faster Feedback, Better Debugging

Learn how to run Github Actions locally in your machine using act

Run Your GitHub Actions Locally with Act: Faster Feedback, Better Debugging

If you're using GitHub Actions for your CI/CD pipelines or other automation tasks, you know how powerful they are. But you've probably also felt the frustration of the git commit -> git push -> wait -> check logs -> repeat cycle when debugging or tweaking your workflows. It can be slow and consume valuable GitHub Actions minutes.

What if you could test your workflows before pushing them? Enter act.

What is act?

act (from nektos) is an open-source command-line tool that lets you run your GitHub Actions workflows locally. It reads your workflow files (usually found in .github/workflows/) and uses Docker to simulate the GitHub Actions environment on your own machine.

Why Use act?

Running your Actions locally offers several key advantages:

  1. ⚑ Fast Feedback: Get immediate results from your workflow changes without waiting for GitHub's runners to pick up the job. This drastically speeds up development and debugging.
  2. πŸ’° Cost Savings: Avoid using up your free GitHub Actions minutes (or paying for extra minutes) just for testing minor tweaks.
  3. ✈️ Offline Work: Test basic workflow logic even when you don't have an internet connection (after initial image downloads).
  4. πŸ› Easier Debugging: Iterate quickly on fixes and experiment with workflow steps in a local environment.
  5. ♻️ Local Task Runner: You can even potentially replace tools like make for local tasks by leveraging the workflows you've already defined.

Getting Started: Installation

act requires Docker to be installed and running on your system, as it uses containers to execute the workflow jobs. Make sure you have Docker installed for your operating system (macOS, Windows, or Linux).

You can install act using various package managers:

  • Manual Download: Pre-built binaries are available on the act releases page on GitHub.

Linux (using install script):

curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

Windows (using Chocolatey):

choco install act-cli
# Or using Winget:
winget install --id=nektos.act -e
# Or using Scoop:
scoop install act

macOS/Linux (using Homebrew):

brew install act

Running act for the first time

You can run the following command to run act:

act

The first time you run act, it will likely ask you to choose a default Docker image size (Micro, Medium, Large) to use for the standard Ubuntu runner. The Medium size is often a good starting point. Your choice is saved in ~/.actrc.

Running Your Workflows Locally with act

Navigate to the root directory of your repository containing the .github/workflows/ folder in your terminal.

  1. Handling Secrets: GitHub Actions secrets aren't automatically available locally. You need to provide them:
  2. Using Different Runner Images: act uses default Docker images (often based on catthehacker/ubuntu or node). If you need a specific environment or the larger GitHub-provided images (which are very big!), you can specify them using the -P flag or configure them in your ~/.actrc file.
# Example: Use a specific image for ubuntu-latest runners for this run
act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04

# Example: Save this mapping permanently in ~/.actrc
# Add this line to ~/.actrc:
# -P ubuntu-latest=nektos/act-environments-ubuntu:18.04
  1. Handling GITHUB_TOKEN: Often, you need to provide a GITHUB_TOKEN. You can generate a Personal Access Token (PAT) on GitHub and pass it:
act -s GITHUB_TOKEN=<your_github_pat>

From a file: (Uses .env format, e.g., KEY=VALUE lines)

act --secret-file ./my.secrets

From an environment variable: (Prompts if not set)

act -s MY_SECRET

Via command line:

act -s MY_SECRET=my_value -s ANOTHER_SECRET=another_value

Dry Run: List the steps that would run without actually executing them:

act -n

Run a Specific Job: If your workflow has multiple jobs, you can run just one:

act -j <job_id>
# Example: Run the job with the id 'build'
act -j build

Run a Specific Event: Trigger workflows associated with different events (e.g., pull_request, workflow_dispatch):

act pull_request
act workflow_dispatch

List Available Jobs: See which jobs would run for the default (push) event:

act -l
# Or list jobs for a specific event:
act pull_request -l

Run Default Event: The simplest command runs the default push event:

act

A Simple Example

Let's say you have a basic workflow in .github/workflows/greeting.yml:

name: Greeting CI
on: [push]
jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
    - name: Send greeting
      run: echo "Hello from the local workflow!"

Simply navigate to your repo's root directory and run:

act

You should see output indicating the job is running in Docker and eventually print "Hello from the local workflow!".

[Greeting CI/greet] ⭐ Run Set up job
[Greeting CI/greet] πŸš€  Start image=catthehacker/ubuntu:act-latest
[Greeting CI/greet]   🐳  docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
[Greeting CI/greet]   🐳  docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Greeting CI/greet]   🐳  docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Greeting CI/greet]   🐳  docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[Greeting CI/greet]   βœ…  Success - Set up job
[Greeting CI/greet] ⭐ Run Main Send greeting
[Greeting CI/greet]   🐳  docker exec cmd=[bash -e /var/run/act/workflow/0] user= workdir=
| Hello from the local workflow!  πŸ‘ˆπŸ½πŸ‘ˆπŸ½πŸ‘ˆπŸ½πŸ‘ˆπŸ½
[Greeting CI/greet]   βœ…  Success - Main Send greeting [32.379625ms]
[Greeting CI/greet] ⭐ Run Complete job
[Greeting CI/greet] Cleaning up container for job greet
[Greeting CI/greet]   βœ…  Success - Complete job
[Greeting CI/greet] 🏁  Job succeeded

Important Considerations & Limitations

  • Environment Differences: While act tries to mimic the GitHub Actions environment, it's running in Docker on your machine. There might be subtle differences (OS, installed software, network access, hardware) compared to the actual GitHub runners.
  • Runner Images: act primarily supports Linux-based runners using Docker. While workarounds exist, native Windows and macOS runner support is limited or requires running jobs directly on the host without container isolation. The default images provided are minimal and might lack tools present on GitHub's hosted runners; consider using larger or custom images if needed.
  • Secrets: Secrets must be manually supplied. Never commit actual secrets to your repository, even in secret files used by act. Use a .gitignore entry for your secrets file (e.g., my.secrets, .env).
  • GitHub Context: Some context variables available in GitHub Actions (like specific event payloads) might not be fully populated or accurate locally unless you provide a custom event payload JSON file (act <event> -e event.json).
  • Network & Service Dependencies: Workflows relying on external services or specific network configurations might behave differently locally.
  • GITHUB_TOKEN Permissions: The permissions of the GITHUB_TOKEN you provide locally might differ from the token automatically generated by GitHub Actions.

Conclusion

act is an invaluable tool for any developer working with GitHub Actions. By enabling local testing and debugging, it significantly speeds up the development feedback loop, saves resources, and ultimately leads to more robust and reliable workflows. While it has limitations, understanding them allows you to leverage act effectively for the majority of workflow testing scenarios.

Give act a try in your next project – you might find it dramatically improves your GitHub Actions development experience!


Further Information:

By the way, have you checked out how to "Vibe Code" with Google Gemini 1.5?

No? Well, watch this πŸ‘‡πŸΌ