Debugging GitHub actions locally in an interactive shell
It’s not news that nektos/act
works well to
debug GitHub actions locally, but I wanted the fast feedback loop of an
interactive shell instead of re-running act push
each time I changed echo
commands in the workflow file.
Today was the first time that I resorted to nektos/act
because usually it
isn’t so difficult to reproduce CI-only errors locally in JavaScript projects,
but today it happened and I’m glad it exists.
Fortunately I had already installed Docker in my Fedora machine so I was spared of this headache, but I still needed to fix not being able to run it as a non-root user:
sudo groupadd dockersudo usermod -aG docker $USERnewgrp docker docker run hello-world
Once that was done, I started running the problematic action locally to start debugging it:
act push
At first, I was adding echo
commands to debug what I think would help me
understand the errors:
name: Debugrun: echo "grep -C10 'export type CollectionEntry' ./.astro/content.d.ts"
But this workflow got tired fast since it’s not so much faster than running it on github.com itself, so I had the idea of getting into this Docker image after a certain step, similar to a debugging breakpoint.
Nothing as such exists, naturally, but I asked Claude and it gave me an amazing
idea… to use sleep
:
name: Sleeprun: sleep 9999999999
Once the Docker container is sleeping, we can run /bin/bash
to get access to
it! First, we need the Docker container, let’s run docker ps
to find it:
% docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES43539276413c catthehacker/ubuntu:act-latest "tail -f /dev/null" 51 minutes ago Up 51 minutes act-Deploy-website-to-GitHub-Pages-on-push-deploy-222f0898354481efb0d5304069c913b76bf812924903a1f31f1e1000da84071f
Then we can hop into a Bash shell with the following command:
% docker exec -it 43539276413c /bin/bash
Now, I can run any commands or read any files without waiting for the whole workflow to run! It’s perfect.
Unfortunately, it does not have vim
nor emacs
neither nano
, so it’s
difficult to edit files but we still have “here documents”:
% cat << EOF > myfile.json{"foo":"bar"}EOF
It is even possible to copy container files to the host machine to help reproducing the errors — that was how I ended up finding the fix:
% rm -rf .astro% docker cp 43539276413c:/home/phelipe/Projetos/blog/.astro .
…In case you’re wondering, it was a bunch of TypeScript errors of the type
TS7006: Parameter 'xxx' implicitly has an 'any' type
that occurred only for
Astro-generated types, which explains my attempt to reproduce the errors by
copying the container .astro
folder. Eventually, I discovered that the
problem was with my tsconfig.json
, which was outdated according to Astro docs
recommendations:
{ "extends": "astro/tsconfigs/base", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"]}
I also learned that tsconfig.json
files do not merge array values with the
extended tsconfig.json
array values, which was the mistaken assumption that
kept me from fixing it faster.