Skip to content

Instantly share code, notes, and snippets.

@Marc-Ducret
Created March 9, 2023 15:21
Show Gist options
  • Save Marc-Ducret/ae65c430e6d27bfdf618c89150559cb6 to your computer and use it in GitHub Desktop.
Save Marc-Ducret/ae65c430e6d27bfdf618c89150559cb6 to your computer and use it in GitHub Desktop.
Automate build and deploy to Steam
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using DiceKingdoms.Meta;
using UnityEngine;
using Unity.Build;
using UnityEditor;
using Debug = UnityEngine.Debug;
namespace DiceKingdoms.Editor.Build {
[CreateAssetMenu(fileName = "SteamBuild", menuName = "Dice-Kingdoms/SteamBuild", order = 12)]
public class SteamBuild : ScriptableObject {
[Header("References")]
[SerializeField]
private LocalVersion localVersion;
[SerializeField]
private string branchName;
[SerializeField]
private string steamCmdFolder;
[SerializeField]
private bool preview;
[Header("Apps")]
[SerializeField]
private App[] apps;
[ContextMenu("Build and Deploy")]
public void BuildDeploy() {
string folder = $"{Directory.GetCurrentDirectory()}/{steamCmdFolder}";
string AppFile(App app) => $"{folder}/input/app_build_{app.appId}.vdf";
string DepotFile(Depot depot) => $"{folder}/input/depot_build_{depot.depotId}.vdf";
string AppFileContents(App app) =>
$@"""AppBuild""
{{
""AppID"" ""{app.appId}""
""Desc"" ""{localVersion.Version.Render}""
""Preview"" ""{(preview ? 1 : 0)}""
""SetLive"" ""{branchName}""
""BuildOutput"" ""{folder}/output/""
""Depots""
{{
{string.Join("\n", app.depots.Select(depot => @$" ""{depot.depotId}"" ""{DepotFile(depot)}"""))}
}}
}}
";
string DepotFileContents(Depot depot) =>
$@"""DepotBuild""
{{
""DepotID"" ""{depot.depotId}""
""ContentRoot"" ""{Directory.GetCurrentDirectory()}/{depot.buildConfiguration.GetOutputBuildDirectory()}/""
""FileMapping""
{{
""LocalPath"" ""*""
""DepotPath"" "".""
""Recursive"" ""1""
}}
""FileExclusion"" ""*_BurstDebugInformation_DoNotShip""
""FileExclusion"" ""*_BackUpThisFolder_ButDontShipItWithYourGame""
}}
";
localVersion.Increment();
// [[ BUILD ]]
foreach (BuildConfiguration buildConfiguration in apps.SelectMany(app => app.depots)
.Select(depot => depot.buildConfiguration)
.Distinct()) {
BuildResult buildResult = buildConfiguration.Build();
buildResult.LogResult();
if (buildResult.Failed) {
localVersion.Decrement();
return;
}
}
// [[ DEPLOY ]]
{
string[] credentials = File.ReadAllLines($"{steamCmdFolder}/credentials.txt");
foreach (App app in apps) {
File.WriteAllText(AppFile(app), AppFileContents(app));
foreach (Depot depot in app.depots)
File.WriteAllText(DepotFile(depot), DepotFileContents(depot));
Process deployProcess = new() {
StartInfo = new ProcessStartInfo {
FileName = @$"{folder}/cmd/steamcmd.exe",
Arguments = $"+login {credentials[0]} {credentials[1]} +run_app_build {AppFile(app)} +quit",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
}
};
try {
EditorUtility.DisplayProgressBar("Deploying", "...", 1);
deployProcess.Start();
StringBuilder logs = new();
while (true) {
string stdOut = deployProcess.StandardOutput.ReadLine();
if (stdOut == null) break;
logs.AppendLine(stdOut);
EditorUtility.DisplayProgressBar("Deploying", stdOut, 1);
}
Debug.Log(logs);
deployProcess.WaitForExit();
} finally {
EditorUtility.ClearProgressBar();
}
}
}
}
[Serializable]
public struct Depot {
public BuildConfiguration buildConfiguration;
public ulong depotId;
}
[Serializable]
public struct App {
public ulong appId;
public Depot[] depots;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment