Skip to content

feat(ci): add winget manifest automation - #1318

Merged
KuSh merged 10 commits into
rtk-ai:developfrom
kerta1n:feat/winget-automation
Sep 11, 2026
Merged

KuSh merged 10 commits into
rtk-ai:developfrom
kerta1n:feat/winget-automation

Conversation

@kerta1n

@kerta1n kerta1n commented Apr 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a winget job to the release workflow that auto-submits updated manifests to microsoft/winget-pkgs on stable releases via vedantmgoyal9/winget-releaser@v2
  • Adds winget install rtk-ai.rtk to README.md and INSTALL.md installation docs
  • Adds winget uninstall rtk-ai.rtk to INSTALL.md binary removal section

The job follows the same pattern as the existing homebrew and notify-discord post-release jobs: guarded by !inputs.prerelease, depends on [release], runs on ubuntu-latest.

Prerequisites

Before this automation works, the repo owner needs to:

  1. Create a GitHub PAT (classic) with public_repo scope
  2. Add it as repo secret WINGET_TOKEN

Test plan

  • Verify workflow YAML is valid (no syntax errors in CI)
  • Verify winget job only runs on stable releases (!inputs.prerelease guard)
  • After merge + next stable release: confirm auto-PR appears in microsoft/winget-pkgs

Fixes #383

🤖 Generated with Claude Code

Auto-submit updated manifests to microsoft/winget-pkgs on stable releases
using vedantmgoyal9/winget-releaser. Windows users can now install via
`winget install rtk-ai.rtk`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Apr 15, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@kerta1n

kerta1n commented Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

This PR fixes issue #383

@Odonno Odonno left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kerta1n

kerta1n commented Apr 18, 2026

Copy link
Copy Markdown
Contributor Author

Pinging @aeppling

Move placement to make winget command easier to find
Add winget commands into other documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kerta1n

kerta1n commented Apr 19, 2026

Copy link
Copy Markdown
Contributor Author

Above commit adds winget docs into other language README's, I missed that in the first commit

Odonno
Odonno previously requested changes Apr 20, 2026
Comment thread README.md Outdated
Comment thread README_fr.md Outdated
@kerta1n

kerta1n commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

@pszymkowiak is this eligble for review?

@smoochy

smoochy commented Aug 3, 2026

Copy link
Copy Markdown

Could this please be approved?

Match the hardening applied to the release, homebrew and notify-discord
jobs in 9cc4937: interpolate inputs.tag and github.event.release.tag_name
into env vars rather than into the run script body.
- README_pt.md: add the winget section (only translation missing it)
- docs/guide/getting-started/installation.md: add winget install and
  uninstall entries
- README_{es,fr,ja,ko,zh}.md: drop the superlative from the winget
  heading so all seven READMEs read "winget (Windows)", matching the
  existing "Homebrew (recommended)" convention
- README.md: shorten the Native Windows heading to "(manual install)",
  move the winget pointer into prose

Deliberately out of scope: docs/guide/getting-started/installation.md
still tells Windows users to use WSL "for full hook support". README.md
contradicts this - native Windows hooks have worked since v0.37.2.
Correcting it means rewriting text this PR does not otherwise touch, so
it is left for a separate change.
@kerta1n

kerta1n commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor Author

(Opus says:)
@pszymkowiak @KuSh This PR is now rebased on develop (was ~420 commits behind) — merged clean, no conflicts.

Two prerequisites for this job, both on the maintainer side:

1. WINGET_TOKEN needs a forked winget-pkgs, not just a PAT. winget-releaser pushes its working branch to the token owner's fork of microsoft/winget-pkgs before opening the upstream PR. So whoever creates the classic PAT (public_repo scope) must also have forked microsoft/winget-pkgs on that same account. Creating the secret alone will leave the job red.

2. This replaces an existing manual process.
rtk-ai.rtk is already published — 14 versions, currently through v0.48.0 (microsoft/winget-pkgs#431023, open). Submissions to date have come from @kerta1n, @wxxb789 and @smoochy independently. Once this merges, whoever is next to release should hold off on a manual submission or the automation will race a duplicate PR upstream.

Minor note, no action needed here: existing manifest folders are inconsistent — 0.36.0 … 0.46.0 are bare, v0.47.0 and v0.48.0 carry the v, mistake by @kerta1n. This workflow strips it (${TAG#v}), so it submits bare and matches the majority. winget's version comparator still orders correctly either way.

@KuSh KuSh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 1 of 3 — CHANGES REQUESTED

Claim: automate winget manifest submission on stable releases, and document winget install rtk-ai.rtk across the install docs.
Scope: accept (round 1, frozen). Fixes #383 is accurate. Overlaps #3775 on action pinning — narrow fix asked for here, not a wait. Not a duplicate of #2773 (Chocolatey, different manager).
Ran: winget-releaser@v2 action.yml read in full; cd.yml → release.yml call paths traced; installers-regex matched against the 10 real assets of v0.48.0; the published rtk-ai.rtk manifests read; YAML parsed; merges clean on develop@8e9aa04c.
CI @2f905f7b: only license/cla green — the CI run is action_required and has never built this head. A maintainer needs to approve it.

Thanks for the rebase and for the research in your last comment — the manifest-inconsistency note in particular saved me a trip.

Blocks merge (1, frozen at round 1)

  1. .github/workflows/release.yml:372 — the winget job is not fail-isolated (regression against develop). See the inline comment. update-latest-tag is needs: [release-please, build-release] with no if: always(), so a red winget job leaves the latest tag on the previous version. Fix is continue-on-error: true on the job.

Optional — will not hold merge

  • Pin winget-releaser. @v2 is a mutable major tag and that step receives WINGET_TOKEN, a classic PAT with write access to public repositories. #3775 is currently pinning exactly this class across the repo (release-please-action@v4, rust-toolchain@stable, action-gh-release@v2); doing it here avoids that PR having to come back for a seventh. v2 resolves to 4ffc7888bffd451b357355dc214d43bb9f23917e today, so the pin is behaviour-identical:

    - uses: vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e # v2
  • docs/guide/getting-started/installation.md:3 — the frontmatter description: still reads "via curl, Homebrew, Cargo, or from source". It renders as the page's meta description and search snippet, so the docs site advertises a method list that omits the one this PR promotes. Adding winget, after Homebrew, closes it.

  • feat(ci): will have release-please cut a minor bump for a change that ships no binary difference; CONTRIBUTING.md maps CI to chore and the documented scope is cicd, not ci. Genuinely arguable — a new install channel is a real user-facing feature — and it's your call, not a blocker.

Checked and correct — no need to re-verify

  • Job wiring. cd.yml's pre-release path passes prerelease: true → job skipped; the stable path omits it → defaults false → job runs. secrets: inherit carries WINGET_TOKEN into the reusable workflow. Matches homebrew and notify-discord exactly.
  • release-tag: (commit 69cd16ee) is necessary, not cosmetic. The action's default is github.event.release.tag_name || github.ref_name, and this workflow has no release trigger, so the default would resolve to a branch name. Good catch.
  • installers-regex matched exactly 1 of the 10 real assets on v0.48.0.
  • zip installer. The published v0.48.0 manifest is InstallerType: zip / NestedInstallerType: portable / RelativeFilePath: rtk.exe; komac carries that shape forward, so no hand-editing.
  • ${TAG#v} matches 13 of the 15 published folders.
  • Doc coverage is complete and consistently placed: 7 READMEs (all after Homebrew, before Quick Install), INSTALL.md (install + uninstall), docs site (install + uninstall). The #winget-windows anchor resolves.
  • No CHANGELOG.md edit — correct, it's release-please-generated.

Hypotheses built and dropped

  • "WINGET_TOKEN isn't set, so the next release goes red." gh secret list --repo shows six secrets and HOMEBREW_TAP_TOKEN isn't among them either — yet rtk-ai/homebrew-tap is at 0.48.0, so that job ran fine with it. They're org-level. Whether WINGET_TOKEN exists is undetermined from outside.
  • "Translated READMEs are missing the Prefer winget cross-link." They carry no Windows section at all (22 headings vs 42 in README.md). Not a gap.
  • "openclaw/README.md mentions brew install rtk and is missing winget." It's a bash-only prerequisite block for a Linux/macOS plugin.
  • "The github.event.release.tag_name fallback is dead code." True — no release trigger — but copied verbatim from both sibling jobs. Pre-existing, not yours.

Your questions

  • "WINGET_TOKEN needs a forked winget-pkgs, not just a PAT." — Right that a fork is needed, but not on the token owner's account. fork-user is unset here, so it defaults to github.repository_owner = rtk-ai, and the action exports KOMAC_FORK_OWNER=rtk-ai. komac will push its working branch to rtk-ai/winget-pkgs, which 404s. So even with a valid WINGET_TOKEN the job goes red. Two ways to close it, maintainer's call: fork microsoft/winget-pkgs into the rtk-ai org and give the PAT push access (no workflow change), or add fork-user: <pat-owner-login> to the step. kerta1n and wxxb789 already have forks; smoochy does not. This is release-time setup, not a merge blocker — but it is why finding 1 matters.
  • "Whoever is next to release should hold off on a manual submission." — Agreed, noted.
  • "Existing folders are inconsistent; this submits bare and matches the majority." — Confirmed, 13/15 bare. No action. One thing worth a check on a Windows box, though: if winget sorts v0.48.0 below 0.46.0, then winget install rtk-ai.rtk currently resolves to 0.46.0, and the docs this PR adds point Windows users at a several-releases-old build until the first automated submission lands. Not this PR's to fix — a cleanup PR against winget-pkgs removing the two v-prefixed folders would.

Next

Add continue-on-error: true to the winget job. That is the only thing holding merge — the pin and the frontmatter line are welcome in the same push but won't block. Then a maintainer needs to approve the CI run, and set up the fork before the next stable release.

Rounds: 1/3. Threads: 0 open, 2 resolved.

Comment thread .github/workflows/release.yml
The winget job sat in the release workflow's critical path: cd.yml gates
update-latest-tag on build-release without `if: always()`, so a failed
manifest submission would fail release.yml and leave the 'latest' tag on
the previous version. Mark the job continue-on-error so a submission
failure cannot hold back the release.

Pin winget-releaser to 4ffc7888bffd451b357355dc214d43bb9f23917e (v2)
rather than the mutable major tag, matching the pinning underway across
the repo. The step receives a classic PAT with write access to public
repositories, so the resolved ref should not be able to move underneath
it.
The frontmatter description renders as the page's meta description and
search snippet, so it advertised an install method list that omitted the
one the page now documents.
@kerta1n

kerta1n commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

All three addressed in 7b09caa and 7be2879:

  • continue-on-error: true on the winget job, with your reasoning as the comment above it.
  • Pinned to vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e # v2.
  • Frontmatter — winget, added after Homebrew, in the installation page description.

On the commit type: leaving feat(ci): as-is. Changing it means rewriting already-pushed history, and since you called it non-blocking it doesn't seem worth a force-push.

Two follow-ups on your findings

Your Windows check — the concern doesn't hold. Ran it on winget v1.29.290:

> winget show rtk-ai.rtk
Found rtk [rtk-ai.rtk]
Version: v0.48.0

The comparator does not sort the v-prefixed folders below the bare ones, so winget install rtk-ai.rtk already resolves to the newest release rather than 0.46.0. The docs this PR adds are accurate today, and no winget-pkgs cleanup PR is needed for correctness.

rtk-ai/winget-pkgs 404 confirmed. GET /repos/rtk-ai/winget-pkgs returns 404, so your diagnosis is right — fork-user defaults to github.repository_owner and komac would push to a repo that doesn't exist. With continue-on-error in place that no longer holds back the release or the latest tag, but the job will show red until either microsoft/winget-pkgs is forked into the rtk-ai org with the PAT given push access, or fork-user: <pat-owner-login> is added to the step. Maintainer's call which — happy to add the fork-user line here if that's the preferred route.

Two asks

1. Could a maintainer dismiss Odonno's April review? Both of its inline comments were addressed in d38cce2 back in April — the French wording was applied verbatim, and the heading they flagged has since been normalised across all seven READMEs. Both threads show as resolved/outdated. Because the review carries read-only permissions it isn't counted toward the approval requirement, but it does leave a standing "changes requested" on the PR, and I can't clear it from the author side.

2. CI has never built this head. Checks are sitting at action_required — only license/cla is green. Once the review state is clear, someone with write access will need to approve the workflow run so the release workflow actually gets validated.

The v2 tag is the action's only tag and has not moved since 2024-11-27,
while development continued on main. Four fixes sit between them, one of
which matters here: the action runs cargo binstall komac, and cargo is
missing on ubuntu-slim runners without it.

Pin to the most recent functional commit rather than to main, whose two
newer commits are documentation only. Its inputs are a superset of the
tag's, so the step needs no other change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@KuSh KuSh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 of 3 — APPROVED

Claim: automate winget manifest submission on stable releases, and document winget install rtk-ai.rtk across the install docs.
Scope: accept (frozen at round 1).
Ran: release.yml parsed at each head to check where continue-on-error actually landed; a43926ed's own action.yml checked for input compatibility; Odonno's two threads diffed from their original commit bd141209 to the head; merge against the latest develop re-checked.
CI @e8a1ef82: green.

All three round-1 items are in, and applied correctly.

Blocks merge (0 — was 1, fixed in 7b09caad)

The fail-isolation finding is closed. I checked the placement rather than the diff, because step-level continue-on-error would have looked identical in review and behaved differently: parsing the file at the head puts it on the job, which is what the finding needed.

One caveat worth stating rather than implying: I verified where it sits, not that GitHub then keeps build-release green. That a continue-on-error job does not fail its workflow run is documented behaviour, but exercising it needs a real release, so the first stable release after this merges is where it gets proven.

Fixup pushed — e8a1ef82

I asked for the pin in round 1 and pointed you at the wrong commit, so I have corrected it rather than leaving you to discover it.

4ffc7888 is genuinely what @v2 resolves to, so your 7b09caad did exactly what I asked. The problem is @v2 itself: it is the action's only tag and has not moved since 2024-11-27, while development continued on main. Ten commits separate them, four of which are fixes — cargo command not found in ubuntu-slim runner (a43926ed), pwsh doesn't sort sometimes (19e706d4), unexpected argument '' found (komac) (3e78d7ff), automatically sync winget fork (e83bb785). The ubuntu-slim one is a live risk here, since the action runs cargo binstall komac on ubuntu-latest.

e8a1ef82 moves the pin to a43926ed822e5a076ac8a81e0a794915cbad51d1 — the most recent functional commit, since the two above it on main are documentation only. I checked that commit's own action.yml before pushing: its inputs are a superset of the tag's, and fork-user keeps its semantics, so the with: block needed no other change. The comment above the step records why it points at a commit rather than a tag, so nobody restores @v2 later.

Optional — applied, threads resolved by me

Frontmatter description: now lists winget.

Checked and correct — no need to re-verify

Job wiring against cd.yml's pre-release and stable paths; secrets: inherit; release-tag: being necessary rather than cosmetic; installers-regex matching exactly 1 of the 10 real assets on v0.48.0; the zip / NestedInstallerType: portable shape carrying forward through komac; ${TAG#v} matching 13 of 15 published folders; doc coverage across 7 READMEs, INSTALL.md and the docs site; no CHANGELOG.md edit. Re-checked this round: still merges clean on the latest develop.

Hypotheses built and dropped

  • Mine, disproven by your execution. I suggested winget install rtk-ai.rtk might resolve to 0.46.0 because the two v-prefixed folders could sort below the bare ones. Your winget show rtk-ai.rtk on v1.29.290 returns Version: v0.48.0, so the comparator handles it and the docs this PR adds are accurate today. No winget-pkgs cleanup needed — that one was mine to run and I could not, so thank you for closing it.
  • Carried from round 1 and still dropped: the WINGET_TOKEN-is-missing claim (org-level secrets are not visible to gh secret list --repo — HOMEBREW_TAP_TOKEN is not either, yet the tap is current); the translated-README cross-link gap (they carry no Windows section at all); openclaw/README.md; the dead github.event.release.tag_name fallback (pre-existing in both sibling jobs).

Your questions

  • "Could a maintainer dismiss Odonno's April review?" — Yes, and I have. I checked it rather than taking the ask at face value, and you are right on both threads: the README comment was anchored on the heading ### winget (Windows — easiest), which is now ### winget (Windows). My round-1 note that "the head still reads Easiest way" was wrong — I read the head cold and judged it by the body sentence instead of diffing the anchored region from bd141209. The French thread carries Odonno's wording verbatim.
  • "CI has never built this head." — Fixed; I approved the run on both of the last two heads. Note that PR CI only parses release.yml, it never executes it, which is why the caveat above matters.
  • "Happy to add the fork-user line here if that's the preferred route." — Not needed, leave it out. The fork is going under the rtk-ai org, which is what fork-user's default already points at. Your diagnosis of the 404 was correct and matched mine; we will handle the setup on our side.
  • "Leaving feat(ci): as-is." — Your call, accepted. It was non-blocking and not worth a force-push.

Next

Approved. On hold until #3868 (Next Release) ships — this adds a job to release.yml, so it should not land mid-release. It merges as-is straight after that.

Thanks for the turnaround on this one, and for running the winget check on Windows — that settled a question I had no way to answer.

Rounds: 2/3. Threads: 0 open, 3 resolved.

@KuSh
KuSh dismissed Odonno’s stale review September 10, 2026 21:43

Both inline comments were addressed in d38cce2: the heading flagged here is now ### winget (Windows), and the French wording was applied verbatim. Verified by diffing the anchored regions from bd14120 to the current head; both threads are resolved. Dismissing so the stale review state does not sit on an approved PR.

@KuSh
KuSh merged commit 22d49e3 into rtk-ai:develop Sep 11, 2026
11 checks passed
@rtk-release-bot rtk-release-bot Bot mentioned this pull request Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: add winget package support

5 participants