Create initial GitHub Actions CI/CD and WinGet submission#8
Create initial GitHub Actions CI/CD and WinGet submission#8sirredbeard wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces the initial CI/CD pipeline for the CopilotTaskbarApp project using GitHub Actions. It adds three workflows: a build workflow triggered on pull requests and reusable for releases, a release workflow to orchestrate the full build/tag/publish flow, and a WinGet submission workflow to automate publishing to the Windows Package Manager repository.
Changes:
- Added
.github/workflows/build.yml: Reusable build workflow that compiles and packages the app forx64andARM64, conditionally producing ZIP artifacts when aversioninput is provided. - Added
.github/workflows/release.yml: Orchestration workflow (triggered viaworkflow_dispatch) that callsbuild.yml, creates a git tag, creates a GitHub Release with assets, and callswinget-release.ymlfor WinGet submission. - Added
.github/workflows/winget-release.yml: Reusable workflow that downloads release assets, computes SHA256 hashes, generates WinGet manifests, and submits them usingwingetcreate.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
.github/workflows/build.yml |
Build + artifact upload workflow triggered by PRs and reusable for release |
.github/workflows/release.yml |
Release orchestration: tag creation, GitHub Release creation, and WinGet submission |
.github/workflows/winget-release.yml |
WinGet manifest generation and submission to the public winget-pkgs repo |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/release.yml
Outdated
| outputs: | ||
| tag: v${{ inputs.version }} |
There was a problem hiding this comment.
The outputs block on the release job (lines 23–24) declares tag: v${{ inputs.version }}, but this output is never referenced by any downstream job. The winget job uses v${{ inputs.version }} directly rather than needs.release.outputs.tag. This dead code adds confusion about whether the output is meant to be used and should be removed.
| outputs: | |
| tag: v${{ inputs.version }} |
.github/workflows/winget-release.yml
Outdated
| Invoke-WebRequest "https://aka.ms/wingetcreate/latest" -OutFile wingetcreate.exe | ||
|
|
There was a problem hiding this comment.
The wingetcreate binary is downloaded from the unversioned, un-pinned redirect https://aka.ms/wingetcreate/latest, and no integrity check (e.g., SHA256 verification) is performed on the downloaded binary. This means: (1) any future change to that binary could silently break the workflow or, in a worst-case supply-chain compromise scenario, execute arbitrary code; (2) builds are not reproducible since the binary version can change at any time. Consider downloading a specific versioned release from the official GitHub Releases page (e.g., https://github.com/microsoft/winget-create/releases/download/vX.Y.Z/wingetcreate.exe) and verifying its SHA256 hash before executing it.
| Invoke-WebRequest "https://aka.ms/wingetcreate/latest" -OutFile wingetcreate.exe | |
| $wingetCreateVersion = "v1.5.5" # TODO: update to desired pinned version | |
| $expectedHash = "EXPECTED_SHA256_HERE" # TODO: replace with SHA256 of wingetcreate.exe for the pinned version | |
| $wingetCreateUrl = "https://github.com/microsoft/winget-create/releases/download/$wingetCreateVersion/wingetcreate.exe" | |
| Invoke-WebRequest $wingetCreateUrl -OutFile wingetcreate.exe | |
| $actualHash = (Get-FileHash "wingetcreate.exe" -Algorithm SHA256).Hash.ToLowerInvariant() | |
| if ($actualHash -ne $expectedHash.ToLowerInvariant()) { | |
| Write-Error "SHA256 hash mismatch for wingetcreate.exe. Expected $expectedHash but got $actualHash." | |
| exit 1 | |
| } |
.github/workflows/winget-release.yml
Outdated
| $version = "${{ steps.version.outputs.version }}" | ||
| $dir = "manifests/s/sirredbeard/CopilotTaskbarApp/$version" | ||
|
|
||
| .\wingetcreate.exe submit --token "${{ secrets.WINGET_PAT }}" $dir |
There was a problem hiding this comment.
The $dir argument passed to wingetcreate.exe is unquoted. While the version value is controlled via workflow inputs, quoting the path argument (e.g., .\wingetcreate.exe submit --token "${{ secrets.WINGET_PAT }}" "$dir") is a best practice to guard against unexpected behavior if the path were to contain spaces or special characters in the future.
| .\wingetcreate.exe submit --token "${{ secrets.WINGET_PAT }}" $dir | |
| .\wingetcreate.exe submit --token "${{ secrets.WINGET_PAT }}" "$dir" |
.github/workflows/winget-release.yml
Outdated
| release: | ||
| types: [released] |
There was a problem hiding this comment.
The winget-release.yml workflow is triggered both by the release event (lines 3–5) and as a reusable workflow called from release.yml. Since release.yml creates a GitHub Release (which fires the released event), the WinGet submission will be triggered twice: once via workflow_call from release.yml, and once by the release event trigger in winget-release.yml itself. This will cause duplicate (and likely failing) WinGet submissions. Consider removing the release event trigger from winget-release.yml and relying solely on the workflow_call from release.yml, or alternatively remove the workflow_call from release.yml and keep only the release event trigger.
| release: | |
| types: [released] |
- build.yml: PR validation and reusable build for x64/ARM64 - Matrix strategy with win-x64 and win-arm64 runtime identifiers - .NET 11 Preview SDK setup - Conditional publish and artifact upload when called with version input - Permissions scoped to contents: read - Concurrency group cancels stale PR builds - release.yml: Manual release orchestrator (workflow_dispatch) - Calls build.yml with version input - Creates git tag and GitHub Release with exe binaries - Chains to winget-release.yml for WinGet submission - winget-release.yml: Reusable WinGet package submission - Downloads release exe assets and computes SHA256 hashes - Generates version, locale, and installer manifests - Portable installer type for standalone exe distribution - wingetcreate pinned to v1.10.3.0 with SHA256 verification - Secrets passed explicitly (WINGET_PAT)
No description provided.