- write the main job in a Python/PowerShell/Bash script that runs locally,
- write a workflow that sets up the environment (AWS login), installs dependencies (using GitHub's facilities for that) and calls the script (often passing values using GitHub Secrets),
- push the workflow with a "push" trigger on a feature branch (for fast testing),
- push 30 fixup commits to fix all the small syntax errors, logic mistakes, and GHA idiosyncrasies I hadn't thought of,
- remove the push trigger,
- do an interactive rebase to squash all the fixups,
- force-push and merge.
It works pretty well and can be easily used locally or in other CI/CD systems.
I don't have a lot of experience with GitHub Actions, but is there really no better way to do this?
You could write the workflow correctly the first time. Good luck. It's not one language, you're writing PowerShell scripts inside a bunch of YAML files that reference each other with relative paths and need to call installers that were never written for unattended installs. The only way I can make it work is through trial and error.
GHA really feels like it's trying to cobble up a CI/CD pipeline from a million different pieces that were designed for entirely different purposes. It works, if you spend enough weeks on it, but it will never be pleasant to configure. I can understand why they didn't even try to make it reproducible on the users' workstations, it can break if basically any part of your system's configuration, filesystem, or environment deviates from the runners.
That's obviously not entirely GitHub's fault and the service is very practical once it's set up. My advice is to depend on GHA for their useful features (caching, Secrets, parallel jobs) and do everything else in your own scripts or in Docker.
> - write the main job in a Python/PowerShell/Bash script that runs locally,
> - write a workflow that sets up the environment (AWS login), installs dependencies (using GitHub's facilities for that) and calls the script (often passing values using GitHub Secrets),
> - push the workflow with a "push" trigger on a feature branch (for fast testing),
> - push 30 fixup commits to fix all the small syntax errors, logic mistakes, and GHA idiosyncrasies I hadn't thought of,
> - remove the push trigger,
> - do an interactive rebase to squash all the fixups,
> - force-push and merge.
> It works pretty well and can be easily used locally or in other CI/CD systems.
It saddens me that such madness is considered as "works pretty well"
Unironically yes. It's awful, it's ugly, but it works with no extra setup, effort, or cost (other than feeling dirty for a few minutes).
git add […] && EDITOR=true git commit --amend && git push -f […]
(You don't have to open a PR / the usual history rewriting consequences don't apply if you're just pushing to Actions to see how it reacts.)But alternatively, if you find yourself doing this a lot and it's really the code of the step that you're debugging (vs. debugging how the workflow interacts with Actions itself) I try to keep my jobs' steps pretty simple:
- run: ci/thing.sh
… specifically so that I can run the step locally. It's usually much faster. (And on a MBP, doesn't incur the costs of virtualization, at the cost of needing to port to macOS. Usually worth it.) amend = commit —-amend —-no-edit
and if you need to edit the commit message alongside merging new changes in HEAD, > git amend -e -C <commit>, --reuse-message=<commit>
Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.
In the above example, commit can simply be "HEAD", when doing the amend commit: git commit -C HEAD --amendi 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
git commit . -m fix