feat: CI-safe headless build entry point (NDream.Unity.Builder) - #161
Conversation
marc-n-dream
left a comment
There was a problem hiding this comment.
⚪ No Jira key on the branch (
feat/headless-build-entry), the title, or the body — reviewed on the PR body alone.
Head is unchanged at d010aaa3 since the last pass, so all five earlier findings stand as written and I haven't re-posted them. Second pass turned up one new one, inline: this file ships to customers, and it currently points them at a repo they don't have.
I did spend the pass hardening the blocker instead of restating it, and it holds in three independent places: PreBuildProcessing has callbackOrder 1 so it throws before ProjectConfigurationCheck (999) runs at all; Packager.RemoveControllersFromWebGlTemplates actively deletes controller.html at package time, so nothing ever puts it in git; and while ProjectConfigurationCheck.VerifyReferencedAirConsoleApiVersion does tolerate the missing file, PostBuildProcess.VerifyAPIUsage calls File.ReadAllText on the same path with no existence check. A clean agent cannot get a WebGL build out of this.
BuildWebGL/BuildAndroid are zero-arg static methods safe for Unity's -executeMethod. Unlike BuildHelper they do not auto-commit the git repo or open the built player, so they are safe for the cross-repo orchestrator and CI. Output name overridable via -CustomArgs "buildName=<name>". Project config checks and platform post-processing run automatically as build hooks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ShCMtnweyHuUEJQn2EH5d6
d010aaa to
e6b6c4a
Compare
- Switch the active build target explicitly in Run, since some pre-build hooks read EditorUserBuildSettings.activeBuildTarget rather than the target being built, and would otherwise persist settings for the wrong platform when -buildTarget is not passed. - Strip any directory component from a caller supplied buildName so it cannot escape the output directory, and reject "." / ".." outright. - Correct the docstring: the pre-build hooks do rewrite ProjectSettings.asset, so a build leaves a dirty tree. - Drop the reference to the internal airconsole-platform orchestrator path, which shipped to customers via the unitypackage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Builder.BuildWebGL could not succeed on a clean checkout: controller.html in the WebGL template directory is only ever produced by Extentions.OpenBrowser's copy, which fires only from Unity's playModeStateChanged event on entering Play Mode -- an interactive-editor event that never occurs in a batchmode build. PreBuildProcessing then throws before any build work happens. - Extentions.cs: extract the copy into TryCopyControllerHtmlToTemplate(AirConsole), reused by OpenBrowser (behavior unchanged) and by the new headless path. - Builder.cs: BuildWebGL now opens the first enabled build scene and regenerates controller.html from that scene's AirConsole.controllerHtml before building, throwing a BuildFailedException naming the scene if no AirConsole/controllerHtml is found. BuildAndroid is untouched. - Docstring updated to document the new WebGL-only step. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Why
create-release.yamlhas its build steps commented out and references aBuilderclass that doesnot exist. The existing
BuildHelperis not usable from CI: it auto-commits to git and callsShowBuiltPlayer, neither of which is acceptable on a build agent.What
NDream.Unity.Builder— a zero-argument headless build entry point suitable for-executeMethod. No git side effects, no player launch, non-zero exit on failure.Follow-up
Wiring
create-release.yamlto this entry point is deliberately not in this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01ShCMtnweyHuUEJQn2EH5d6