Skip to content

Instantly share code, notes, and snippets.

@sim2kid
Last active November 20, 2021 13:42
Show Gist options
  • Save sim2kid/7fa28b8d19bbcf705e55f202fe8789ac to your computer and use it in GitHub Desktop.
Save sim2kid/7fa28b8d19bbcf705e55f202fe8789ac to your computer and use it in GitHub Desktop.
Set Unity Version to GitHub Tag + Number of Commits. Keep this in an editor only folder. Shit+b to enduce in editor. Should run often enough to keep your build up-to-date
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using System.Diagnostics;
using System.Text;
using System.IO;
// Will run the script whenever the editor loads
[InitializeOnLoad]
public class SetVersion: IPreprocessBuildWithReport
{
public int callbackOrder => -5000;
public void OnPreprocessBuild(BuildReport report)
{
Version();
}
static SetVersion()
{
Version();
}
/// <summary>
/// Version is selected from last tag following the "v0" format.
/// Itll take the number of commits and tag it on the end so that "v1.5" with 26 commits will become "v1.5.26"
/// </summary>
[MenuItem("PreBuild/Set Version From Git #b")]
public static void Version()
{
try
{
// Get Root Folder for Git
string gitRepository = GetRootFolder();
// Get Git Version Number
string newVersion = GitTagVersion(gitRepository);
if (Application.version == newVersion)
return;
// Get Project Version File
string filePath = GetProjectFileName();
// Replace project version without messing up the rest of the file
ReplaceVersionInEditor(filePath, newVersion);
Debug.Log($"New Build Version: v{newVersion}");
}
catch (System.Exception e)
{
Debug.LogError($"Could not get new version. Version will not be updated. \n" + e);
}
}
private static void ReplaceVersionInEditor(string filePath, string newVersion)
{
string yaml = File.ReadAllText(filePath);
yaml = yaml.Replace($"bundleVersion: {Application.version}", $"bundleVersion: {newVersion}");
File.WriteAllText(filePath, yaml);
}
private static string GitTagVersion(string repository)
{
string version = RunGit(@"describe --tags --long --match ""v[0-9]*""", repository);
version = version.Replace('-', '.');
version = version.Substring(1, version.LastIndexOf('.') - 1);
return version;
}
public static string RunGit(string arguments, string path)
{
using (var process = new System.Diagnostics.Process())
{
int exitCode = process.Run("git", arguments, path,
out string output, out string errors);
if (exitCode == 0)
return output;
else
throw new System.Exception($"Git Exit Code: {exitCode} - {errors}");
}
}
private static string GetRootFolder()
{
string path = SanitizePath(Application.dataPath);
path = Path.Combine(Application.dataPath, SanitizePath("../"));
path = Path.GetFullPath(path);
return path;
}
private static string GetProjectFileName()
{
string path = GetRootFolder();
path = Path.Combine(path, SanitizePath("ProjectSettings/ProjectSettings.asset"));
path = Path.GetFullPath(path);
return path;
}
private static string SanitizePath(string s)
{
return s.Replace('/', '\\');
}
}
public static class ProcessExtensions
{
/// <summary>
/// Runs the specified process and waits for it to exit. Its output and errors are
/// returned as well as the exit code from the process.
/// See: https://stackoverflow.com/questions/4291912/process-start-how-to-get-the-output
/// Note that if any deadlocks occur, read the above thread (cubrman's response).
/// </summary>
/// <remarks>
/// This should be run from a using block and disposed after use. It won't
/// work properly to keep it around.
/// </remarks>
public static int Run(this Process process, string application,
string arguments, string workingDirectory, out string output,
out string errors)
{
process.StartInfo = new ProcessStartInfo
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
FileName = application,
Arguments = arguments,
WorkingDirectory = workingDirectory
};
// Use the following event to read both output and errors output.
var outputBuilder = new StringBuilder();
var errorsBuilder = new StringBuilder();
process.OutputDataReceived += (_, args) => outputBuilder.AppendLine(args.Data);
process.ErrorDataReceived += (_, args) => errorsBuilder.AppendLine(args.Data);
// Start the process and wait for it to exit.
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
output = outputBuilder.ToString().TrimEnd();
errors = errorsBuilder.ToString().TrimEnd();
return process.ExitCode;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment