Skip to content

liortal53/BuildMetadata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BuildMetadata

License: MIT

Installation

Install via the Unity Package Manager (UPM) using a Git URL pointing to the package subfolder in this repository.

  1. Open Window → Package Manager in Unity.
  2. Click the + button and choose Add package from git URL…
  3. Enter the following URL and click Add:
https://github.com/liortal53/BuildMetadata.git?path=Assets/BuildMetadata

The ?path=Assets/BuildMetadata suffix tells UPM to treat that subdirectory as the package root (where package.json lives), rather than the repository root.

To lock to a specific version, append a tag or commit SHA:

https://github.com/liortal53/BuildMetadata.git?path=Assets/BuildMetadata#1.0.0

Requirements

  • Unity 2021.2+ (Roslyn source generator support)
  • Git must be installed and on your system PATH

Motivation

A Unity build produces a binary that, once compiled, has no inherent memory of when or where it was built, which Git commit it came from, or what environment variables were set on the build machine. This information is invaluable for debugging ("which exact build is this?"), analytics, and CI/CD traceability — but it simply isn't available at runtime through normal Unity APIs.

BuildMetadata solves this by capturing that information at build time and baking it into the game, so it is always accessible at runtime without any manual steps. Version strings, Git branch and commit SHA, build timestamp, machine name, OS, scripting defines, and any custom environment-specific values are gathered the moment the build starts and written to a JSON file that ships with the game. At runtime a single static property gives you everything.

Overview

BuildMetadata hooks into the Unity build pipeline to record a snapshot before every build — version strings, Git branch/commit, timestamp, platform settings, and any custom fields you define. At runtime, your game loads this data from a single JSON file via a clean static API.

Custom fields are added by marking a class with [CustomBuildMetadata]. A Roslyn source generator folds the class's properties directly into BuildMetadataData at compile time. No separate JSON files, no boilerplate.

How It Works

  1. Unity build starts.
  2. BuildMetadataProcessor runs at preprocess, constructs a BuildMetadataData with core values.
  3. It discovers all [CustomBuildMetadata] classes via TypeCache, instantiates each, and uses reflection to set their generated backing fields on the same object.
  4. The unified object is serialized to Resources/Generated/BuildMetadata.json.
  5. At runtime, Build.Metadata deserializes lazily from that JSON.

The source generator (Roslyn) runs at C# compile time: it finds [CustomBuildMetadata] classes and emits a partial BuildMetadataData with the corresponding [SerializeField] backing fields and read-only properties. XML doc comments are forwarded to the generated properties.

Runtime Usage

using BuildMetadata;

var info = Build.Metadata;
Debug.Log($"v{info.AppVersion}  {info.GitSha1.Substring(0, 7)}  {info.BuildTimestamp}");

// Custom fields land directly on Build.Metadata
Debug.Log(info.CiPipelineId);

Adding Custom Fields

Create a class in the Runtime assembly (same assembly as BuildMetadataData):

[CustomBuildMetadata]
public class CIMetadata
{
    /// <summary>Pipeline ID from CI environment.</summary>
    public string CiPipelineId  => Environment.GetEnvironmentVariable("CI_PIPELINE_ID") ?? "local";

    public string CiTriggeredBy => Environment.GetEnvironmentVariable("CI_TRIGGERER")   ?? "unknown";
    public bool   CiIsAutomated => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI"));
}

After Unity recompiles, Build.Metadata.CiPipelineId, Build.Metadata.CiTriggeredBy, and Build.Metadata.CiIsAutomated are available.

Rebuilding the Generator

When BuildMetadata.Generator/CustomBuildMetadataGenerator.cs changes:

dotnet build BuildMetadata.Generator/ -c Release
cp BuildMetadata.Generator/bin/Release/netstandard2.0/BuildMetadata.Generator.dll \
   Assets/BuildMetadata/Runtime/Analyzers/BuildMetadata.Generator.dll

Then Assets → Refresh in Unity and regenerate project files via Edit → Preferences → External Tools → Regenerate project files.

Requirements

  • Unity 2021.2+ (Roslyn source generator support)
  • .NET SDK to rebuild the generator DLL
  • Git on PATH for branch / SHA capture

Constraints

  • [CustomBuildMetadata] classes must be in the Runtime assembly so the generator can emit the partial BuildMetadataData extension into the same compilation.
  • Only public instance properties with a getter are picked up — fields and static properties are ignored.
  • Property types must be Unity-serializable (string, int, bool, float, etc.).
  • BuildReport is not accessible inside [CustomBuildMetadata] classes; they are instantiated with no arguments.
  • Property names must be unique across all [CustomBuildMetadata] classes.

Project Structure

Assets/BuildMetadata/
├── Editor/
│   ├── BuildMetadataProcessor.cs         # IPreprocessBuildWithReport hook
│   ├── Utilities/
│   │   └── GitUtility.cs               # Git command runner
│   └── BuildMetadata.Editor.asmdef
└── Runtime/
    ├── BuildMetadataData.cs            # Partial, immutable data container
    ├── Build.cs                        # Static API: Build.Metadata
    ├── CustomBuildMetadataAttribute.cs # [CustomBuildMetadata] attribute
    ├── Analyzers/
    │   └── BuildMetadata.Generator.dll # Roslyn source generator
    └── BuildMetadata.Runtime.asmdef

BuildMetadata.Generator/               # Generator source (.NET Standard 2.0 project)
├── BuildMetadata.Generator.csproj
└── CustomBuildMetadataGenerator.cs

License

MIT — see LICENSE.

About

Inject custom metadata to Unity projects at build time

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages