CI Pipelines for ArmA3 mods
2024-07-24
Previous: [Woodpecker CI Setup on NixOS]
With setting up woodpecker being out of the way, I can now focus on actually writing the CI pipeline.
Overall, grasping the concepts nessecary was far easier than expected. I already have some familiarity with how containers work and I didn't find anything else within the documentation particurlarly difficult to understand.
I ended up writing the first half -- the compilation of the mod itself -- within a couple of hours after having setup woodpecker. It entailed downloading the build tool off of github, unzipping it and calling it to build the mod.
The other half, and what I ended up spending a considerable amount of time on, was actually getting the mod to be uploaded to the steam workshop reliably. There ended up being a few hurdles.
One was figuring out how to go from 'game mod' to 'thing that you can upload to the steam workshop'. I recalled having come across a github action that actually did just that for an ArmA3 mod. It relied on steamcmd
and essentially took the mod, wrote a workshop.vdf
file, which included metadata about the mod itself (what game it belongs to, the mod's ID, a changelog message, etc), and called steamcmd
with login credentials to upload it. Simple enough. I ended up using a modified version of that shell script within my pipeline.
Second was to figure out how to properly store credentials within a public repository, and how to easily access them from within a shell script. Luckily, woodpecker comes with a system for storing such things. They are called secrets, stored as strings within woodpecker itself, and are made to be write-only from the admin's perspective. I.e you can only write to them and you can never read them back (at least intentionally). You can still leak the secrets if you manage to write a pipeline that somehow manages to spit out secret values in any roundabout way (b64 encoded, encrypted, etc), so don't expect them to be truly secure, especially if you are running untrusted pipelines or have other people who can modify your pipeline.
And last but not least, I had to actually get steam workshop updates to run reliably. I ran into an issue where I could not login to the account that the steam workshop item belonged to from inside the pipeline container. The issue at heart here is that steamcmd
asks for a Steam Guard code supposedly every time a login attempt is made on an unfamiliar machine. An internet search revealed that steamcmd
does not ask for repeated codes upon a single successful login. This is achieved by steamcmd
writing to a file labled config.vdf
and updating it every time you log in with user/pass successfully. If it can't find a valid config.vdf
, it asks for a Steam Guard code.
The source of the issue was the fact that I was running steamcmd in a container, which is unable to persist config.vdf
between runs, by virtue of being a container.
The solution, in hindsight, is simple. I just needed to setup a persistent docker volume for the container that does the uploading. After that, All I needed to do is login through steamcmd once on the woodpecker host, have it write to it's config.vdf
, and after that, all my pipelines started to run reliably. I'll admit that figuring this out took longer than I'd like to admit, but hey, it's a learning experience.
All in all, I now have a valid, working pipeline that pushes an update to the steam workshop every time I push a commit to the release
branch within my mod. Lovely.
I can also say that I now have a much better understanding of how to setup and run CI/CD pipelines in general. This was a good experience.
You can find the resulting CI setup here, within the .woodpecker
folder.