From 18d3c6a22e0209f6a611774507e5ff94785b3f46 Mon Sep 17 00:00:00 2001 From: HelloThisWorld Date: Sun, 19 Jul 2026 21:16:53 +0800 Subject: [PATCH 1/3] ci: install pinned WinGet validator --- .github/workflows/winget.yml | 29 +++++++++++++++++++-- scripts/winterm/test-release-workflow.ps1 | 31 ++++++++++++++++++++--- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index a33d226e2..5f46631e8 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -1,6 +1,11 @@ name: Prepare winTerm WinGet manifests on: + pull_request: + paths: + - '.github/workflows/winget.yml' + - 'scripts/winterm/generate-winget-manifests.ps1' + - 'scripts/winterm/test-release-workflow.ps1' release: types: - published @@ -12,7 +17,7 @@ permissions: jobs: validate: name: Generate and validate public-release manifests - if: github.event_name == 'workflow_dispatch' || github.event.release.tag_name == 'v1.0.2' + if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || github.event.release.tag_name == 'v1.0.2' runs-on: windows-2022 timeout-minutes: 20 steps: @@ -49,10 +54,30 @@ jobs: -InstallerSha256 $sha ` -OutputDirectory 'packaging\winget\1.0.2' + - name: Install the pinned WinGet manifest validator + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: | + Install-Module ` + -Name Microsoft.WinGet.Client ` + -RequiredVersion '1.29.280' ` + -Repository PSGallery ` + -Scope CurrentUser ` + -Force + Import-Module Microsoft.WinGet.Client -RequiredVersion '1.29.280' -Force + Repair-WinGetPackageManager -Version '1.29.280' -Force + + $winget = Get-Command winget.exe -ErrorAction Stop + & $winget.Source --version + if ($LASTEXITCODE -ne 0) { + throw 'The pinned WinGet manifest validator is not executable.' + } + - name: Validate WinGet manifests shell: pwsh run: | - winget validate 'packaging\winget\1.0.2' + winget validate --manifest 'packaging\winget\1.0.2' --disable-interactivity if ($LASTEXITCODE -ne 0) { throw 'winget validate failed.' } diff --git a/scripts/winterm/test-release-workflow.ps1 b/scripts/winterm/test-release-workflow.ps1 index 6855ccf81..42fc01169 100644 --- a/scripts/winterm/test-release-workflow.ps1 +++ b/scripts/winterm/test-release-workflow.ps1 @@ -13,6 +13,8 @@ try { $workflowPath = Join-Path $repositoryRoot '.github\workflows\release.yml' $workflow = Get-Content -LiteralPath $workflowPath -Raw + $wingetWorkflowPath = Join-Path $repositoryRoot '.github\workflows\winget.yml' + $wingetWorkflow = Get-Content -LiteralPath $wingetWorkflowPath -Raw $wingetGeneratorPath = Join-Path $repositoryRoot 'scripts\winterm\generate-winget-manifests.ps1' $wingetGenerator = Get-Content -LiteralPath $wingetGeneratorPath -Raw @@ -53,13 +55,16 @@ try throw 'Release workflow contains a forbidden trigger, permission, or asset replacement option.' } - foreach ($line in $workflow -split "`r?`n") + foreach ($workflowToInspect in @($workflow, $wingetWorkflow)) { - if ($line -match '^\s*uses:\s*(?[^@\s]+)@(?[^\s#]+)') + foreach ($line in $workflowToInspect -split "`r?`n") { - if ($Matches.reference -notmatch '^[0-9a-f]{40}$') + if ($line -match '^\s*uses:\s*(?[^@\s]+)@(?[^\s#]+)') { - throw "GitHub Action '$($Matches.action)' is not pinned to an immutable commit SHA." + if ($Matches.reference -notmatch '^[0-9a-f]{40}$') + { + throw "GitHub Action '$($Matches.action)' is not pinned to an immutable commit SHA." + } } } } @@ -76,6 +81,24 @@ try throw 'WinGet manifest generation does not accept only the current v1.0.2 public installer URL.' } + foreach ($required in @( + 'pull_request:', + 'Microsoft.WinGet.Client', + "-RequiredVersion '1.29.280'", + "Repair-WinGetPackageManager -Version '1.29.280' -Force", + "winget validate --manifest 'packaging\winget\1.0.2' --disable-interactivity" + )) + { + if (-not $wingetWorkflow.Contains($required)) + { + throw "WinGet workflow is missing required validator boundary '$required'." + } + } + if ($wingetWorkflow.Contains('Repair-WinGetPackageManager -Latest')) + { + throw 'WinGet workflow must pin the manifest validator instead of installing the latest version.' + } + Write-Host 'PASS: stable release workflow security and publication boundaries.' -ForegroundColor Green } catch From fe56659a67fc359e81e8c7bc8bc5cde46b25785e Mon Sep 17 00:00:00 2001 From: HelloThisWorld Date: Sun, 19 Jul 2026 21:20:30 +0800 Subject: [PATCH 2/3] fix: use the complete WinGet release tag --- .github/workflows/winget.yml | 2 +- scripts/winterm/test-release-workflow.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index 5f46631e8..c5f7929d3 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -66,7 +66,7 @@ jobs: -Scope CurrentUser ` -Force Import-Module Microsoft.WinGet.Client -RequiredVersion '1.29.280' -Force - Repair-WinGetPackageManager -Version '1.29.280' -Force + Repair-WinGetPackageManager -Version 'v1.29.280' -Force $winget = Get-Command winget.exe -ErrorAction Stop & $winget.Source --version diff --git a/scripts/winterm/test-release-workflow.ps1 b/scripts/winterm/test-release-workflow.ps1 index 42fc01169..872ffc658 100644 --- a/scripts/winterm/test-release-workflow.ps1 +++ b/scripts/winterm/test-release-workflow.ps1 @@ -85,7 +85,7 @@ try 'pull_request:', 'Microsoft.WinGet.Client', "-RequiredVersion '1.29.280'", - "Repair-WinGetPackageManager -Version '1.29.280' -Force", + "Repair-WinGetPackageManager -Version 'v1.29.280' -Force", "winget validate --manifest 'packaging\winget\1.0.2' --disable-interactivity" )) { From 567d762ddaed0a447f1c6b0a37b81ce7c20fe459 Mon Sep 17 00:00:00 2001 From: HelloThisWorld Date: Sun, 19 Jul 2026 21:22:49 +0800 Subject: [PATCH 3/3] fix: provision WinGet for all runner users --- .github/workflows/winget.yml | 2 +- scripts/winterm/test-release-workflow.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index c5f7929d3..9dc641389 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -66,7 +66,7 @@ jobs: -Scope CurrentUser ` -Force Import-Module Microsoft.WinGet.Client -RequiredVersion '1.29.280' -Force - Repair-WinGetPackageManager -Version 'v1.29.280' -Force + Repair-WinGetPackageManager -Version 'v1.29.280' -AllUsers -Force $winget = Get-Command winget.exe -ErrorAction Stop & $winget.Source --version diff --git a/scripts/winterm/test-release-workflow.ps1 b/scripts/winterm/test-release-workflow.ps1 index 872ffc658..c9faaf130 100644 --- a/scripts/winterm/test-release-workflow.ps1 +++ b/scripts/winterm/test-release-workflow.ps1 @@ -85,7 +85,7 @@ try 'pull_request:', 'Microsoft.WinGet.Client', "-RequiredVersion '1.29.280'", - "Repair-WinGetPackageManager -Version 'v1.29.280' -Force", + "Repair-WinGetPackageManager -Version 'v1.29.280' -AllUsers -Force", "winget validate --manifest 'packaging\winget\1.0.2' --disable-interactivity" )) {