Testing Github Actions with act

Github actions are great, but whilst you’re building an action it can be quite painful to keep pushing changes to Github to trigger action runs. This is where act can help! act is a command line tool written in go that parses Github workflow files, pulls the required docker images and sets GITHUB_ environment variables similar to how they’d be set when running as an action.

Installation

If you’re on MacOS and use Homebrew you can install act by running the following:

brew tap nektos/tap && brew install nektos/tap/act

Otherwise, you can down download the correct binary for your system from Github and add it to your $PATH.

Usage

When you run act it performs a set of instructions that emulate the same process that Github follows when running your action:

1. Reads your workflow file

To know which actions to run, act will read .github/main.workflow from the repo in the current working directory. You can change the workflow used by setting the -f flag e.g. act -f .github/new-testing.workflow

2. Resolves which actions should be run

By default act emulates a push event, but you can change the event used by providing an additional parameter when running act e.g. act release to trigger a release event

3.Pulls and builds any required Docker images

Once it knows which actions should be run it pulls and builds the required Docker images. It doesn’t show you the docker output, but runs the following command

docker build -t action_name:<sha1> /path/to/your/action_name

4. Runs the docker images

Once the build has completed act runs the image, passing in mocked values for any GITHUB_ environment variables.
If your main.workflow defines any secrets, act will prompt you to enter them when the workflow is run.

If you were to run it yourself using the docker command, it’d look like the following:

docker run -e GITHUB_WORKSPACE=/github/workspace -e GITHUB_WORKFLOW="Demo" -e GITHUB_EVENT_NAME=push -e GITHUB_SHA=2dcdcf05064e38eea9182b65791c78276ad0378f -e GITHUB_REF=refs/heads/github-action-release -e GITHUB_ACTION="Debug" -e GITHUB_ACTOR=nektos/act -e GITHUB_EVENT_PATH=/github/workflow/event.json -e [email protected]:mheap/github-action-debug -e HOME=/github/home -v `pwd`:/github/workflow action_name:2dcdcf0

Some of the values are fixed (GITHUB_ACTOR, HOME) but the rest are dynamically populated using the workflow you’ve defined and information from the git repo you’re running act in (so make sure to initialise a repo, commit and configure a remote!)

Advanced usage

Once you start building more advanced actions you’ll be relying on more than just the GITHUB_ environment variables. You’ll be inspecting the event payload that’s available in event.json on every action.

act does not provide this file as the contents are specific to the event that triggered your action. Instead, it lets you provide a path to your own event JSON file using the -e option .

I recently built an action that triggers when a release is published. To test it locally, I used the release event JSON from the Github docs as my event.json file.

act release -e event.json

You don’t need to use the entire release event to test. If you know which fields you’re going to be accessing, you can use a stripped down event.json. In my case I only needed a few fields, so the following was sufficient:

{
    "action": "created",
    "release": {
        "name": "1.2.3",
        "body": "This is a test",
        "html_url": "https://example.com"
    },
    "repository": {
        "name": "Testing"
    }
}

You can find more event JSON examples in the Github docs

Conclusion

act is a fantastic tool for testing Github actions locally. It removes the pain of having to constantly push changes to test your local code.

Once you start working with the payload provided in event.json things get a little trickier, but the samples in the Github docs are a great reference for you to use.

Thoughts on this post

Leave a comment?