Docs ▸ Steam
Publishing
npx gameshipper publish --dry-run # check everything, upload nothing
npx gameshipper publish # Steam, itch.io and GitHub Releases, whichever are set up
npx gameshipper publish --to steam --branch beta # also set the Steam build live on your beta branch
npx gameshipper publish --to github --live # publish the GitHub release instead of leaving a draftSet these in gameshipper.json; they're names, not secrets:
| Field | Example | For |
|---|---|---|
steam.appId |
1234560 |
Steam: your own App ID. 480 is Valve's test app, which can't take uploads, so Steam is left out until you set it |
steam.user |
moon_builder |
Steam: the account that uploads builds (or pass --steam-user) |
steam.depots |
{ "windows": 1234561 } |
Steam: depot IDs, when they aren't the App ID + 1, 2 and 3 |
itch.project |
moonstudio/moon-game |
itch.io |
github.repo |
moonstudio/moon-game |
GitHub Releases (or pass --repo) |
Steam. Gameshipper downloads Valve's SteamCMD into its cache (checked against a pinned SHA-256) and uploads one build with a depot per OS, from out/windows, out/mac and out/linux, with your version as its description; steam_appid.txt is never uploaded. The first time, SteamCMD asks for the password and Steam Guard code in your terminal; Gameshipper never sees them. SteamCMD runs with a HOME of its own in Gameshipper's cache, where it keeps its login, and on a Mac with a stand-in launchctl, so it never changes your Steam client's files and never loads or removes its background jobs. The build is uploaded, not set live: publish prints the link to set it live, and the launch option and Steam Cloud settings to enter once in Steamworks. --branch beta also sets it live on an existing beta branch; Valve only lets the website set the default branch live. The account needs Steamworks' Edit App Metadata and Publish App Changes To Steam permissions, and Valve recommends an account just for builds. A dry run logs in too, because Steam checks the build on its servers.
itch.io. Gameshipper downloads itch.io's butler and pushes each build to the channels windows, mac and linux, with your version. The first time, butler opens your browser to log in, and keeps the login itself; in CI, set BUTLER_API_KEY. Uploads are downloadable at once if the game's page is public: keep it in Draft to try a build first.
GitHub Releases. Needs a token in GITHUB_TOKEN (or GH_TOKEN) that can write to the repository: a fine-grained token limited to it with Contents: Read and write, or a classic token with the repo scope. Set it yourself, in your shell or the MCP server's environment; never paste it into a chat with an agent. Gameshipper never uses the gh CLI's login. It zips each build (on a Mac with ditto, so the Mac app keeps its signature however it's unzipped) and attaches them to the release v<version>, as a draft unless you pass --live. Publishing again replaces the draft's files; a published release is never changed (GITHUB_RELEASE_PUBLISHED: raise the version).
iOS and Android aren't uploaded: publish lists the steps in Xcode and Android Studio.
| Code | |
|---|---|
STEAM_LOGIN_REQUIRED, ITCH_LOGIN_REQUIRED |
No saved login, and nobody at a terminal to log in (an agent, --json or --yes): run the command in the fix once in your own terminal. Exit code 2. |
BUILD_MISSING, STEAM_TEST_APP, STEAM_DEFAULT_BRANCH, GITHUB_TOKEN_MISSING, GITHUB_AUTH_FAILED, GITHUB_REPO_NOT_FOUND, GITHUB_RELEASE_PUBLISHED |
Something to set or fix first; exit code 2. |
STEAM_PATH_UNSUPPORTED |
The game folder's path has a " (or, on macOS and Linux, a \), which SteamCMD's build scripts can't hold: move or rename the folder. On a Mac it's also returned when Gameshipper's cache folder has a :: set GAMESHIPPER_CACHE to another. Exit code 2. |
STEAM_UPLOAD_FAILED, STEAM_SET_LIVE_FAILED, STEAM_LOGIN_FAILED, STEAMCMD_CANT_RUN, ITCH_PUSH_FAILED, ITCH_LOGIN_FAILED, GITHUB_API_FAILED, ZIP_FAILED, TOOL_DOWNLOAD_FAILED, TOOL_CHECKSUM_MISMATCH, TOOL_UNSUPPORTED_HOST |
The upload or a tool failed; the message says why and the run log has the tool's output. Exit code 1. |
ITCH_UPLOADS_LIVE |
A warning: itch.io uploads are public at once if the page is. |