From 771a11feab259664afa6d4a56ed465b4166c0619 Mon Sep 17 00:00:00 2001 From: bherbruck Date: Wed, 14 Oct 2026 17:07:06 -0400 Subject: [PATCH] Submit published releases to WinGet (#1222) Publishing a non-prerelease release runs winget.yml, which opens the winget-pkgs pull request for bherbruck.SolidCraft with Komac (pinned 2.16.0 binary, SHA-256 checked) from the three versioned MSIs. It skips cleanly without the WINGET_TOKEN secret or before the package's first version is in winget-pkgs. docs/releasing.md has the one-time token setup; the README's Download section gains the winget install line. Co-authored-by: Claude Opus 5.5 --- .github/workflows/winget.yml | 77 ++++++++++++++++++++++++++++++++++++ README.md | 2 + docs/releasing.md | 35 ++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 .github/workflows/winget.yml diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml new file mode 100644 index 00000000..ac6981b6 --- /dev/null +++ b/.github/workflows/winget.yml @@ -0,0 +1,77 @@ +# Publishing a GitHub release (not a prerelease) opens a pull request at microsoft/winget-pkgs +# that adds the new version of bherbruck.SolidCraft, so `winget install bherbruck.SolidCraft` +# and `winget upgrade` get it. Komac (https://github.com/russellbanks/Komac) downloads the three +# versioned MSIs, reads their product codes and copies the rest from the previous manifest. +# Skipped until the owner adds the WINGET_TOKEN secret, and while the package isn't in +# winget-pkgs yet; see docs/releasing.md. +name: WinGet + +on: + release: + types: [released] + workflow_dispatch: + inputs: + tag: + description: Published release tag to submit (e.g. v0.11.1) + required: true + +permissions: + contents: read + +concurrency: + group: winget + cancel-in-progress: false + +env: + PACKAGE_ID: bherbruck.SolidCraft + KOMAC_VERSION: 2.16.0 + KOMAC_SHA256: 7d2707fa6210f2789a3702de49fbd150b736dbf426ee0b9bc8e098736f9fd82d + +jobs: + submit: + runs-on: ubuntu-latest + steps: + - id: check + name: Check for the token and the package + env: + WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }} + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name || inputs.tag }} + run: | + if [ -z "$WINGET_TOKEN" ]; then + echo "No WINGET_TOKEN secret: nothing to submit." + exit 0 + fi + case "$TAG" in + v[0-9]*.[0-9]*.[0-9]*-*|*nightly*) echo "$TAG is a prerelease: not submitted."; exit 0 ;; + v[0-9]*.[0-9]*.[0-9]*) ;; + *) echo "::error::Unexpected tag '$TAG'"; exit 1 ;; + esac + if ! gh api "repos/microsoft/winget-pkgs/contents/manifests/b/bherbruck/SolidCraft" --silent; then + echo "$PACKAGE_ID isn't in winget-pkgs yet: nothing to update." + exit 0 + fi + echo "version=${TAG#v}" >>"$GITHUB_OUTPUT" + echo "tag=$TAG" >>"$GITHUB_OUTPUT" + - name: Install Komac + if: steps.check.outputs.version != '' + run: | + archive="komac-${KOMAC_VERSION}-x86_64-unknown-linux-gnu.tar.gz" + curl -fsSLo "$RUNNER_TEMP/$archive" \ + "https://github.com/russellbanks/Komac/releases/download/v${KOMAC_VERSION}/$archive" + echo "$KOMAC_SHA256 $RUNNER_TEMP/$archive" | sha256sum -c - + tar -xzf "$RUNNER_TEMP/$archive" -C "$RUNNER_TEMP" komac + - name: Open the winget-pkgs pull request + if: steps.check.outputs.version != '' + env: + GITHUB_TOKEN: ${{ secrets.WINGET_TOKEN }} + VERSION: ${{ steps.check.outputs.version }} + TAG: ${{ steps.check.outputs.tag }} + run: | + base="https://github.com/${GITHUB_REPOSITORY}/releases/download/$TAG" + "$RUNNER_TEMP/komac" update "$PACKAGE_ID" --version "$VERSION" \ + --urls "$base/solidcraft-$VERSION-windows-x64.msi" \ + "$base/solidcraft-$VERSION-windows-x86.msi" \ + "$base/solidcraft-$VERSION-windows-arm64.msi" \ + --release-notes-url "https://github.com/${GITHUB_REPOSITORY}/releases/tag/$TAG" \ + --submit diff --git a/README.md b/README.md index c9990f2c..04e1deca 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ model through the built-in MCP server. - **Windows:** download and run the [installer][windows-msi]. Also for [ARM64][windows-arm64-msi] and [32-bit][windows-x86-msi] PCs, or as a [portable zip][windows-portable] that runs without installing. + With [WinGet](https://learn.microsoft.com/windows/package-manager/winget/): + `winget install bherbruck.SolidCraft`. - **macOS:** open the [disk image][macos-dmg] and drag SolidCraft into Applications (Apple silicon and Intel). - **Linux:** download the [AppImage][linux-appimage], allow it to run as a program and open it. diff --git a/docs/releasing.md b/docs/releasing.md index 96be9681..8c9754c8 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -206,6 +206,41 @@ Renew the credentials before `--expires` by repeating steps 2 and 3. The snap us confinement and only plugs that connect automatically, apart from `removable-media`, which users connect with `sudo snap connect solidcraft:removable-media` (getting-started.md). +## WinGet (Windows Package Manager) + +SolidCraft is in [winget-pkgs](https://github.com/microsoft/winget-pkgs) as +`bherbruck.SolidCraft` (`winget install bherbruck.SolidCraft`). Publishing a non-prerelease +GitHub release runs `winget.yml`, which uses [Komac](https://github.com/russellbanks/Komac) +(a pinned, checksum-verified binary) to open a pull request at microsoft/winget-pkgs from the +owner's fork `bherbruck/winget-pkgs`. It submits the three versioned MSIs +(`solidcraft--windows-{x64,x86,arm64}.msi`, never the fixed-name copies), reads their +product codes, links the release notes and keeps the other fields from the previous version's +manifest. The winget-pkgs bots validate it and a moderator merges it, usually within a day or two. + +The job does nothing, successfully, while the `WINGET_TOKEN` repository secret is missing or +before the package's first version is merged into winget-pkgs. Like `snap-store.yml`, a +publication made with `GITHUB_TOKEN` doesn't trigger it: then run +`gh workflow run winget.yml -R bherbruck/solidcraft -f tag=v`. + +To enable it once (owner): + +1. Create a **classic** personal access token at + (Settings > Developer settings > Personal access tokens > Tokens (classic)): note + "solidcraft winget", an expiry such as one year, and only the **`public_repo`** scope. + Fine-grained tokens can't open pull requests on microsoft/winget-pkgs. +2. Store it as the repository secret (paste the token when asked): + + ```sh + gh secret set WINGET_TOKEN -R bherbruck/solidcraft + ``` + +3. Keep the fork `bherbruck/winget-pkgs` (Komac pushes its branches there). Its default branch + doesn't need syncing. + +When the token expires, create a new one the same way and run step 2 again. If a release was +published while the secret was missing or expired, submit it afterwards with +`gh workflow run winget.yml -R bherbruck/solidcraft -f tag=v`. + ## Update signing The app's **Update now** (docs/book/src/guide/updates.md) only installs a package whose SHA-256