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.
The Windows installer has been produced by hand: build the TSF DLLs and the Server locally, build the settings page, copy dictionaries out of a developer checkout, then run the msime-installer scripts against a self-signed certificate. This automates that end to end, keeping the same artifact name the releases have always carried, MetasequoiaIME_Setup_v<version>.exe.
The workflow follows the shape of MSIME-Apple's release.yml. release-please owns version.txt and opens a release PR; merging it creates a draft release, which the publish path then builds and fills in. A manual dispatch can rebuild an existing draft tag, and validates that the tag matches version.txt at an immutable commit SHA before anything is built.
Four jobs feed the packaging job: the TSF DLLs for x64 and Win32, the Server Release build, and the settings page. msime-installer needs no changes because the packaging job stages each checkout under the historical directory name its scripts already address, so Prepare-PackageFiles.ps1 and Compile-Installer.ps1 run unmodified. windows-2025 ships Inno Setup 6.7.1, above the 6.6 the scripts require.
Dictionaries are not rebuilt here. They are downloaded from a dict-* release of metasequoiaime/MSIME-Dict and checked against its SHA256SUMS.txt, with the Mozc IPAdic / ICOT / Okinawa notice placed where Prepare-PackageFiles.ps1 expects so it reaches the installed product.
Signing follows the pattern MSIME-Apple uses: sign when the certificate secrets are configured, otherwise publish with an -unsigned suffix and say in the release notes that uiAccess will not take effect. Sign-PackageBinaries-Local.ps1 mints a self-signed certificate for local testing and is never invoked here.
release-please cannot drive the VERSIONINFO block in the resource script, which spells the version both as a comma quad and as a dotted string, so scripts/apply_version.py stamps it from version.txt before the release build configures CMake. It also has a --check mode. The committed resource moves off the stale 1.0.0.1 placeholder to the current 0.0.9.
The manifest starts at 0.0.9 rather than the four-part 0.0.9.2 that semver cannot express, so the next release will be 0.0.10, which still sorts after every existing tag.
Build the TSF tip with /MT so it no longer depends on the host's MSVCP140,
skip SetText(empty) in OnCompositionTerminated after normal EndComposition,
and guard SetText/EndComposition with SEH.