Commit Graph
40 Commits
Author SHA1 Message Date
Evan Hu c3fcc4a515 refactor(product): consume the consolidated Engine data and shared voice capture
Ports metasequoiaime/MSIME-Windows#153 onto the consolidated repository. That pull request was written against the six-repository layout: it edited product-ci.yml, which no longer exists, and re-pinned Server, UiHtml and Installer, which are directories now.

Three of its pinned commits had not reached this repository at all. The consolidation took each source repository at its main, and Server, UiHtml and Installer each landed two more commits afterwards, so dropping the pins as merely obsolete would have silently dropped the work the pull request exists to consume. The two substantive ones are ported here: Server drops its vendored miniaudio.h and builds against the engine's MetasequoiaIme::VoiceCapture, and the installer collects helpcodes from the engine. UiHtml's was an engine gitlink bump, which one submodule resolves on its own.

The engine is pinned to d0dc0c2b rather than to the b7c799ef that pull request named. b7c799ef predates 403b4a4d, which is what this repository pins today and is the commit that added pagination to the settings dictionary contract, so taking the pull request's pin verbatim would have reverted a contract main already depends on and stripped offset, limit and hasMore back out of the generated web bindings. d0dc0c2b is the engine's main and is the same commit the dictionary release declares as its source, so the code and the data now name one commit.

The helpcodes moved into the engine, so MSIME-HelpCode stops being a product input: the gitlink that pins the contracts pins the tables too. product-lock.json is down to the engine and the dictionary release, and the dictionary itself now ships from MSIME-Engine. Its manifest states which commit built the data and whether that tree was clean, and the lock verifies both, so matching digests can no longer stand in for a source nobody can rebuild from. The retired MSIME-Dict repository stays valid for the one tag that shipped from it and nothing else.

The release job that packages now checks out submodules, because the helpcodes it collects live in one.
2026-09-06 04:13:04 +09:00
Evan Hu b48dc82652 fix(ci): resolve the pipe probe contracts from the repository, not the server
The probe took its include directory from $ServerRoot/MetasequoiaImeEngine/contracts, which is where the engine sat when it was a submodule of Server. It is a submodule of the repository now, so the path does not move with -ServerRoot. A missing include directory is not a configure error, so this surfaced minutes later as C1083 on a header nobody had moved; the script now checks and says so before building.

The local packaging rehearsals had the same stale assumption, looking for MetasequoiaImeTsf, MetasequoiaImeServer and MetasequoiaImeUiHtml beside the installer. Worse, they skipped the build when a neighbour was absent, which in this layout means every build is skipped and whatever binaries are lying around get packaged into an installer you then run on your own machine. The three components are directories of this repository, so a missing one is now a hard failure, and Prepare-PackageFiles.ps1 is passed the directory names it needs.

Both were missed because the sweep that moved the submodules read its own output through head, so a truncated list looked like a complete one. Re-checked by resolving every relative path literal in every tracked file with no filtering.
2026-09-06 03:28:13 +09:00
Evan Hu 6bb0c1e10e fix(ci): check out the engine submodule in the product inputs job
check-dictionary-contract.py compares scripts/dictionary_product.py against the engine's own copy, so the job needs the submodule's contents and not just its gitlink. The reusable workflow this job replaced checked out submodules; the rewrite dropped that.

The script reported a missing file as "differs from the pinned Engine contract", which describes a drift that had not happened and sends the reader looking for a content change. It now says the file is missing and how to get it.
2026-09-06 02:51:08 +09:00
Evan Hu 32e722c176 ci: build every component from the one checkout
The product lock existed because five repositories had to be pinned to reproduce one product. Four of them are directories now, so a commit of this repository already pins them and there is nothing left for the lock to say about them. What it still records is what the product consumes from outside: the engine submodule, the helpcodes and the dictionary release.

CI gains a job per component instead of a reusable workflow that checked out locked commits and rebuilt them. The release workflow no longer stages five sibling checkouts under historical names and no longer carries a second sparse checkout for its own scripts; Prepare-PackageFiles.ps1 already took the source directory names as parameters, so it is told the new ones, plus where the product-wide notice now lives.

Two checks the removed cross-repository pins used to provide are replaced in kind: the pages are verified against the engine submodule's web contract in CI rather than by locking UiHtml and Engine together, and the engine bump triage that Server carried moves here and now also says so when a bump leaves the lock behind.
2026-09-06 02:35:49 +09:00
Evan Hu 253b068984 refactor: move the Windows TSF frontend under windows/
Preparation for folding Server, UI, UiHtml, Installer, ImeLog and TsfEditControl into this repository. The Windows tip's own sources, build files and local build scripts move under windows/ so every component sits at the same level. Product-level files stay at the root: the lock, the release manifest, the shared CI scripts, the integration tests, the docs and the Engine submodule.
2026-09-06 02:24:27 +09:00
Evan e08f434e31 Merge pull request #148 from metasequoiaime/architecture/product-contracts
feat(product): validate and lock the shared-session release combination
2026-09-06 01:54:16 +09:00
Evan Hu 831b828d00 refactor(ci): move the Inno Setup language check into scripts/ci
Every other piece of shell in these workflows lives in scripts/ci and the workflow only wires it up. The language probe went in inline, so it did not: twenty lines of PowerShell building an .iss heredoc inside a YAML block scalar, which is the least reviewable and least runnable place to put it.

Same check, now in check-inno-language.ps1, and runnable by hand on a Windows machine. It falls back to the system temp directory when RUNNER_TEMP is unset so that running it outside CI works.
2026-09-06 01:37:20 +09:00
Evan Hu 7c6dc8b6a0 fix(release): install the Inno Setup language file where ISCC looks
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.
2026-09-06 01:37:13 +09:00
Evan Hu 1c6c956530 feat(product): lock the shared-session stack and validate dictionary formats 2026-09-06 00:53:26 +09:00
Evan Hu 2a15c6a4ad ci(release): only build and sign on an explicit dispatch
The signing certificate allows a limited number of signatures, so a release costs something finite. It should not be spent by merging a pull request.

Until now a push to main was enough to spend one: release-please opened the release pull request, merge-release-pr.sh merged it, the merge commit came back through this workflow as release_created, and the build jobs signed two binaries and an installer and published the result. Nobody had to ask for any of that.

should_publish is now true only for workflow_dispatch, and the package job -- the only one that signs -- states that condition itself rather than inheriting it from four other jobs whose conditions a later edit could quietly change.

Auto-merging the release pull request goes with it, since that is the mechanism that turned a merge into a release, and leaving it would also mint a draft release and a tag on every merge to main that nobody intends to build. What remains automatic is getting a passing check onto that pull request, which is not optional: GITHUB_TOKEN cannot start a workflow run, so without the dispatch in check-release-pr.sh the release pull request has no checks at all and required_status_checks (#121) leaves it permanently unmergeable.

Releasing is now two deliberate steps. Merge the release pull request, which creates the draft release and its tag and builds nothing. Then run the Release workflow against that tag. Dispatching the same tag twice is already refused by validate-draft-release.sh, because a published release is no longer a draft, so a retry cannot quietly spend a second signature.
2026-09-06 00:48:51 +09:00
Evan Hu a81bc47c71 feat(product): require locked commits to be on their default branch at release
The lock pins immutable commits, but nothing checked that anybody merged them. Today it pins server 40d85a4 and engine 9a4b0c6, both of which exist only on architecture/product-contracts branches, and a release built from this commit would have shipped and attested to a Server that never reached main. The release job's existing provenance check covers only the TSF commit being released, not the inputs the lock names.

verify-published compares each locked commit against its own repository's default branch and accepts only behind or identical, the two states that mean it is an ancestor. ahead and diverged both mean the commit sits on something nobody merged.

It runs in the release path and deliberately not in product-ci.yml. A pull request legitimately locks branch commits while one change lands across several repositories at once, which is exactly the situation this branch is in; enforcing reachability in pull request CI would deadlock the landing it exists to protect. At release time the judgement inverts, because an input that never reached its default branch is an input nobody reviewed.
2026-09-05 23:18:03 +09:00
Evan Hu 9b2844534e feat(product): keep WebView and native contracts in one locked combination 2026-09-05 23:10:29 +09:00
Evan Hu 1c045f1738 test(ipc): exercise real Server handshakes from x86 and x64 clients 2026-09-05 22:41:45 +09:00
Evan Hu 487011c802 feat(product): lock release inputs and share negotiated IPC contracts 2026-09-05 22:32:21 +09:00
Evan Hu 550e0a1c70 fix(ci): find the release pull request by branch, not by prs_created
The step ran only when release-please reported a pull request as created, which is once. It rewrites
that branch on every later push to main, and a release pull request that could not be merged the
first time is never retried -- main advancing during the build is the normal way that happens, and
the script deliberately leaves the pull request open in that case, so the two together meant it
would sit there forever.

Finding the branch through git/matching-refs and then its open pull request covers both: a rewritten
head gets a fresh build, and a pull request left open gets picked up on the next push. Taken from
MSIME-Linux#38, which caught the same mistake in the equivalent change there.
2026-09-05 21:58:56 +09:00
Evan 8e96da945c Merge pull request #135 from metasequoiaime/ci/test-release-pr
ci: build the release pull request before merging it
2026-09-05 21:52:58 +09:00
Evan Hu b02e4c8cc9 ci: build the release pull request before merging it
MSIME-Windows#121 records that CI cannot be made a required check here, because release-please's
pull request never gets one: GITHUB_TOKEN may not start workflows, so the pull_request run is
created in action_required and waits for a human forever.

I previously wrote on that issue that the only way out was a GitHub App or PAT. That was wrong.
workflow_dispatch is the exception GitHub allows GITHUB_TOKEN to fire, and MSIME-Apple's release
automation has been relying on it all along. Checked its release branch: workflow_dispatch runs
exist there and succeed, alongside pull_request runs that do not.

Also checked the two alternatives that looked cheaper, and neither works:

  - A push trigger on release-please--** produces nothing. Every run on that branch in MSIME-Linux
    is a pull_request event; a GITHUB_TOKEN push creates no run at all. MSIME-Linux#31 merged on
    the belief that it does.
  - The approval policy is not the cause. All six repositories are already on
    first_time_contributors_new_to_github, the loosest setting, and bot-triggered runs are still
    gated. Comparing runs, the gate tracks triggering_actor exactly: github-actions[bot] gives
    action_required, houko gives success.

So merge-release-pr.sh now dispatches ci.yml on the release branch, polls for the run at that exact
head commit, and waits for it with --exit-status before merging. The checks land on the pull
request's head commit, which is what required_status_checks needs.

It also re-reads main and the pull request head afterwards: main can advance during a build, and
merging then would rebase the release commit onto something that was never tested.

ci.yml gains workflow_dispatch so it can be dispatched at all. The paths-ignore stays: it keeps the
unapprovable pull_request run out of the checks list, leaving only the dispatched run's results,
which avoids two check runs with the same name and different outcomes on one commit.

The prepare job gains actions: write, without which gh workflow run cannot dispatch.
2026-09-05 21:41:40 +09:00
Evan Hu 0ce7e1f5b9 chore(scripts): drop the unused boost_path variable
prepare_env.py 里 boost_path 定义后从未被引用,Bug 汇总 #95 第一节也指出该顺手删掉。

这一处来自 PathGao 在 #97 中的改动。#97 的另一半(prepare_env.py 读取 VCPKG_ROOT)
与后来合入的 #117 重复,本仓这边没有先核对 open PR,重复劳动的责任在我们;
这里把该 PR 中尚未被覆盖的部分单独取出合入。
2026-09-05 21:33:25 +09:00
Evan Hu d59be91390 refactor(ci): move every release shell step into scripts/ci
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.
2026-09-05 17:19:51 +09:00
Evan a7a3fc42b5 revert: leave the unused boost_path alone 2026-09-05 16:54:15 +09:00
Evan f9e52d98a8 fix(scripts): read vcpkg and boost roots from the environment 2026-09-05 16:53:49 +09:00
Evan Hu 03b3f5f45a ci: build and publish the installer from a release workflow
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.
2026-09-05 16:10:33 +09:00
fanlusky 8e825920c5 Add inline preedit in-time ars result support for voice input. 2026-08-17 00:56:22 +08:00
fanlusky b5ded50274 Add English input mode. 2026-08-01 23:11:02 +08:00
fanlusky c17e6a1070 Fix host-process crashes (notably QQ) on text commit.
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.
2026-07-22 10:40:20 +08:00
fanlusky 66110ade2a Continue cleaning up some unused codes. 2026-06-25 22:52:04 +08:00
fanlusky 2a6cc3dd3b Clean up some window-related codes. 2026-06-25 22:40:47 +08:00
fanlusky 502256e470 Remove unused codes. 2026-06-25 21:31:09 +08:00
fanlusky a36fd5e13b add compile release scripts 2026-04-02 18:24:39 +08:00
fanlumaster 6224292fd2 sign dll with certum certificate 2026-03-04 01:48:43 +08:00
fanlumaster eb104a9616 [config]: Update to VS2026 2025-12-29 21:55:53 +08:00
fanlumaster 29c4252042 squashed commits for create word feat 2025-10-25 12:44:29 +08:00
fanlumaster 3919be71e9 [Project]: Rename IME name again 2025-06-10 17:53:10 +08:00
fanlumaster 4483a6eb2c [Project]: Project name is ready 2025-06-10 16:04:39 +08:00
fanlumaster 4200ee8e93 [dependency]: Using vcpkg to install and use utfcpp 2025-06-06 22:26:01 +08:00
fanlumaster 495bd1fc52 [feat]: Do not embed preedit string to VSCode like apps 2025-06-06 16:38:25 +08:00
fanlumaster 20072b6e0c [docs]: Build steps 2025-06-01 00:52:01 +08:00
fanlumaster e22c57567b [env]: Scripts for generating project config 2025-06-01 00:24:42 +08:00
fanlumaster ace57e9531 [dev]: Refactor 2025-05-30 22:03:24 +08:00
fanlumaster f29d6ad681 minimal integration of direct2d and directwrite 2025-01-28 03:57:15 +08:00