Live data from Hacker News

Act: Run your GitHub Actions locally

github.com

111–120 of 161 posts

Re: Act: Run your GitHub Actions locally

#111

Ability to run {X} locally is _the_ problem with building atop paid services, not the dreaded vendor lock-in.

do 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.

Until 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.

Re: Act: Run your GitHub Actions locally

#112

Rather 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.…

I use Makefiles anywhere I can fit them they're a brief respite from YAML hell. This issue was solved in 1976 -- I appreciate there's a lot of VC money in reinventing the wheel (and coming full circle) but I digress.

I too use Make everywhere, but what I would give for an improved tool that had better syntax, composability, and simultaneously deployed everywhere. Sadly, it is good enough, so we shall suffer forever.

Re: Act: Run your GitHub Actions locally

#116

Earlier quoted context omitted.

This 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.

Yep. 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 a…

You 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.

Re: Act: Run your GitHub Actions locally

#117
post #115

This 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.

They 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

Re: Act: Run your GitHub Actions locally

#119
post #47

Isn't GitHub Actions now open source? You can self-host runners now https://github.com/actions/runner or am I missing something?

That's only the "agent", the coordination between github and the actions happens on github's side (proprietary).

That 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

Re: Act: Run your GitHub Actions locally

#120
post #66
post #63

Earlier quoted context omitted.

What about caching to reduce ci time? GH setup scripts cache dependencies in a way that would seem hard to replicate in a make file.

If it’s manageable – just don’t. Build from scratch. Make sure your build works from scratch and completes in acceptable timeframe. If it’s painful, treat the root cause and not the symptoms. If it’s unbearable due to circumstances out of your control, there’s nothing wrong with adding some actions/cache steps to .github/workflows – this goes around the build: fetch previous cache before, update the cache after if ne…

> If you need to install a whole host of mostly static dependencies, GitHub Actions support running steps in arbitrary Docker container. Prepare an image beforehand, it can be cached too, now you have a predictable environment. (The only downside is that it doesn’t work on macOS and Windows.)

Actually I use a similar workflow for some of the other projects that I have to work with, keeping everything CI agnostic. I incrementally add various types of dependencies to the container images where the application will be built.

For example:

  1. common base image (e.g. Debian, Ubuntu, or something like Alpine, or maybe RPM based ones)
  2. previous + common tools (optional, if you want to include curl or other tools in the container for debugging or testing stuff quickly)
  3. previous + project runtime (depending on tech stack, for example OpenJDK for Java projects)
  4. previous + development tools (depending on the tech stack, typically for pulling in dependencies, like Maven, or npm, or whatever)
  5. previous + project dependencies (if the project is large and the dependencies change rarely, you can install them once here and the changing 5% or so later)
  6. previous + project build (including things like running tests, typically multi-stage with the build and tests, and built app handled separately)
Compared to the more "common" way to do things, step #5 probably jumps out the most here, I do a pass of installing all of the dependencies, say, every morning, or hourly in the background, so that later when the project is built the CI can just go: "Hmm, it seems like 95% of the things I need here are already present, I'll just pull the remaining packages (if any)." Clean installs only need to be done when packages are removed, which is also reasonably easy to do.

Though the benefits of this aren't quite as staggering, if you use a self-hosted package repository like Sonatype Nexus, which can cache any dependencies that you've used previously and make everything faster on the network I/O side. This only doesn't hold true when actually installing the packages takes up the majority of the time (e.g. compiling native code), in which case the above is still very useful.

So, an example of how the stages might look, is as follows:

  Builder: Ubuntu + tools (optional) + OpenJDK + Maven + project dependencies + project build (and run tests)
  Runner:  Ubuntu + tools (optional) + OpenJDK + built project from last image (using COPY with --from, typically .jar file or app directory)
Of course, things are less comfortable when you don't have all of your app's dependencies packaged statically but need them "on the system" instead, like Python packages or Ruby Gems, but then your builder and runner will simply look more alike.

For my own personal stuff I also use a slightly simplified version of this, about which I wrote on my blog here, the drawbacks included: https://blog.kronis.dev/articles/using-ubuntu-as-the-base-fo...

Post reply on HN