Link winget PRs to Package Request issues automatically
Scrape the PR URL from wingetcreate's output, open a Package Request issue on first submission, and rewrite the winget-pkgs PR body to fill the Description, tick the issue checkbox, and add Resolves #NNN. This replaces the manual post-release step of editing each PR by hand. Co-Authored-By: siGit Code v1.6.7-acp <noreply@sigit.si>
Seto Elkahfi committed
Oct 11, 2026 at 20:34 UTC
2e68304d118fb6c872613bdbfb2d5e017897ce9c
1 file changed
+93
-2
.github/workflows/release-winget.yml
+93
-2
@@ -124,6 +124,7 @@ jobs:
124
run: Invoke-WebRequest -Uri "https://aka.ms/wingetcreate/latest" -OutFile wingetcreate.exe
125
126
- name: Submit new package
127
+ id: submit_new
128
if: steps.exists.outputs.found == 'false'
129
shell: pwsh
130
env:
@@ -138,16 +139,28 @@ jobs:
139
140
$version = "${{ steps.release.outputs.version }}"
141
142
+ # Tee stdout so we can scrape the PR URL afterwards. wingetcreate
143
+ # prints "Pull request can be found here: <url>" on success, and
144
+ # that line is the only handle we get on the PR it just opened.
145
# --no-open because the runner has no browser to open the PR in.
146
.\wingetcreate.exe submit manifests `
147
--prtitle "New package: $env:PACKAGE_IDENTIFIER version $version" `
144
- --no-open
148
+ --no-open 2>&1 | Tee-Object -Variable output
149
150
if ($LASTEXITCODE -ne 0) {
151
Write-Error "wingetcreate submit failed with exit code $LASTEXITCODE"
152
}
153
154
+ $match = [regex]::Match(($output -join "`n"), 'https://github\.com/microsoft/winget-pkgs/pull/(\d+)')
155
+ if ($match.Success) {
156
+ "pr_url=$($match.Value)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
157
+ "pr_number=$($match.Groups[1].Value)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
158
+ } else {
159
+ Write-Warning "Could not find the PR URL in wingetcreate output; skipping issue linking."
160
+ }
161
+
162
- name: Submit manifest update
163
+ id: submit_update
164
if: steps.exists.outputs.found == 'true'
165
shell: pwsh
166
env:
@@ -171,8 +184,86 @@ jobs:
184
--release-date "${{ steps.release.outputs.date }}" `
185
--prtitle "Update $env:PACKAGE_IDENTIFIER to version $version" `
186
--submit `
174
- --no-open
187
+ --no-open 2>&1 | Tee-Object -Variable output
188
189
if ($LASTEXITCODE -ne 0) {
190
Write-Error "wingetcreate failed with exit code $LASTEXITCODE"
191
}
192
+
193
+ $match = [regex]::Match(($output -join "`n"), 'https://github\.com/microsoft/winget-pkgs/pull/(\d+)')
194
+ if ($match.Success) {
195
+ "pr_url=$($match.Value)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
196
+ "pr_number=$($match.Groups[1].Value)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
197
+ } else {
198
+ Write-Warning "Could not find the PR URL in wingetcreate output; skipping issue linking."
199
+ }
200
+
201
+ # wingetcreate has no --prbody flag, so it always opens the PR with the
202
+ # winget-pkgs template: an empty Description and an unticked
203
+ # "Linked to an issue" box next to a "Resolves #[Issue Number]"
204
+ # placeholder. We used to tick that box and fill in the issue number by
205
+ # hand after every release. This step does it instead.
206
+ #
207
+ # On a first submission it also files the Package Request issue the
208
+ # linkable number comes from. Updates to an existing package don't need
209
+ # one (the checkbox is "if applicable"), so there we just fill the
210
+ # Description.
211
+ - name: Link the winget PR to a Package Request issue
212
+ id: link
213
+ if: >-
214
+ (steps.submit_new.outputs.pr_number != '') ||
215
+ (steps.submit_update.outputs.pr_number != '')
216
+ shell: bash
217
+ env:
218
+ # The PR and the issue both live in microsoft/winget-pkgs, which the
219
+ # default GITHUB_TOKEN can't write to. Reuse the wingetcreate PAT,
220
+ # which already has the scope to open PRs there.
221
+ GH_TOKEN: ${{ secrets.WINGET_TOKEN }}
222
+ run: |
223
+ set -euo pipefail
224
+
225
+ PR_URL="${{ steps.submit_new.outputs.pr_url || steps.submit_update.outputs.pr_url }}"
226
+ NEW_PACKAGE="${{ steps.exists.outputs.found == 'false' }}"
227
+ VERSION="${{ steps.release.outputs.version }}"
228
+ TAG="${{ steps.release.outputs.tag }}"
229
+
230
+ ISSUE_NUMBER=""
231
+ if [ "$NEW_PACKAGE" = "true" ]; then
232
+ ISSUE_URL=$(gh issue create \
233
+ --repo microsoft/winget-pkgs \
234
+ --title "Package Request: ${PACKAGE_IDENTIFIER} ${VERSION}" \
235
+ --body "Request to add ${PACKAGE_IDENTIFIER} version ${VERSION} to the Windows Package Manager Community Repository. Installers come from ${TAG} of ${REPO}.")
236
+ echo "Opened issue ${ISSUE_URL}"
237
+ ISSUE_NUMBER="${ISSUE_URL##*/}"
238
+ fi
239
+
240
+ # Rewrite the template body: fill the Description, tick the issue
241
+ # box when we have an issue, and drop in the real number (or remove
242
+ # the placeholder line on updates that aren't linked to anything).
243
+ if [ -n "$ISSUE_NUMBER" ]; then
244
+ CHECKBOX="- [x] Linked to an issue (if applicable)"
245
+ RESOLVES="- Resolves #${ISSUE_NUMBER}"
246
+ DESC="Adds ${PACKAGE_IDENTIFIER} version ${VERSION} from ${TAG}."
247
+ else
248
+ CHECKBOX="- [ ] Linked to an issue (if applicable)"
249
+ RESOLVES=""
250
+ DESC="Updates ${PACKAGE_IDENTIFIER} to version ${VERSION} from ${TAG}."
251
+ fi
252
+
253
+ BODY=$(cat <<EOF
254
+ ## 📖 Description
255
+ ${DESC}
256
+ ## ✅ Checklist
257
+ - [x] Signed the [Contributor License Agreement](https://cla.opensource.microsoft.com)
258
+ ${CHECKBOX}
259
+ ${RESOLVES}
260
+ ## 📦 Manifest Checklist
261
+ - [x] Checked that there aren't other open [pull requests](https://github.com/microsoft/winget-pkgs/pulls) for the same manifest update/change
262
+ - [x] This PR only modifies one (1) manifest
263
+ - [x] Validated manifest locally with \`winget validate\`
264
+ - [x] Tested manifest locally with \`winget install\`
265
+ EOF
266
+ )
267
+
268
+ gh pr edit "$PR_URL" --body "$BODY"
269
+ echo "Linked ${PR_URL} to issue #${ISSUE_NUMBER:-<none>}"