How to run GitHub Actions workflows locally?
Solution 1
There are tools like the already-mentioned act
, but they are not perfect.
You are not alone with this issue. Similar problems are:
- how to test Jenkins builds locally
- how to test Circle CI builds locally
- how to test XXXX builds locally
And my solution for these problems is:
- avoid functionalities provided by your CI tools (GitHub Actions, Gitlab CI, etc)
- write as much as possible in CI-agnostic way (BASH scripts, PowerShell scripts, Gradle scripts, NPM scripts, Dockerfiles, Ansible scripts - anything you know)
- invoke those scripts from your CI tool. In GitHub actions:
run: your command to run
Update 2022; Bit-bucket's Pipelines support running locally, which means 100% free use-hours, with the cost of buying own PC/Mac (if you want permanent server).
Solution 2
You can use nektos/act which supports yaml syntax since 0.2.0 (prerelease).
Check out their latest release.
Solution 3
One way to test Github actions is to create a private repo, and iterate the actions conf there. So you can avoid polluting the actual repo with broken commits.
I know, this is not a direct answer to the question - this is not a local way. But this didn’t occur to me at first and I think this could be enough for many use cases.
Solution 4
your best bet is https://github.com/nektos/act however (prior to 0.2.0) it doesn't support yaml syntax yet, though there is a lot of interest aka: https://github.com/nektos/act/issues/80 https://github.com/nektos/act/issues/76 and https://github.com/nektos/act/issues/74
Gitlab has gitlab-runner exec docker job-name
but that's Gitlab :)
Solution 5
I'm assuming that you want to run the action locally because it is failing, and you want to debug it. If so, another alternative (which doesn't require running locally) is to use action-tmate to SSH into the machine running your action. From there, you can view logs, run commands, etc to work out what the problem is.
To get started:
- In your workflow yaml file, after the step that is failing, put a new step as follows:
- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/[email protected]
-
Push the changes to GitHub and rerun the action.
-
Wait for it to fail again - this time, instead of stopping the workflow, a tmate session will be opened, and the SSH details will be printed in the workflow console.
-
Connect via SSH from your own machine, and now you have full access to the runner machine.
Related videos on Youtube

William Entriken
Lead author of ERC-721. Personal website and contact information: https://phor.net Promoting two open source projects: https://github.com/fulldecent/web-puc - A script to validate you are using the latest JQuery, Bootstrap, Font Awesome versions in your favorite PHP or other web front-end (compatible with Travis CI) https://fulldecent.github.io/cameralife/ - Mature LAMP project for displaying large photo collections on the web (i.e. your life work)
Updated on May 09, 2022Comments
-
William Entriken 5 months
I am planning to move our Travis CI build to GitHub Actions using Docker for our per-commit testing.
Can I reproducibly run these new GitHub Actions workflows locally? Is there a generic way to run any GitHub Actions workflow locally?
-
smac89 almost 3 yearsThere is if you are still using the deprecated HCL syntax for actions and haven't graduated to the new YAML style. I have yet to see anything being done to support the new yaml style workflows
-
Jubair over 2 yearsthere is a lot of interest for
nejtos/act
to support YAML syntax, see my answer below with links to the issues it's being discussed. -
UselesssCat over 1 yearmaybe self-hosted runners can help github.com/actions/runner
-
-
Jubair over 2 yearsActually gitlab has a cli tool to test your workflows:
gitlab-runner exec docker my-job
-
Danny over 2 yearsSeems this doesn't support windows builds. Curious, how are others usually testing their changes to Github Actions for Windows apps (without checking in and triggering them)?
-
dmedine about 2 yearsGreat answer! but unfortunately this doesn't help much when you are testing things like uploading and downloading artifacts to github releases.
-
iirekm about 2 yearsMaybe github api or github cli can do that? Unfortunately my method works only for some 95% of actions. Things like collecting test results and coverage from xmls generated by tools, and maybe your problem, can only be done natively by GHA / Jenkins, etc
-
Mike Pennington about 2 yearsCircle CI also allows you to run locally: circleci.com/docs/2.0/local-cli
-
Firecow almost 2 yearsgithub.com/firecow/gitlab-ci-local I've made this project.
-
Frank Rem almost 2 yearsact supports yaml syntax since 0.2.0 (see Webber's answer)
-
Webber over 1 yearSeems it's fixed as per github.com/nektos/act/pull/675
-
reesaspieces over 1 yearAct doesn't support macos builds either :(
-
Iter Ator about 1 yearIt does not support artifacts
-
m4heshd about 1 yearThis is a handful when working with massive, multi-repo projects. Wish there was a better alternative but unfortunately this is the only guaranteed mirror functionality for testing.
-
luismartingil about 1 year"CI-agnostic way" brings on caching challenges when using each specific CI caching capabilities
-
iirekm about 1 yearThis is github actions only (people also use Jenkins, gitlab ci, Amazon code pipeline, Travis, etc). Using your build tool (gradle, npm, bash) to script most of your build works the best
-
Webber about 1 year@iirekm The question is about GitHub Actions specifically.
-
iirekm about 1 yearWhy? There are at least 3 approaches to caching in CI: 1. For example with Gradle you can just tell CI to cache ~/.gradle and ./**/build/** directories, with nodejs it'll be ./**/node_modules/**. Probably all CI tools support caching of file masks (by zipping them and uploading) - unfortunately it's slow 2. Create your own persistent gitlab/gitbub actions runner per project. All files will be in local directory. Caching is fast and easy. 3. Gradle can use Gradle Enterprise Server to download - upload contents of build dirs
-
Jordan Mitchell Barrett 12 monthsAnother possibility is creating a new branch in your repo, pushing changes to that branch until you get the action working, and then squash into a single commit and merge into main.
-
Mike Nakis 5 monthsThat's exactly what I have been doing for years now. The benefit of being in control and not relying on proprietary CI tooling far outweighs the benefit of being able to see little circles marked with checkmarks for each stage completed. CI tool vendors should provide hooks for our scripts to use to indicate stages completed. CI tool vendors should handle caching transparently to us; it is their problem, not ours.