Build Services
Build services run during the build lifecycle to handle submodule initialization, caching, LFS configuration, and git hooks. They work with any provider - local, AWS, Kubernetes, GCP Cloud Run, Azure ACI, or custom CLI providers.
Submodule Profiles
Selectively initialize submodules from a YAML profile instead of cloning everything. Useful for monorepos where builds only need a subset of submodules.
Profile Format
primary_submodule: MyGameFramework
submodules:
- name: CoreFramework
branch: main # initialize this submodule
- name: OptionalModule
branch: empty # skip this submodule (empty branch)
- name: Plugins* # glob pattern - matches PluginsCore, PluginsAudio, etc.
branch: main
branch: main- initialize the submodule on its configured branchbranch: empty- skip the submodule (checked out to an empty branch)- Trailing
*enables glob matching against submodule names
Variant Overlays
A variant file merges on top of the base profile for build-type or platform-specific overrides:
# server-variant.yml
submodules:
- name: ClientOnlyAssets
branch: empty # skip client assets for server builds
- name: ServerTools
branch: main # add server-only tools
Inputs
| Input | Default | Description |
|---|---|---|
submoduleProfilePath | - | Path to YAML submodule profile |
submoduleVariantPath | - | Path to variant overlay (merged on top) |
submoduleToken | - | Auth token for private submodule clones |
How It Works
- Parses the profile YAML and optional variant overlay
- Reads
.gitmodulesto discover all submodules - Matches each submodule against profile entries (exact name or glob)
- Initializes matched submodules; skips the rest
- If
submoduleTokenis set, configures git URL rewriting for auth
Example
- uses: game-ci/unity-builder@v4
with:
providerStrategy: local
submoduleProfilePath: config/submodule-profiles/game/client/profile.yml
submoduleVariantPath: config/submodule-profiles/game/client/server.yml
submoduleToken: ${{ secrets.SUBMODULE_TOKEN }}
targetPlatform: StandaloneLinux64
Local Build Caching
Cache the Unity Library folder and LFS objects between local builds without external cache actions. Filesystem-based - works on self-hosted runners with persistent storage.
How It Works
- Cache key:
{platform}-{version}-{branch}(sanitized) - Cache root:
localCacheRoot>$RUNNER_TEMP/game-ci-cache>.game-ci/cache - Restore: extracts
library-{key}.tar/lfs-{key}.tarif they exist - Save: creates tar archives of the Library and LFS folders after the build
- Garbage collection: removes cache entries that haven't been accessed recently
Inputs
| Input | Default | Description |
|---|---|---|
localCacheEnabled | false | Enable filesystem caching |
localCacheRoot | - | Cache directory override |
localCacheLibrary | true | Cache Unity Library folder |
localCacheLfs | true | Cache LFS objects |
Example
- uses: game-ci/unity-builder@v4
with:
providerStrategy: local
localCacheEnabled: true
localCacheRoot: /mnt/cache # persistent disk on self-hosted runner
targetPlatform: StandaloneLinux64
Custom LFS Transfer Agents
Register external Git LFS transfer agents that handle LFS object storage via custom backends like elastic-git-storage, S3-backed agents, or any custom transfer protocol.
How It Works
Configures git to use a custom transfer agent:
git config lfs.customtransfer.{name}.path <executable>
git config lfs.customtransfer.{name}.args <args>
git config lfs.standalonetransferagent {name}
The agent name is derived from the executable filename (e.g. elastic-git-storage from
./tools/elastic-git-storage).
Inputs
| Input | Default | Description |
|---|---|---|
lfsTransferAgent | - | Path to custom LFS agent executable |
lfsTransferAgentArgs | - | Arguments passed to the agent |
lfsStoragePaths | - | Sets LFS_STORAGE_PATHS environment variable |
Example
- uses: game-ci/unity-builder@v4
with:
providerStrategy: local
lfsTransferAgent: ./tools/elastic-git-storage
lfsTransferAgentArgs: --config ./lfs-config.yml
lfsStoragePaths: /mnt/lfs-cache
targetPlatform: StandaloneLinux64
Git Hooks
Detect and install lefthook or husky during builds. Disabled by default for build performance - enable when your build pipeline depends on hooks running.
How It Works
- Detect: looks for
lefthook.yml/.lefthook.yml(lefthook) or.husky/directory (husky) - If enabled: runs
npx lefthook installor sets up husky - If disabled (default): sets
core.hooksPathto an empty directory to bypass all hooks - Skip list: specific hooks can be skipped via environment variables:
- Lefthook:
LEFTHOOK_EXCLUDE=pre-commit,prepare-commit-msg - Husky:
HUSKY=0disables all hooks
- Lefthook:
Inputs
| Input | Default | Description |
|---|---|---|
gitHooksEnabled | false | Install and run git hooks during build |
gitHooksSkipList | - | Comma-separated hooks to skip |
Example
# Enable hooks but skip pre-commit
- uses: game-ci/unity-builder@v4
with:
providerStrategy: local
gitHooksEnabled: true
gitHooksSkipList: pre-commit,prepare-commit-msg
targetPlatform: StandaloneLinux64
Related
- CLI Provider Protocol - Write providers in any language
- Cloud Providers - GCP Cloud Run and Azure ACI
- Caching - Orchestrator caching strategies