Deploy to Steam
This page assumes you are registered as a partner with Steam and that you are familiar with using SteamPipe to upload your builds to Steam.
1. Create a Steam Build Account
Create a specialised builder account that only has access to Edit App Metadata and
Publish App Changes To Steam.
See the docs.
2. Add jobs to main.yml
jobs:
buildForWindowsAndLinux:
name: Build for ${{ matrix.targetPlatform }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
targetPlatform:
- StandaloneWindows64 # Build a Windows 64-bit standalone.
- StandaloneLinux64 # Build a Linux 64-bit standalone.
outputs:
buildVersion: ${{ steps.buildStep.outputs.buildVersion }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ matrix.targetPlatform }}-${{ hashFiles('Assets/**', 'Packages/**',
'ProjectSettings/**') }}
restore-keys: |
Library-${{ matrix.targetPlatform }}-
Library-
- uses: game-ci/unity-builder@v4
id: buildStep
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
targetPlatform: ${{ matrix.targetPlatform }}
versioning: Semantic
- uses: actions/upload-artifact@v4
with:
name: Build-${{ matrix.targetPlatform }}
path: build/${{ matrix.targetPlatform }}
deployToSteam:
needs: [buildForWindowsAndLinux]
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download StandaloneWindows64 Artifact
uses: actions/download-artifact@v4
with:
name: Build-StandaloneWindows64
path: build/StandaloneWindows64
- name: Download StandaloneLinux64 Artifact
uses: actions/download-artifact@v4
with:
name: Build-StandaloneLinux64
path: build/StandaloneLinux64
- uses: game-ci/steam-deploy@v3
with:
username: ${{ secrets.STEAM_USERNAME }}
configVdf: ${{ secrets.STEAM_CONFIG_VDF}}
appId: ${{ secrets.STEAM_APP_ID }}
buildDescription: v${{ needs.buildForWindowsAndLinux.outputs.buildVersion }}
rootPath: build
depot1Path: StandaloneWindows64
depot1InstallScriptPath: StandaloneWindows64/install_script.vdf
depot2Path: StandaloneLinux64
releaseBranch: prerelease
3. Add GitHub Secrets
- STEAM_USERNAME: The username of the Steam Build Account that you created in step 1.
- STEAM_CONFIG_VDF: See the step "Setup Steam Authentication" below.
- STEAM_APP_ID: The identifier of your app on steam. You can find it on your dashboard.
4. Setup Steam Authentication
Deploying to Steam requires using Multi-Factor Authentication (MFA) through Steam Guard. This means that simply using username and password isn't enough to authenticate with Steam. However, it is possible to go through the MFA process only once by following these steps:
- Install Valve's offical steamcmd on your local machine. All following steps will also be done on your local machine.
- Try to login with
steamcmd +login <username> <password> +quit, which may prompt for the MFA code. If so, type in the MFA code that was emailed to your builder account's email address. - Validate that the MFA process is complete by running
steamcmd +login <username> +quitagain. It should not ask for the MFA code again. - The folder from which you run
steamcmd(or~/Library/Application Support/Steamon macOS) will now contain an updatedconfig/config.vdffile. Usecat config/config.vdf | base64 > config_base64.txton Linux to encode the file, if you are on a Windows device, usecertutil -encode -f .\config\config.vdf tmp.b64 && findstr /v /c:- tmp.b64 > config_base64.txt. Copy the contents ofconfig_base64.txtto a GitHub SecretSTEAM_CONFIG_VDF. - If when running the action you receive another MFA code via email, run
steamcmd +set_steam_guard_code <code>on your local machine and repeat theconfig.vdfencoding and replace secretSTEAM_CONFIG_VDFwith its contents. - You will also need to repeat the process if the action fails with
ERROR (License expired)when logging into Steam.
If your builder account uses MFA through the Steam Guard App, the steam-deploy app can use a TOTP
instead of the above configuration. Generating a TOTP is outside the scope of this guide, as it is
simpler to follow the above steps.
5. Additional Configuration
You can configure these to better match your use case.
totp
Deploys to Steam using a TOTP. If this is passed, configVdf is not required.
buildDescription
The identifier for this specific build, which helps you identify it in steam.
It is recommended to use the semantic version of the build for this.
rootPath
The root path to your builds. This is the base of which depots will search your files.
depot[X]Path
Where X is any number between 1 and 9 (inclusive both).
The relative path following your root path for the files to be included in this depot.
If your appId is 125000 then the depots 125001 ... 125009 will be assumed.
depot[X]InstallScriptPath
Where X is any number between 1 and 9 (inclusive both).
The relative path following your root path for the InstallScript to be included in this depot.
If your appId is 125000 then the depots 125001 ... 125009 will be assumed.
firstDepotIdOverride
You can use this to override the ID of the first depot in case the IDs do not start as described in depot[X]Path (e.g. for DLCs).
If your firstDepotId is 125000 then, regardless of the used appId, the depots 125000 ... 125008 will be assumed.
releaseBranch
The branch within steam that this build will be automatically put live on.
Note that the default branch
has been observed to not work as a release
branch, presumably because it is potentially dangerous.
extraExclusions
Comma-separated extra file-exclusion glob patterns for the primary depot, on top of the built-in
defaults (*.pdb, *.log, *.vdf, and Unity's Burst debug/backup folders). Useful for anything
Valve's depot FileExclusion
rules need to
strip that isn't already covered.
- uses: game-ci/steam-deploy@v3
with:
extraExclusions: '*.tmp,Docs/*'
# ...
Finer-grained depot control — multiple FileMapping blocks per depot, and FileProperties
(userconfig/versionedconfig, for files a player modifies locally that updates shouldn't
overwrite) — is implemented in game-ci/cli but not yet exposed as
inputs on this action. Track game-ci/steam-deploy#67
for progress.
6. Multiple Steam accounts or apps in one workflow
You don't need anything special for this — username/configVdf/appId are all per-step, so just
add one game-ci/steam-deploy step per account or app, each pointed at its own secrets:
steps:
- uses: game-ci/steam-deploy@v3
with:
username: ${{ secrets.STEAM_USERNAME_APP1 }}
configVdf: ${{ secrets.STEAM_CONFIG_VDF_APP1 }}
appId: 111111
rootPath: build/app1
- uses: game-ci/steam-deploy@v3
with:
username: ${{ secrets.STEAM_USERNAME_APP2 }}
configVdf: ${{ secrets.STEAM_CONFIG_VDF_APP2 }}
appId: 222222
rootPath: build/app2
7. Bundling extra files with a build (e.g. the Steamworks SDK)
Anything under the path(s) you point rootPath/depot[X]Path at gets uploaded as part of that
depot — there's no separate "extra files" input. Copy whatever you need into the build output
before the deploy step runs:
- run: cp -r steamworks-sdk-files/ build/StandaloneWindows64/
- uses: game-ci/steam-deploy@v3
with:
rootPath: build
depot1Path: StandaloneWindows64
Use extraExclusions if you need to keep specific files out instead.
8. Avoiding the artifact upload/download round-trip
actions/upload-artifact + download-artifact (as used in the example above) is only necessary
when the build and deploy steps run in different jobs — jobs don't share a filesystem. If you
build and deploy in the same job, the build output is already on disk when the deploy step
runs, so skip the artifact steps entirely:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: game-ci/unity-builder@v4
with:
targetPlatform: StandaloneWindows64
- uses: game-ci/steam-deploy@v3
with:
rootPath: build
depot1Path: StandaloneWindows64
Splitting build and deploy into separate jobs is only worth the artifact-transfer cost when you want to parallelize multiple platform builds ahead of a single deploy job, as in the step 2 example above.