Building and Publishing Games to Steam Directly from GitHub Actions
21 comments
·March 23, 2025adobrawy
Uvix
If there were a large number of contiguous commands that you could run in isolation, I’d agree. But it looks like four commands is the most you could chain together, and they depend on other tasks’ output, so I don’t see a lot of benefit to pulling them out into a shell script.
nevon
This doesn't really say much about publishing games from GitHub Actions. There's about 3 lines that reference https://github.com/game-ci/steam-deploy which contains the actual implementation.
hedin_hiervard
How do you deal with Steam Guard code?
maccard
I’ve run CI for games pushing to steam. The best way is to ensure a lock on steam operations to only allow one in parallel any time across your CI. Download the steam works sdk for your CI runner platform, bootstrap it locally, and log in manually once. Then push the entire sdk directory into S3, and in CI you then pull it, login without a password, and push the entire thing back to S3 again.
diggan
> Then push the entire sdk directory into S3, and in CI you then pull it, login without a password, and push the entire thing back to S3 again.
Doesn't that effectively defeat the purpose of 2FA?
Personally, I feel like I'd automate it in a way that everything up until that point is automated, but the actual "release" (upload really) to Steam would be in a different step that asks for the 2FA every single time, on purpose, so I actually get the benefits of a 2FA together with automating most of the pipeline while still having control of the final release.
maccard
> Doesn't that effectively defeat the purpose of 2FA?
Yes and No. You need to 2FA in the first place to get the credentials in place. After that it's just basic secrets management - your steam credentials are no more or less secure than your playfab developer secret that you use to upload servers, or the credentials that you use on your AWS machine to do the deploy.
There's no way to generate a service token for steam that says "this is allowed to deploy builds only", like a gha token, or an AWS credential. Both of those require you to 2FA to generate the token in the first place. Ultimately, if steam really cared about security they would allow for something like this, like every other modern provider does. But they haven't exactly kept up with "modern" best practices.
> Personally, I feel like I'd automate it in a way that everything up until that point is automated, but the actual "release" (upload really) to Steam would be in a different step that asks for the 2FA every single time, on purpose, so I actually get the benefits of a 2FA together with automating most of the pipeline while still having control of the final release.
You can't upload builds above a certain size manually to steam, you need to use steamcmd. Steam isn't just for releasing public builds, we use it for playtesting for example. So our CI uploads versions of our game to private betas on steam for our team to be able to jump into, like a staging environment. Requiring a manual step for that in another tool, with another set of credentials and scopes to manage is a bigger risk (IMO) than managing an extra secret. If you do these steps as manual steps but make the "release" step a manual step, then you've introduced a massive untested failure point in your deployment pipeline that happens at the latest possible moment. If you have servers to manage, or clients on another storefront (Epic, GoG, PSN/Xbox) you need to ensure versions are coordinated; and now you're potentially asking someone to log into 5 dashboards to set manually upload versions and set builds.
There's no reason games should be exempt from CICD best practices, IMO.
simonw
I'd protect my GitHub account with 2FA and configure GitHub Actions to trigger on creating a release in GitHub. That way my release process is fully automated but still protected by 2FA, in this case GitHub's 2FA implementation.
azthecx
You can see it on the totp section of the underlying project https://github.com/game-ci/steam-deploy
EncomLab
Why? For most games (especially a "2d hide and seek") you drop a zip file and press a single button on your dev console to publish.
diggan
> For most games (especially a "2d hide and seek") you drop a zip file and press a single button on your dev console to publish
If you read through the actual pipeline, you'll see it's not just "drop a zip file and press a single button". Firstly, you're missing everything that goes before even having a ZIP file, making that process reproducible is valuable regardless of what you do later. Secondly, doing this for three platforms would mean repeating the same thing three times, in slightly different ways. Automating it just makes sense at that point.
Overall, building and publishing a game via automation just brings about every benefit from CI/CD, just to a "game development" context instead, so you'd do it for the same reason you'd automate any software release process.
simonw
If you automate your release process:
1. You won't forget how to ship a release if you go months between releases
2. You won't make mistakes when you release code - forgetting a crucial step along the way for example
3. Related: you can add tests to your release process - so your release doesn't go out if you made some last-minute mistake that broke the build
4. You'll release more often: the automation has de-risked your release process and reduced friction around it, which means you can ship with more confidence and less ceremony
5. You can reliably share that release process with other collaborators - not end up in a situation where only one person's laptop is able to ship
6. If your laptop breaks or gets stolen it won't harm your ability to release software
All of the above are true for non-game projects, I don't see why they shouldn't apply to games as well.
usrusr
And that zip file might be not the version you thought it was, if it's not from a build server it might include any number of uncommitted or gitignored changes, more transfer steps mean more things that can go wrong. These automations are not about reducing keypresses, they are about reducing the number of trivialities to mess up. People tend to have other things on their mind when going through that kind of routine.
DonHopkins
I recently heard some salty chap here on HN use the term "ClickOps" as opposed to "DevOps" or "GitOps" to describe the "just click on the button in the dev console web page to do that" approach.
https://www.wiechtig.com/blog/clickops-is-the-worst/
https://www.lastweekinaws.com/blog/clickops/
https://blog.equinix.com/blog/2022/12/01/what-is-clickops-an...
pseudoeu
Congratulations! Nice job man.
null
lupusreal
What's the idea here, to make it easier for lazy devs to push builds to paying customers without even stopping to play test it themselves first? Streamlined publishing makes negligence easier and more enticing.
teamonkey
Steam allows you to host and deploy development builds of your game for testing, without being released to the public.
Essentially you gain access to a private game on Steam with one or more Steam opt-in betas, to test different branches. It's common to use a CI system to build and then deploy to a steam beta branch.
The process of doing that is, however, a little bit... raw.
null
I hope there is an author of the post. I appreciate sharing this example.
However, there is a caveat regarding the workflow code itself, that placing "run" statement with specific commands directly in YAML may make it difficult to debug locally. I would recommend that "run" statements be only for script execution and their number minimized. This way, scripts can be run locally without waiting for the entire CI pipeline to execute each time.