Repository navigation
No CI job transpiles to Lua, so a core change that breaks the Factorio build passes fully green #53
Description
What happens
The job named test-lua does not transpile anything. .github/workflows/ci.yml:53-80 runs checkout, setup-dotnet, dotnet workload restore, dotnet restore, and then:
- run: dotnet build --configuration Debug /p:UseLuaSettings=true
- run: dotnet build --configuration Release /p:UseLuaSettings=true
- run: dotnet test --no-build --configuration Release ...UseLuaSettings=true resolves in Directory.Build.props:7-18 to ten MSBuild properties (UseHashSets=false, UseBitArray=false, LocationAsStruct=false, and so on) that feed DefineConstants. It is a C# #if configuration, nothing more. It selects the Lua-compatible code paths; it never runs CSharp.lua.
Checked across the whole workflow directory: no job invokes src/lua/Invoke-LuaBuild.ps1, no job builds the CSharp.lua launcher, and no Lua interpreter runs anywhere. deploy-cloudflare.yml publishes BrowserWasm and the Vue dist, so it does not either.
And nothing verifies the committed output. grep -rn "src/lua\|\.lua" test/ --include=*.cs returns nothing - there is no round-trip check, no freshness gate on the 22.9k committed Lua lines, and no syntax check. CLAUDE.md:103 documents luac5.2 -p as a manual fish loop.
Why it matters more than "the transpile might break"
The obvious failure - someone reintroduces a construct CLAUDE.md:101 bans (LINQ, yield return, named tuples, try/catch, struct dictionary keys) - would be caught by a transpile step. There isn't one, so it lands green.
But LINQ specifically is worse than a transpile error, and this is the part worth knowing. CSharp.lua can transpile it - submodules/CSharp.lua/CSharp.lua/CoreSystem.Lua/CoreSystem/Collections/Linq.lua exists. What ships is the problem: src/lua/CoreSystem.lua:6-27 does not load("Collections.Linq"), and Invoke-LuaBuild.ps1:32-33 copies only the modules named in that load list. So src/lua/CoreSystem/Collections/ contains exactly:
Dictionary.lua EqualityComparer.lua HashSet.lua
List.lua PriorityQueue.lua Queue.lua
No Linq.lua. LINQ in the core would transpile cleanly, then emit Lua that calls a runtime module which was never shipped - a runtime failure inside Factorio, at whatever point the mod first hits that code path. Later and much harder to diagnose than a build error, and CI catches neither.
Worth noting CLAUDE.md:101 frames the LINQ ban as a performance rule. The shipping consequence is stronger than that, and the doc could say so.
How to verify
grep -niE "lua|pwsh|powershell|luac" .github/workflows/*.yml # only the job name and the two flags
ls src/lua/CoreSystem/Collections/ # no Linq.lua
grep -rn "src/lua\|\.lua" test/ --include=*.cs # nothingOptions
- Add a transpile step to CI. Run
Invoke-LuaBuild.ps1and fail if it errors. Catches banned constructs at the point they are introduced. Cost: PowerShell plus the submodules on the runner. - Also diff the output against the committed
src/lua. Turns the 22.9k committed lines into a verified artifact rather than a trusted one, and makes a stale checkout visible. Stricter, and would need the generated output to be deterministic. - Syntax-check only - run
luac5.2 -poversrc/lua/**in CI. Cheapest, but only validates the committed output, so it would not catch a C# change that was never re-transpiled. - Ship
Linq.luaby adding it to theCoreSystem.luaload list, so LINQ degrades to a performance regression rather than a runtime crash. Note this cuts against the perf rationale for banning it, so it is probably the wrong trade - included for completeness.
Option 1 closes the largest gap for the least work. Renaming the test-lua job would help too: it currently reads as though Lua is covered.
Scope
.github/workflows/ci.yml predates the fork, so upstream likely has the same gap. Whether joelverhagen/FactorioTools wants the same change is a separate question - filing here since this is where the CI runs.
Provenance
Found while testing a refactoring skill against this repo; verified read-only. The Linq.lua shipping detail was checked against both the submodule and src/lua/.
Activity
Fail CI when the committed swagger.json or TS client has drifted (#69)