| id | 234 |
|---|---|
| title | Distribute mdsmith on Windows via Scoop and WinGet |
| status | ✅ |
| summary | Publish the prebuilt `mdsmith-windows-amd64.exe` through a Scoop bucket and a WinGet manifest, mirroring the Homebrew tap and asdf plugin: a checksum-verified binary install bumped on each release. Adds two release-channel docs (so the install picker and table gain the rows automatically), two best-effort release-workflow jobs, and the dispatch tokens plus rotation entries they need. |
| model | sonnet |
| depends-on |
Give Windows users a one-line package-manager install:
scoop install mdsmith or winget install jeduden.mdsmith.
Both serve the same checksum-verified release .exe as the
manual download.
Today Windows has only the direct .exe download (see the
Windows section of the
install guide). There is no
package-manager channel, so every Windows install is a
manual download-and-PATH step.
Plan 130 shipped npm, PyPI, and the VS Code marketplaces and left the OS package managers — Scoop and Chocolatey among them — out of scope as follow-ups. Peer linters already publish to Windows repositories (mise ships via WinGet, Scoop, and Chocolatey), so this is a known gap, not a new direction.
The pattern to copy already exists in the repo. The
Homebrew tap
and the asdf plugin
are both pull channels that install the prebuilt binary,
verify it against the release checksums.txt, and are
bumped on each release by a best-effort dispatch job in
release.yml plus a
scheduled self-bump. Scoop and WinGet slot into that same
shape.
A new jeduden/scoop-mdsmith bucket repo holds a
bucket/mdsmith.json manifest. It pins the version, the
release .exe url, and its SHA-256 hash (from
checksums.txt). bin: mdsmith.exe exposes the command.
checkver and autoupdate blocks let the bucket self-bump.
- Install:
scoop bucket add mdsmith https://github.com/jeduden/scoop-mdsmiththenscoop install mdsmith. - Release glue: a
notify-scoop-bucketjob inrelease.ymlmirrors the existingnotify-homebrew-tapjob — it fires arepository_dispatchat the bucket with a fine-grained PAT (Contents: writeon the bucket). It is best-effort: the bucket self-bumps daily viacheckver, so a missing token or failed dispatch never blocks a release. - Channel doc:
docs/development/release-channels/scoop.md,mechanism: pull,platforms: [windows].
A jeduden.mdsmith manifest is submitted to
microsoft/winget-pkgs by a release job. komac
builds the manifest from the release's Windows
binary URL and opens the PR. It computes the
SHA-256 itself. The first version is bootstrapped
by hand with
mdsmith-release render-winget-manifest. That
mirrors render-scoop-manifest for the Scoop
bucket.
The asset is a bare CLI binary, not an installer, so
the manifest declares InstallerType: portable with
PortableCommandAlias: mdsmith. WinGet then stores
the binary and links it onto PATH as mdsmith. An
exe type with Silent: /S would instead make WinGet
run mdsmith-windows-amd64.exe /S, which the linter
rejects as a bad argument — nothing would install.
- Install:
winget install jeduden.mdsmith. The short form works only after the manifest lands and Microsoft moderation merges the PR; until then the GitHub release.exeis the documented fallback, the same way the asdf and mise docs caveat their short forms. - Release glue: a best-effort
winget-submitjob gated on thereleaseenvironment, using aWINGET_PR_TOKENPAT that can forkwinget-pkgsand open a PR. A missing token skips the job and never fails the release. - Channel doc:
docs/development/release-channels/winget.md,command: winget install jeduden.mdsmith,platforms: [windows],unlisted: true. The flag keeps WinGet out of the install picker and table until the manifest PR merges, since nothing installs through WinGet before then; the doc and tooling stay.
Per the
release-tooling rule,
workflow logic lives in the mdsmith-release Go CLI, not
inline shell. Add render-scoop-manifest and
render-winget-manifest subcommands. Each takes the version
and checksums.txt and emits one manifest. Unit-test the
version, URL, and hash substitution red/green.
Both channel docs feed channels.yaml through
sync-channels. The picker and the install table gain the
Scoop row with no manual edit. WinGet's doc carries
unlisted: true, so sync-channels drops it from the
picker and the install-table catalog excludes it by glob —
it stays out of both until the manifest PR merges.
Both are CLI binary-download channels. They
should sort among the CLI channels (Homebrew 7, asdf 9,
GitHub Releases 10), ahead of the higher-weighted ones.
Weights only need to be >= 1 and sort ascending; they need
not be unique or contiguous. So give Scoop and WinGet weights
just above GitHub Releases. Bump the channels now at 11–14
(the two marketplaces, Flatpak, and Obsidian) to make room,
or let weights tie — the stable sort keeps ties in file
order.
Update the Windows section of the
install guide. Replace the
"no package-manager channel yet" lead with the Scoop
one-liner. Keep the manual .exe download as the offline
or air-gapped path. The WinGet one-liner is added back
when the manifest PR merges and unlisted is dropped.
Two new tokens need rotation tracking in
secret-rotations.
They are SCOOP_BUCKET_DISPATCH_TOKEN (a plain repo secret,
like the existing tap dispatch token) and WINGET_PR_TOKEN.
Add a file per secret under secret-rotations/. The
scheduled 30-day reminder then covers both.
Chocolatey is deferred. It needs a chocolatey.org account,
an API key (another rotated secret), and a moderation queue
— more friction than Scoop or WinGet, and not required for
default-Windows reach (WinGet ships with Windows 11).
- Add
mdsmith-release render-scoop-manifestwith unit tests (version, URL, and SHA-256 fromchecksums.txt). - Create the
jeduden/scoop-mdsmithbucket repo with the manifest,checkver, andautoupdate. (external — repo now available) - Add the
notify-scoop-bucketjob andSCOOP_BUCKET_DISPATCH_TOKEN; document its rotation. - Add
docs/development/release-channels/scoop.md. - Add
mdsmith-release render-winget-manifestwith unit tests. - Add the
winget-submitjob usingkomacandWINGET_PR_TOKEN; document its rotation. - Add
docs/development/release-channels/winget.md. - Run
sync-channels; confirm the picker and table show the Scoop row, weighted among the CLI channels. WinGet isunlisteduntil its manifest PR merges. - Update the Windows section of the install guide.
All in-repo tasks are complete. ✅ reflects that all in-repo work is
done. The two criteria below remain unchecked because each has an
external gate. The Scoop bucket (jeduden/scoop-mdsmith) self-bumps
but lives outside this repo. The winget-submit job runs here and
opens the PR, but winget install jeduden.mdsmith only works after
Microsoft moderation merges that PR.
-
scoop install mdsmith(afterscoop bucket add) installs the released.exe, checksum-verified. (external — jeduden/scoop-mdsmith repo is live) -
winget install jeduden.mdsmithinstalls the released.exeonce the manifest PR is merged. (external — winget-submit job opens the PR; Microsoft moderation must merge it before the command works) - Manifest generation lives in
mdsmith-release(render-scoop-manifest,render-winget-manifest), not inline workflow shell; the recurringwinget-submitjob haskomacgenerate the WinGet manifest from the binary URL. The manifest is aportableinstaller type, so WinGet links the binary onto PATH asmdsmithinstead of executing it. - A missing
SCOOP_BUCKET_DISPATCH_TOKENorWINGET_PR_TOKENlogs a notice and never fails the release. - The install picker and table show the Scoop row for
Windows; WinGet carries
unlisted: trueand is held out of both until its manifest PR merges. - secret-rotations tracks both tokens under the 30-day reminder.
- All tests pass:
go test ./... -
go tool golangci-lint runreports no issues. -
mdsmith check .passes.