13 ms·
Act: Run your GitHub Actions locally
- whinvik 4y agoThis is pretty cool but I have never managed to make it work with our AWS ECR repos. There are probably some permissions that I am missing but not very clear in the documentation how to do that.
- domh 4y agoSame. I've only got it to work with the most basic of actions. Anything that requires Docker didn't work for me the last time I tried it! There's a way to download a much larger "base image" which in theory would make it work, but if I remember rightly it was something like 60gb of containers which I was never patient enough to download. It was always quicker to just push up to github and iterate that way unfortunately.
- camkego 4y agoThe lack of a frictionless way to run github actions locally has always seemed a big issue to me. So in many cases, I use a makefile with one of the github actions to run a makefile. It has worked okay in the few cases I've tried it.
- jerpint 4y agoThe downside to this approach is that you have to wait longer for things to pass compared to certain actions. For example, linting can be run in seconds with an action. If you instead clone and install dependencies before linting, you’re waiting much longer to realize you have more whitespace than you should have
- hk1337 4y agoYou could create multiple tasks that aren’t dependent on each other to run? You could still have the main build task but also split it up into multiple tasks.
- pocketarc 4y agoI’ve used this a bunch; I actually don’t know how else you’d write and test a GitHub action. Do people just push them and hope they work and push more commits with “fix” as the message until it works?
- easrng 4y agoyeah i also use other incredibly informative messages like: - oh oops - fix for real this time - will this actually work? - this probably won't fix it - a
- yjftsjthsd-h 4y agoYeah, but with one word messages you can pass it on the command line without quotes: git commit . -m fix
- reilly3000 4y agoTIL. Thanks!
- easrng 4y agoi usually write my actions in the web editor, but i do use -m when committing from git itself pretty much every time
- DeWilde 4y agoI just commit --amend and the push -f to not waste brainpower on messages.
- motoxpro 4y agoYou've described my workflow perfectly. Edit: Downvoters, please help me.
- deleted 4y ago[deleted]
- yjftsjthsd-h 4y ago
- benrutter 4y agoFinally! I've been wanting something like this for ages- generally speaking I don't consider myself an idiot, but I'm forced to pull that into questioning every time I test and debug ci/cd actions with an endless stream of pull request modifications
- choeger 4y agoI don't consider myself a cynic (1), but I am forced to pull that into questioning every time I see how many paid worker minutes are wasted by such endless streams of pull request modifications. (1) Who am I kidding, of course I am a cynic.
- reubenmorais 4y agoUnfortunately act is only capable of running very simple workflows. I've found this action to be more useful against the endless PR stream: https://github.com/mxschmitt/action-tmate https://github.com/mxschmitt/action-tmate You drop it in your workflow and get an SSH shell into the worker, figure things out iteratively, then push when it's working.
- dwightgunning 4y agoCan you elaborate with some examples of workflows that it is incapable of? So far I’ve not found any limitations or issues using Ubuntu runners on my OSX dev machine. A couple examples from my workflows: - building docker images - provisioning VMs with the Digital Ocean cli / http api - hardening VMs with ansible - creating/managing k3s clusters with k3sup - deploying apps with helm I like your suggested approach of using tmate to access the worker mid-way through a run. This should make it faster to develop/debug the steps that make up the workflow. Though this doesn’t address the cycle time of push-to-GitHub/queue-workflow/watch-for-result. I’m actually going to try combining the two techniques - use tmate to develop inside a local act runner.
- Benjamin_Dobell 4y agoWorkflows that interact with the Github API heavily will fail as they're not available in act e.g. actions like https://github.com/styfle/cancel-workflow-action https://github.com/styfle/cancel-workflow-action. Dealing with secrets is also a bit cumbersome. You can throw the following on actions that are not compatible with act in order to skip them: if: ${{ !env.ACT }} That said, despite its limitations, I've been using both act and tmate in combination for a couple of years. Gets the job done.
- antman 4y agoCan this be used to emulate github actions to a git server other than github? e.g. gitea
- veleek 4y agoYup
- Epa095 4y agoI use this a lot. It's not perfect, but better than nothing. For example, last time I checked it did not support reusable workflows, and I have had a few cases I got some error from github but act worked. I guess it's a hard catchup game, not only do you have to get the semantic for correct workflows correctly, you also want to error out on the same errors. I really don't understand why github don't release a local runner for github actions. Everyone I know which has worked with cicd wants the same, some way to run and debug the pipelines/workflows locally.
- Eun 4y agoI also struggle with CI vendor lock-in. Somebody wants to build a serverless- type ci system?
- ithkuil 4y agoI'd love to. Do you have anything more specific in mind?
- Eun 4y agoGenerally speaking: have one syntax/pipeline that works on GitHub, Gitlab, etc I think the big problem would be the marketplace, you need to implement your own or make it compatible with the GitHub one
- Beltalowda 4y agoThis is already entirely doable: just create some executable "test" program in $language_of_choice (shell script, Python, compiled C binary if you really want to) and run that in the CI. You're still going to have to need a wee bit of CI configuration (usually YAML) to tell it which containers to run and whatnot, but this usually isn't all that much.
- ithkuil 4y agoYep. CI systems offer some extra features. If you don't use them there isn't really a lock in. From the top of my head: 1. Parallelization. 2. Capture of build artifacts, which can also be useful for logs of non-linear complex tests such as dependencies of e2e tests. 3. Secrets for release or artifact uploads to third party repos (e.g. docker repos) 4. Caching. There may be more. Once you sprinkle these things left and right in your CI config, it becomes hard to move to another, even if the bulk of the actual tests you run are just "make test"
- Beltalowda 4y agoYou don't really need all that much CI-specific stuff for most of that, except maybe the secrets, although you will end up duplicating some CI features if you choose not to use them, but that's usually not too hard.
- jawadch93 4y ago[dead]
- alexanderdavide 4y agoAct is truly helpful and I appreciate its development but it has its caveats. For instance, I face problems with passing parameters to composite actions.
- zephyros 4y agoI found Dagger[1] and Earthly[2] which supposedly would solve the issue of debugging the CI locally. I haven't got time to try them out yet though. [1]: https://dagger.io/ https://dagger.io/ [2]: https://earthly.dev/ https://earthly.dev/
- noroot 4y agoYeah, I got so frustrated with the odd workflow (having no sane way to locally test new/more advanced pipelines and having to do lot's of "change .gitlab-ci commits") at work that I started investigating alternatives. At home, for some hobby projects, I've been using earthly. It's just amazing. I can fully run the jobs locally and they are _blazing_ fast due to the buildkit caching. The CI now only just executes the earthly stuff and is super trivial (very little vendor lock in, I personally use woodpecker-ci, but it would only take 5 minutes to convert to use GH actions). I am not a fan of the syntax. But it's so familiar from Dockerfiles and so easy to get started I can't really complain about it. Easy to make changes, even after months not touching it. Unless I update dependencies or somehow invalidate most of the cache a normal pipeline takes <10s to run (compile, test, create and push image to a registry). This workflow is such a game-changer. It also allows, fairly easy, to do very complicated flows [1]. I've tried to get started with dagger but I don't use the currently supported SDK's and the cue-lang setup was overwhelming. I think I like the idea of a more sane syntax from dagger, but Earthly's approachability [2] just rings true. [1]: https://github.com/phoenixframework/phoenix/blob/master/Earthfile https://github.com/phoenixframework/phoenix/blob/master/Eart... [2]: https://earthly.dev/blog/platform-values/#approachability https://earthly.dev/blog/platform-values/#approachability
- deleted 4y ago[deleted]
- shepherdjerred 4y ago+1 for Earthly. It isn't perfect, but it does a very good job at making CI and development 1:1
- killingtime74 4y agoAlso https://batect.dev/ https://batect.dev/
- dabeeeenster 4y agoHow does this deal with docker in docker? Or does it not?
- Arnavion 4y agoRather than replacing your Makefile with GH Actions, replace your GH Actions with a Makefile, and make your GH Actions run `make` in a script task. Do you really need that GH Action for pulling Docker images / installing $language_compiler / creating cloud resources ? A `docker` / `curl` / `sudo apt-get install` invocation in a Makefile / script needs to be written once and is the same in CI as on your dev machines. The Action is GH-specific, requires you to look it up, requires you to learn the DSL for invoking it, requires you to keep it up-to-date, requires you to worry about it getting hacked and stealing your secrets, ... A Makefile already supports dependencies between targets. A shell script is a simple DSL for executing processes, piping the output of one to another, and detecting and acting on failure of subcommands. How much YAML spaghetti do you need to write to do those same things in a workflow file?
- Gigachad 4y agoWith actions you can run multiple tasks in parallel, restart failed portions without retrying the whole CI, run certain sections with conditions like which branch you are on (different tasks when commit to master vs feature branch)
- Arnavion 4y ago>With actions you can run multiple tasks in parallel, If you mean "I want to run one build with the foo feature and one build with the bar feature. Actions lets me run those in parallel", then that is the "strategy" part of the workflow, not the "tasks" part. My comment was about the latter. ("and make your GH Actions run `make` in a script task.") If you mean "I want to run two steps of a job in parallel and then run the rest of the job after they're complete", then shell is a much simpler DSL for that. Running things in parallel is literally a single `&` character. >restart failed portions without retrying the whole CI, run certain sections with conditions like which branch you are on (different tasks when commit to master vs feature branch) So can a shell script.
- FooBarWidget 4y ago> Running things in parallel is literally a single `&` character. Yes now try waiting for all parallel tasks, and error out if at least one errors. And try separating their output so that they don't get interleaved into a big mess. And try by default hiding the outputs of commands that succeeded, only showing those that failed, except when the user explicitly asks for it. Your "simple" shell script now suddenly isn't so simple anymore.
- imaltont 4y agoGit also has built in support for automated stuff (git hooks). By default it is only local to each machine, but it is possible to set it up to distribute the hooks too.
- toastal 4y agoYep. And these hook shell scripts, don't need to involve Node.js projects (cough Husky) injecting this scripts and executing them without your consent.
- mathstuf 4y agoExcept that `git commit -n` exists. Server-side checking is still important.
- imaltont 4y agoThe post is about running github actions locally though. The built in ones also support running server-side too, though I imagine github doesn't have the same level of interface over that as their own services.
- mathstuf 4y agoThe comment I was replying to seemed to have the idea that `git hooks` could replace actions. Maybe I just read too much into it.
- imaltont 4y agoIt was my comment you replied to. I meant for running scripts locally, before pushing/pulling/commiting etc. The distribution part is just those scripts being by default in a folder that is not tracked by git (.git/hooks), but you can change it in your config file. Hooks should be able to run any executable script file, so there isn't really any limits outside of convenience to what you can make it do. You probably could use server-side git hooks just fine as an alternative if you self host the repo though, but I would assume if you are using github, or another hosting service, their tools are probably best/easiest/most convenient for their own platform.
- exDM69 4y agoThis could've been very useful to me when setting up some cross compiler targets in a Rust project. I burned through my almost all of my 3000 actions minutes in no time at all. Had to put my project on a hiatus until the next billing period starts. It's very easy to set up a nice matrix of CPU architectures and operating systems, but phew does it churn through a lot of CPU time fast. I did not like configuring the GH Actions YAML files at all, but in the end it works quite nicely. The ability to do MSVC Windows (x86_64-pc-windows-msvc) and MacOS builds (for "free") is kinda nice.
- teekert 4y agoYou can also very easily start runners yourself, perhaps some unused hardware or a linode can get you there cheaper?
- patrickaljord 4y agoIsn't GitHub Actions now open source? You can self-host runners now https://github.com/actions/runner https://github.com/actions/runner or am I missing something?
- techn00 4y agoThat's only the "agent", the coordination between github and the actions happens on github's side (proprietary).
- mdaniel 4y agoThat smells like a good opportunity to set up a mock http server that implements enough of the Actions API to trick the runner into executing the job as if it was a push event
- zingar 4y agoI’ve been playing with Act but I find it’s slower to run locally on my M1 MacBook than it is to just push things up to github to run. Edit: also, why does it run things as root instead of with a use set up the same way as actions?
- maxloh 4y agoYou can use "/linux/ubuntu/runner" images https://github.com/catthehacker/docker_images https://github.com/catthehacker/docker_images Seems like the documentation is a little bit hard to find.
- lagrange77 4y agoIt would be really cool, if you could run those docker images on a docker host on another machine in your network.
- letmeinhere 4y agoAbility to run {X} locally is _the_ problem with building atop paid services, not the dreaded vendor lock-in.
- naikrovek 4y agodo your builds and tests in a container. run the container on your dev machine or your dreaded paid service. same every time no matter what.
- letmeinhere 4y agoUntil your (to extend your example) container orchestration is complex enough that that too requires faster/less permissioned iteration than infrastructure-as-code provides, in which case you need to reimplement the paid service locally. Hopefully then the paid service is open source or has some good-enough-for-your-needs analog like this. FWIW, while the above sort of recommends kubernetes-everywhere, I'm happy to make a bet on a service like AWS Fargate because I _don't_ think I need to iterate on container orchestration much (as an application developer). Something like DynamoDB, by contrast, seems quite treacherous to build atop, given how closely an application's code is likely to be tied to its primary database.
- vacillator 4y agoMy solution to testing GitHub actions is pretty straightforward - I've created a private repository where I push and test my actions first. Then when I'm satisfied, I go ahead and create a PR on the main repository I want the action to be in.
- andrewallbright 4y agoGood tip -- engineers are like Jurassic Park because they always find a way. Will you evaluate this tool to see if it affords a nicer workflow for you?
- smoyer 4y agoI NEED this RIGHT NOW - awesome and thank you so much to the submitter! I'm writing my first action and there are so many facets to interacting with the runtime environment that I was testing by pushing updates. Checking my commits, I see that I committed and pushed 19 times this morning and most of them could have been avoided using act. I should also note that my Action is a bit odd since it has the local (to Docker) checkout and then calls back to the GitHub GraphQL API to make changes.
- montroser 4y agoWe have used this many times during GitHub outages. It's great and does what it says. But just one word of warning: when you run `act` with no arguments, what does it do? Displays usage? Nope -- it runs all workflows defined in the repo, all at once in parallel! This seems like a crazy default to me. I've never wanted to do anything remotely like that, so it just seems both dangerous and inconvenient all at once. Nice otherwise though...
- tyropita 4y agoIt was indeed very unexpected. The first time you would try out a cli tool you’d expect just calling its name to return help info and maybe an error.
- ta988 4y agoThis piece of software would have to handle all the intricacies of the GitHub actions but also be updated to the latest changes... We are moving back to a makefile based approach that is called by the GitHub workflows. We can handle different levels of parallelism: the make kind or the indexed by worker number when running in actions. That way we can test things locally, we can still have 32 workers on GitHub to run the full suite fast enough. I also like that we are less bound to GitHub now because it has been notorious unreliable for us this past year and we may move more easily to something else.
- counttheforks 4y agoIs this public?
- ta988 4y agoNo, sorry about that.
- Xelynega 4y agoYou could implement something similar by splitting the make targets in the GitHub action before they get passed to make so each worker is assigned their own target, then have a make target that executes all the targets for local multithreaded builds via `make -j${NUM_CONCURRENT}`.
- killingtime74 4y agohttps://batect.dev/ https://batect.dev/ this is like Act but agnostic and public
- mdaniel 4y agoAre you sure you mean "like Act?" https://batect.dev/docs/using-batect-with/ci/github-actions https://batect.dev/docs/using-batect-with/ci/github-actions seems to imply it is its own build system, closer to Dagger or Earthly, but not a GitHub Actions "emulator" as act is trying to be
- 4y ago
- enbugger 4y agoThis is what Jenkins has been missing for years. Still no viable solution except keeping everything outside of Jenkinsfiles as much as possible.
- hajimuz 4y agoIt’s a good tool but a lot of behaviors are different with GitHub Action so you still can’t test everything locally.
- deleted 4y ago[deleted]
- Spivak 4y agoThis is one of the advantages Gitlab has because the ability to do this is built into gitlab-runner so you don’t have to maintain anything, you’re using the same code Gitlab itself is.
- mdaniel 4y agoThey like to pretend that's true, but it is for sure not, at least not unless your job is so simple it could literally be a shell script or a Makefile as others have said Any use of rules, cache, includes, or ... you know, real life ... gitlab-ci constructs makes `gitlab-runner exec my-job` do absolutely nothing helpful. The circleci binary did as advertised on the tin and has been my favorite "debug ci builds locally" experience
- hardwaregeek 4y agoI really really want to use this but it doesn't work with podman which is unfortunately a bit of a blocker. IMO every CI system should be runnable locally, with minimum effort. Otherwise you end up testing via git push and that's just an ugly development cycle. This does make me wonder if you could create a sort of "local first CI" where CI is just an extension of local checks. Therefore the CI is just a check that tests that pass locally also pass on a clean machine. Obviously we don't want to run CI locally if it'd take an hour, but on the flip side, if CI takes an hour on a (typically) beefy local dev machine, it'll probably take 2 hours on a remote machine.
- reillyse 4y agoSuper interesting you mention “local first CI”. Have a look at Brisk https://brisktest.com/ https://brisktest.com/ (I’m the author). It’s designed to work “locally” pre-commit, giving you super fast tests, but then when you push you can also use it in your CI/CD pipeline. We achieve the speed with massive concurrency and pre-built environments, it was built as a drop in replacement for your local test runner.
- hardwaregeek 4y agoAwesome! Glad to see people are thinking the same things. I'll definitely check it out.
- maxloh 4y agoThe big images (the image GitHub actually use) seems to be outdated for about 5 months. Any chance for rebasing it to upsteam?
- tryauuum 4y agojust because no-one mentioned it. With Gitlab CI you can run pipeline locally if you install gitlab-runner. Sadly, you can run only one job at a time, not the whole pipeline
- mdaniel 4y agohttps://news.ycombinator.com/item?id=33754907 https://news.ycombinator.com/item?id=33754907 mentioned it, and I addressed that "run pipeline locally" claim, which has 100% not been my experience Now, the asterisk to that claim is that I have had good success running gitlab locally, with local runners, such that I can do whatever crazy thing I want to the CI variables, to the repo, to the branches, and can run the runners in "debug" mode (although usually not necessary since I can "docker exec" into them) but the idea that I can just tell my colleagues to "brew install gitlab-runner && gitlab-runner exec some-job" is for sure false
- cmckn 4y agoIt’d be great if act could build its container images locally instead of downloading them through a rate-limited pipe from docker hub. The full size image (~14gb) takes the better part of a day to download; I’ve never been able to wait it out on my work laptop.
- mdaniel 4y agoIf your Internet is so bad, this might not help you, but it's possible to build them locally: https://github.com/nektos/act-environments#building-images https://github.com/nektos/act-environments#building-images
- cmckn 4y agoI have a gigabit connection, docker hub just won’t give me the bits fast enough :( thanks for the link!
- edgan 4y agoYou should try pulling it from gcr.io.
- glauber 4y agoIs there anything similar for Azure DevOps? It’s a nightmare to debug yml pipelines.
- dwardu 4y agoHow does it work with OIDC and AWS? Do I just authenticate my dev account locally?
- MauroIksem 4y agoThis is incredible. Thanks for posting.
- rpep 4y agoI'm a strong advocate (after migration between various cloud CI providers free tiers when I worked in academia) of making your build process as agnostic as possible to the CI provider. That generally means putting things into shell scripts and calling them, which can be a bit painful, and you'll never get 100% there, but it also has the added benefit of being able to debug things locally too if something goes wrong with the pipeline. The first time I used GH Actions I thought there was a strong vendor lock-in element to it which I wasn't hugely comfortable with. I'm a big fan of using GitLab CI these days which seems to be a good trade off between various considerations.