Summary
GitHubActionsRunStep.Write() emits run: ./{BuildCmdPath} <targets> for every job regardless of the runner image, and ConfigurationAttributeBase.BuildCmdPath only globs build.cmd (never build.sh/build.ps1). So any workflow generated for an Ubuntu*/MacOs* image gets ./build.cmd, which can't execute — only windows-* runners work.
Repro
[GitHubActions("ci", GitHubActionsImage.UbuntuLatest, InvokedTargets = [nameof(Foo)])]
generates:
runs-on: ubuntu-latest
...
run: ./build.cmd Foo # .cmd on ubuntu → fails
Cause (10.3.49)
Fallout.Common.CI.GitHubActions.Configuration.GitHubActionsRunStep.Write → " run: ./" + BuildCmdPath + " " + JoinSpace(InvokedTargets)
Fallout.Common.CI.ConfigurationAttributeBase.BuildCmdPath → globs build.cmd, */build.cmd only
No branch on GitHubActionsImage. Confirmed across both assemblies: zero references to build.sh or build.ps1; build.cmd is the only build-script string (2 glob literals in Fallout.Build). The build.sh/build.ps1 bootstrap files ship, but the generator only ever knows build.cmd.
Fix — pwsh route (decided)
pwsh is on every GitHub-hosted runner (win/linux/mac) and build.ps1 already takes targets positionally (ValueFromRemainingArguments), so invoke pwsh and drop per-OS script selection entirely:
ConfigurationAttributeBase — add a pwsh path mirroring BuildCmdPath:
protected virtual string BuildScriptPath =>
Build.RootDirectory.GlobFiles("build.ps1", "*/build.ps1")
.Select(x => Build.RootDirectory.GetUnixRelativePathTo(x))
.FirstOrDefault().NotNull();
GitHubActionsRunStep.Write — invoke pwsh:
writer.WriteLine(" run: pwsh -File ./" + BuildScriptPath + " " + JoinSpace(InvokedTargets));
(thread BuildScriptPath through the attribute's GetSteps where it currently passes BuildCmdPath.)
pwsh -File ./build.ps1 <targets> runs regardless of the runner's default shell — no shell: key, no image branch. Same swap applies to the other CI run-step writers if we want them pwsh too.
Workaround
Pin GitHubActionsImage.WindowsLatest (only image where the generated ./build.cmd runs).
Filed by AI (Claude Opus 4.8 (1M context)) on Chris's behalf.
Summary
GitHubActionsRunStep.Write()emitsrun: ./{BuildCmdPath} <targets>for every job regardless of the runner image, andConfigurationAttributeBase.BuildCmdPathonly globsbuild.cmd(neverbuild.sh/build.ps1). So any workflow generated for anUbuntu*/MacOs*image gets./build.cmd, which can't execute — onlywindows-*runners work.Repro
generates:
Cause (10.3.49)
Fallout.Common.CI.GitHubActions.Configuration.GitHubActionsRunStep.Write→" run: ./" + BuildCmdPath + " " + JoinSpace(InvokedTargets)Fallout.Common.CI.ConfigurationAttributeBase.BuildCmdPath→ globsbuild.cmd,*/build.cmdonlyNo branch on
GitHubActionsImage. Confirmed across both assemblies: zero references tobuild.shorbuild.ps1;build.cmdis the only build-script string (2 glob literals inFallout.Build). Thebuild.sh/build.ps1bootstrap files ship, but the generator only ever knowsbuild.cmd.Fix — pwsh route (decided)
pwshis on every GitHub-hosted runner (win/linux/mac) andbuild.ps1already takes targets positionally (ValueFromRemainingArguments), so invoke pwsh and drop per-OS script selection entirely:ConfigurationAttributeBase— add a pwsh path mirroringBuildCmdPath:GitHubActionsRunStep.Write— invoke pwsh:BuildScriptPaththrough the attribute'sGetStepswhere it currently passesBuildCmdPath.)pwsh -File ./build.ps1 <targets>runs regardless of the runner's default shell — noshell:key, no image branch. Same swap applies to the other CI run-step writers if we want them pwsh too.Workaround
Pin
GitHubActionsImage.WindowsLatest(only image where the generated./build.cmdruns).Filed by AI (Claude Opus 4.8 (1M context)) on Chris's behalf.