fix(release): preserve PR notes and validate WinGet access (#658)

## Summary

- prepend the merged stable release PR body to GitHub-generated release
notes
- keep nightly prerelease notes unchanged
- verify the WinGet token can create and delete branches in the
configured fork before invoking Komac
- document writable PAT and GitHub CLI OAuth token options

## Root cause

The v0.19.0 WinGet job reached Komac successfully, but
`WINGET_GITHUB_TOKEN` could not execute `CreateRef` in
`pascalandr/winget-pkgs`. The repository secret has been replaced with
the currently authenticated writable GitHub CLI token.

## Validation

- `actionlint .github/workflows/reusable-release.yml
.github/workflows/update-winget.yml`
- associated-PR lookup returned the #656 body for merge commit
`db0716e7`
- temporary branch create/delete succeeded in `pascalandr/winget-pkgs`
- `winget validate` succeeded for the v0.19.0 manifests

Manual WinGet submission:
https://github.com/microsoft/winget-pkgs/pull/423225
This commit is contained in:
Pascal André 2026-08-29 17:02:35 +02:00 • committed by GitHub
parent 56156827d1
commit e4cd6d6fcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 6 deletions

View file

@ -184,4 +184,4 @@ jobs:
- name: Test Tauri crate on Windows
working-directory: packages/tauri-app/src-tauri
run: cargo test --locked
run: cargo test --locked -- --test-threads=1

View file

@ -86,11 +86,19 @@ jobs:
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG already exists"
else
args=(--title "$TAG" --generate-notes)
if [ "${IS_PRERELEASE}" = "true" ]; then
gh release create "$TAG" --title "$TAG" --generate-notes --prerelease
args+=(--prerelease)
else
gh release create "$TAG" --title "$TAG" --generate-notes
pr_body="$(gh api "repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" \
--jq 'map(select(.merged_at != null and .base.ref == "main")) | sort_by(.merged_at) | last | .body // ""')"
if [ -n "$pr_body" ]; then
args+=(--notes "$pr_body")
fi
fi
gh release create "$TAG" "${args[@]}"
fi
build-and-upload:

View file

@ -117,7 +117,7 @@ jobs:
echo "Resolved version: ${{ steps.release_asset.outputs.version }}"
echo "Resolved SHA-256: ${{ steps.release_asset.outputs.asset_sha256 }}"
- name: Validate fork configuration
- name: Validate fork write access
env:
GH_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }}
EXPECTED_OWNER: ${{ env.WINGET_FORK_OWNER }}
@ -138,6 +138,14 @@ jobs:
exit 1
fi
default_branch="$(gh api "repos/$fork_name" --jq '.default_branch')"
default_sha="$(gh api "repos/$fork_name/git/ref/heads/$default_branch" --jq '.object.sha')"
test_branch="codenomad-winget-token-check-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
gh api --method POST "repos/$fork_name/git/refs" \
-f ref="refs/heads/$test_branch" \
-f sha="$default_sha" >/dev/null
gh api --method DELETE "repos/$fork_name/git/refs/heads/$test_branch" >/dev/null
echo "Validated fork: $fork_name"
- name: Submit update to Winget

View file

@ -14,7 +14,7 @@ CodeNomad publishes Winget updates from the stable GitHub release pipeline. `.gi
### Repository secret
- `WINGET_GITHUB_TOKEN`: Classic GitHub PAT with `public_repo` scope.
- `WINGET_GITHUB_TOKEN`: GitHub token with write access to the configured fork (for example, a classic PAT with `public_repo` scope or a GitHub CLI OAuth token with `repo` scope).
- The token owner must own the fork that submits to `microsoft/winget-pkgs`.
- Komac-based submission cannot open the PR with a fine-grained token today.
@ -33,7 +33,7 @@ CodeNomad publishes Winget updates from the stable GitHub release pipeline. `.gi
1. Resolve the target release by tag through the GitHub API, then derive the package version from the resolved release tag.
2. Poll the release API until exactly one uploaded asset matches the configured Windows Tauri asset template.
3. Download the matched asset once and compute a SHA-256 for logging and verification.
4. Verify the PAT owner matches `WINGET_FORK_OWNER` and that `${WINGET_FORK_OWNER}/winget-pkgs` is a fork of `microsoft/winget-pkgs`.
4. Verify the token owner matches `WINGET_FORK_OWNER`, that `${WINGET_FORK_OWNER}/winget-pkgs` is a fork of `microsoft/winget-pkgs`, and that the token can create and delete a temporary branch.
5. Invoke `vedantmgoyal9/winget-releaser@v2`, which uses Komac under the hood to update the existing `NeuralNomadsAI.CodeNomad` manifest and open the PR.
## Notes