Freezes the server into a single self-contained `mcp-windbg.exe` with
PyInstaller,
for users who want nothing to do with a Python toolchain. `cdb.exe`
stays a
prerequisite.
**What the build does.** `scripts/Build-Exe.ps1` builds it, `-Verify`
runs the
scenarios against it, and `MCP_WINDBG_SERVER_EXE` re-points the e2e
harness at a
built binary so the whole suite runs with the same assertions and a
different
launcher. A new `exe` job does both on every PR.
**Signed release asset.** The exe is signed and attached to each release
with a
`SHA256SUMS` taken from the signed binary, since signing rewrites the PE
and a
digest from before it would match nothing anyone can download. The
signature is
verified before the asset is attached.
**Identity.** Version resource generated from `pyproject.toml`, plus an
icon and a
`Comments` field stating the binary is signed by Liasoft GmbH, which
sponsors the
certificate. Windows shows the certificate subject as the verified
publisher, so
without that note the author and the signer read as two unrelated names.
**Why signing uses a self-hosted runner.** The signing service requires
one. Two
rules keep that safe on a public repository, and both must hold if the
job is ever
changed: it stays out of reach of `pull_request`, `pull_request_target`
and
`issue_comment`, which would run a fork's code on it, and it never
checks out the
repository. It declares `permissions: {}`, takes its endpoint from a
secret, and
waits for approval in a `signing` environment.
**Verified.** 29 scenarios pass against the binary (2 kernel skips, no
target).
Signing exercised end to end with a rehearsal run, which builds, signs
and
attaches while publishing nothing: `osslsigncode verify` reports
`Succeeded`,
signer `O=Liasoft GmbH`, RFC3161 countersigned.
**Not yet exercised.** Nothing launches the signed binary, so a
post-sign smoke
step is worth adding.
Out of scope: winget.