Every release build since the packaging pipeline landed has failed at "Compile the installer", which is why the last eight versions are still unpublished drafts:
Error on line 63 in msime_setup.iss: Couldn't open include file
"c:\program files (x86)\inno setup 6\Languages\ChineseSimplified.isl"
install-inno-language.ps1 derived the destination from `Get-Command ISCC.exe`. On the windows-2025 image Inno Setup comes from Chocolatey, so that resolves to the shim at C:\ProgramData\Chocolatey\bin\ISCC.exe and the file was written to C:\ProgramData\Chocolatey\bin\Languages\. ISPP resolves compiler: against the real installation. The step printed "Installed ... (21516 bytes)" and exited 0, and the build failed two steps later pointing at a path nothing had written to, which is why this survived eight releases.
The installation is now located by a file only it has -- ISPPBuiltins.iss or Default.isl, neither of which sits beside a shim -- checking the uninstall registry key, the two Program Files locations and any ISCC.exe on PATH, and failing with the list it tried rather than falling back to a guess.
ci.yml now compiles a throwaway script whose only content is a [Languages] entry pointing at compiler:Languages\ChineseSimplified.isl. Asserting the file exists at a path this script computed would only restate the script's own belief; compiling is what proves ISCC agrees. The URL and digest pin moved into the script so that check does not need a second copy of them.
release.yml had grown thirteen inline shell and PowerShell blocks, some of them twenty lines, which made the workflow hard to read and impossible to lint or run outside Actions. Each one is now a file under scripts/ci and the workflow only wires them up.
Two things fall out of the move rather than being separate changes. The two signing steps were near-duplicates and are now one sign-binaries.ps1 taking a path list, used for both the packaged binaries and the finished installer. The pinned Inno Setup language file URL and checksum move to the packaging job's env, where they read as configuration instead of being buried mid-script.
The Server job now checks this repository out into automation/ for its two scripts. That checkout has to come after the MSIME-Server one, because checkout cleans its destination and the workspace root would take automation/ with it.
shellcheck is clean on all six shell scripts. The PowerShell is not syntax-checked here for lack of pwsh, but four of the seven are verbatim from steps that already ran green in run 33953797415.