From 7d99549c85a2f1a26f5f430bb0ff8529163ee737 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 12:42:01 +0000 Subject: [PATCH 1/2] fix: resolve WinGet fork-user from token owner; add workflow_dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WinGet publish workflow was failing with: Could not resolve to a Repository with the name 'dfetch-org/winget-pkgs' Root cause: winget-releaser defaulted fork-user to the repository owner (dfetch-org), but a fine-grained PAT scoped to an organisation cannot create org-level forks — the fork of microsoft/winget-pkgs therefore never existed in dfetch-org. Fix: add a step that calls GET /user with the WINGET_TOKEN to discover the personal GitHub account that owns the token, then pass that account as fork-user to winget-releaser. komac will fork winget-pkgs into the personal account (where the token has full rights) and open the PR from there — the standard WinGet community pattern. Also add workflow_dispatch so maintainers can manually re-trigger the publish for an already-released tag (e.g. to retry 0.14.2 after updating the token). Update the token-setup comment: the PAT must be created with the user's personal account as resource owner, not the DFetch-org organisation. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_012NwjWMaDcFgUU1UNpQFfY4 --- .github/workflows/winget-publish.yml | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/.github/workflows/winget-publish.yml b/.github/workflows/winget-publish.yml index 6404fa36..3e9d4060 100644 --- a/.github/workflows/winget-publish.yml +++ b/.github/workflows/winget-publish.yml @@ -3,6 +3,12 @@ name: Publish to WinGet on: release: types: [published] + workflow_dispatch: + inputs: + release-tag: + description: 'Release tag to publish (e.g. 0.14.2)' + required: true + type: string permissions: contents: read @@ -10,11 +16,14 @@ permissions: jobs: publish: name: Publish to WinGet - # Only publish versioned releases — skip the rolling 'latest' tag on main - if: github.event.release.tag_name != 'latest' + # For releases: skip the rolling 'latest' tag on main. + # For manual dispatch: always run (the operator knows what they're doing). + if: >- + github.event_name != 'release' || + github.event.release.tag_name != 'latest' runs-on: ubuntu-latest concurrency: - group: winget-publish-${{ github.event.release.tag_name }} + group: winget-publish-${{ github.event.release.tag_name || inputs.release-tag }} cancel-in-progress: true environment: @@ -35,13 +44,27 @@ jobs: index.crates.io:443 static.crates.io:443 + - name: Resolve WinGet fork owner from token + # komac forks microsoft/winget-pkgs into the fork-owner's account and + # opens a PR from there. Fine-grained PATs scoped to an *organisation* + # cannot create org-level forks, so we always fork into the *personal* + # account that owns the token (typically the maintainer's account). + id: winget-fork-owner + run: | + OWNER=$(curl -sf \ + -H "Authorization: Bearer ${{ secrets.WINGET_TOKEN }}" \ + https://api.github.com/user \ + | python3 -c "import sys, json; print(json.load(sys.stdin)['login'])") + echo "fork-user=${OWNER}" >> "$GITHUB_OUTPUT" + - name: Publish to WinGet # Requires WINGET_TOKEN secret in the 'winget' environment. # # Setup — create a fine-grained PAT: # 1. GitHub → Settings → Developer settings → Personal access tokens # → Fine-grained tokens → Generate new token - # 2. Resource owner: DFetch-org (or your user) + # 2. Resource owner: YOUR PERSONAL GitHub account (not the org — + # org-scoped tokens cannot create the required winget-pkgs fork) # 3. Repository access: All repositories # (needed to fork microsoft/winget-pkgs and push the manifest branch) # 4. Permissions: @@ -52,5 +75,6 @@ jobs: uses: vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e # v2 with: identifier: DFetch-org.DFetch - release-tag: ${{ github.event.release.tag_name }} + release-tag: ${{ github.event.release.tag_name || inputs.release-tag }} token: ${{ secrets.WINGET_TOKEN }} + fork-user: ${{ steps.winget-fork-owner.outputs.fork-user }} From d384d9dd0840c349ea881ba1529c5a322315743a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 17:02:39 +0000 Subject: [PATCH 2/2] fix: use dfetch-org/winget-pkgs org fork (created manually) Replace the dynamic fork-user resolution with a hardcoded fork-user: dfetch-org now that the org fork of microsoft/winget-pkgs has been created manually. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_012NwjWMaDcFgUU1UNpQFfY4 --- .github/workflows/winget-publish.yml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/.github/workflows/winget-publish.yml b/.github/workflows/winget-publish.yml index 3e9d4060..d113461e 100644 --- a/.github/workflows/winget-publish.yml +++ b/.github/workflows/winget-publish.yml @@ -44,37 +44,26 @@ jobs: index.crates.io:443 static.crates.io:443 - - name: Resolve WinGet fork owner from token - # komac forks microsoft/winget-pkgs into the fork-owner's account and - # opens a PR from there. Fine-grained PATs scoped to an *organisation* - # cannot create org-level forks, so we always fork into the *personal* - # account that owns the token (typically the maintainer's account). - id: winget-fork-owner - run: | - OWNER=$(curl -sf \ - -H "Authorization: Bearer ${{ secrets.WINGET_TOKEN }}" \ - https://api.github.com/user \ - | python3 -c "import sys, json; print(json.load(sys.stdin)['login'])") - echo "fork-user=${OWNER}" >> "$GITHUB_OUTPUT" - - name: Publish to WinGet # Requires WINGET_TOKEN secret in the 'winget' environment. # # Setup — create a fine-grained PAT: # 1. GitHub → Settings → Developer settings → Personal access tokens # → Fine-grained tokens → Generate new token - # 2. Resource owner: YOUR PERSONAL GitHub account (not the org — - # org-scoped tokens cannot create the required winget-pkgs fork) + # 2. Resource owner: DFetch-org # 3. Repository access: All repositories - # (needed to fork microsoft/winget-pkgs and push the manifest branch) + # (needed to push the manifest branch to dfetch-org/winget-pkgs) # 4. Permissions: # Contents → Read and write # Pull requests → Read and write # 5. Store the token as secret WINGET_TOKEN in: # Repo → Settings → Environments → winget → Environment secrets + # + # Prerequisites: dfetch-org/winget-pkgs must exist as a fork of + # microsoft/winget-pkgs (create it once manually on GitHub). uses: vedantmgoyal9/winget-releaser@4ffc7888bffd451b357355dc214d43bb9f23917e # v2 with: identifier: DFetch-org.DFetch release-tag: ${{ github.event.release.tag_name || inputs.release-tag }} token: ${{ secrets.WINGET_TOKEN }} - fork-user: ${{ steps.winget-fork-owner.outputs.fork-user }} + fork-user: dfetch-org