Skip to content

Publish pv-migrate to winget #476

Description

@utkuozdemir

Windows users currently have Scoop and the release archives. A winget package would make winget install utkuozdemir.pv-migrate work, which is the default package manager on Windows now. Windows is a small share of the downloads (about 2 percent of the release archive downloads as of 2026-09), so this is low priority, but it is cheap once the pieces below are in place.

Reference

nvidia_gpu_exporter already publishes to winget from goreleaser, so copy from there:

  • The winget: section of https://github.com/utkuozdemir/nvidia_gpu_exporter/blob/main/.goreleaser.yml. goreleaser writes the manifests (installer, locale, version) from the Windows zip archive and opens the pull request against microsoft/winget-pkgs itself. For pv-migrate: package_identifier: utkuozdemir.pv-migrate, publisher: utkuozdemir, license Apache-2.0, ids pointing at the archive id of the Windows zip, release_notes: "{{ .Changelog }}", a branch per version in the fork, pull_request.enabled: true with microsoft/winget-pkgs as the base.
  • The release workflow needs nothing new, the publisher runs inside the existing goreleaser step.

Token

This is the part that is easy to get wrong.

  • The winget publisher pushes to a fork of microsoft/winget-pkgs and opens a pull request against Microsoft's repository. A fine-grained token cannot do that: it gets write access only to repositories the owner controls, and is read-only on everyone else's. The token has to be a classic PAT.
  • Scopes: repo (or at least public_repo) to push the branch and open the pull request, plus workflow. The workflow scope became necessary in 2026-09 when upstream added a workflow file to the repository, since goreleaser first syncs the fork with upstream and that sync then touches a workflow file. Without it the sync fails with a 422, goreleaser logs the error and still opens the pull request from the stale fork, so it works but the fork drifts. The exporter's token ("goreleaser nvidia_gpu_exporter" in the GitHub settings) has repo and workflow today.
  • Keep pv-migrate's existing fine-grained PRIVATE_ACCESS_TOKEN for the Homebrew tap and the Scoop bucket, where it is the tighter choice, and give the winget publisher its own environment variable in the goreleaser config (e.g. WINGET_TOKEN) backed by a second secret in the release environment. That way the broader classic token is used for the one job that needs it.
  • The fork utkuozdemir/winget-pkgs already exists from the exporter. One fork serves both projects, branches are named per package and version.

Other things to know

  • The Microsoft CLA was agreed once for the exporter's first pull request, and it covers every later pull request from the same account, so no action there.
  • The first pull request for a new package gets a closer look from the winget moderators than a version bump does, and the validation bot comments on the pull request. Nothing to do on our side except wait, and answer if a moderator asks.
  • Once a maintainer approves, the pull requests merge on their own. No action per release.
  • If the release fails at the winget step, everything else is already published. The fix is to correct the token or the manifest and re-run the workflow, never to publish the manifests manually.
  • Prereleases: skip_upload: auto keeps them out of winget, same as the other publishers.
  • After the first published version, the README gets the badge the exporter has: https://img.shields.io/winget/v/utkuozdemir.pv-migrate?style=flat-square, and the install guide a winget install utkuozdemir.pv-migrate section next to Scoop.
  • The published version is {{ .Version }} without the v, which is what winget wants. The archive names keep their v prefix, that does not matter for the manifest.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions