# Release Process This document explains how TroubleScout releases are created, published, and submitted to WinGet. ## Tag-based Release Process TroubleScout uses a **tag-based** release process: the `release.yml` workflow is triggered when an annotated tag like `v1.3.0` is pushed to the repository. We intentionally avoid automatic tag creation so that releases are explicit and reviewers can verify changelogs and release notes before publishing. ### Normal Release Flow (Tag-based) 1. **Update version in `TroubleScout.csproj`**: ```xml 1.3.0 1.3.0.0 1.3.0.0 ``` 2. **Update the CHANGELOG**: - Add a new section for `v1.3.0` (include date and a short summary). - Follow the repo formatting rules: ensure a blank line before and after section headers so release tooling matches expected formatting. 3. **Create a PR that contains the version bump and CHANGELOG updates**: - Use the PR template checklist to confirm the changelog was updated. - Have changes reviewed and merged to `main` following normal branch protection rules. 4. **Create an annotated tag and push it to trigger the release**: ```bash git tag -a v1.3.0 -m "Release v1.3.0" git push origin v1.3.0 ``` 5. **Release publishes automatically**: - Pushing the tag triggers `.github/workflows/release.yml` which builds and packages the release. - A GitHub Release is created with packaged zip files for both architectures (e.g., `TroubleScout-v1.3.0-win-x64.zip` and `TroubleScout-v1.3.0-win-arm64.zip`). - If WinGet automation is configured, successful completion of `.github/workflows/release.yml` then triggers `.github/workflows/winget.yml`, which opens or updates the `winget-pkgs` PR for `sasler.TroubleScout`. ### Optional WinGet Automation TroubleScout can automatically create a `microsoft/winget-pkgs` PR after each published GitHub Release. The repository is configured to use [`vedantmgoyal9/winget-releaser`](https://github.com/vedantmgoyal9/winget-releaser) from a dedicated `.github/workflows/winget.yml` workflow triggered by successful completion of the `Release` workflow (plus optional manual dispatch). #### One-time setup 1. Fork `microsoft/winget-pkgs` under the same GitHub account or organization that owns this repository. 2. Create a **classic** GitHub Personal Access Token with `public_repo` scope. 3. Add the token to this repository as the `WINGET_TOKEN` secret. 4. Verify the existing WinGet package identifier remains `sasler.TroubleScout`. #### Why this workflow is separate - `winget-releaser` expects a **published** GitHub Release so the release assets are publicly available. - Keeping WinGet submission separate from `release.yml` makes retries easier when `winget-pkgs` validation fails for reasons outside this repository. - The Release workflow creates the GitHub Release with `GITHUB_TOKEN`, which does **not** fan out into a second `release`-triggered workflow run. Triggering `winget.yml` from `workflow_run` avoids that GitHub Actions limitation. - The workflow can also be run manually via **Actions -> Publish to WinGet** using a release tag like `v1.9.0`. ### Local WinGet Validation Helper Before opening or retrying a WinGet PR, you can generate a fresh TroubleScout manifest and validate it locally: ```powershell pwsh .\Tools\Validate-WinGetRelease.ps1 -Version 1.9.0 ``` To also run the official `winget-pkgs` sandbox test after validation, clone `microsoft/winget-pkgs` locally and pass its path: ```powershell pwsh .\Tools\Validate-WinGetRelease.ps1 -Version 1.9.0 -RunSandbox -WingetPkgsRoot C:\src\winget-pkgs ``` This helper: - downloads the x64 and arm64 GitHub release zips for the specified version - computes SHA256 hashes - generates temporary WinGet manifest files - runs `winget validate` - optionally runs `Tools\SandboxTest.ps1` from a local `winget-pkgs` clone ### Manual Release Tips - If you need to publish a hotfix, bump the version, update the changelog, merge the PR, and create a tag as above. - If the release workflow fails after tagging, check the `release.yml` workflow run in the Actions tab and inspect build logs. - If a tag already exists for a version, bump the version number for a new release. ### Troubleshooting **No release after creating a tag?** - Verify the tag was pushed: `git ls-remote --tags origin | grep v1.3.0` - Confirm the `release.yml` workflow ran: Check the Actions tab and the run triggered by your tag push - If build fails, review logs in the workflow and fix errors, then re-run the workflow if needed **GitHub Release succeeded, but no WinGet PR was created?** - Confirm `.github/workflows/winget.yml` exists on the default branch. - Verify the `WINGET_TOKEN` repository secret is configured. - Make sure the release is **published** and not a draft or prerelease. - Verify a fork of `microsoft/winget-pkgs` exists under the repo owner account. - Re-run the **Publish to WinGet** workflow manually with the release tag if needed. **Need to create a hotfix release?** - Update version in `TroubleScout.csproj` (e.g., 1.3.0 → 1.3.1) - Update `CHANGELOG.md` for the release - Merge to `main` and create an annotated tag to trigger the release ### Manual Release Recovery & Override If you need to recover from a failed release or create a release manually, follow these recovery steps. Creating annotated tags is the normal way to trigger releases; the guidance below helps when something goes wrong (bad tag, failed workflow, missing assets). #### 1. Create or recreate an annotated tag If you need to publish a release immediately, create an annotated tag and push it: ```powershell # Create and push an annotated tag git tag -a v1.0.1 -m "Release v1.0.1" git push origin v1.0.1 ``` If the tag was pushed erroneously and you need to recreate it: ```powershell # Delete local and remote tag, recreate and push git tag -d v1.0.1 git push origin :refs/tags/v1.0.1 git tag -a v1.0.1 -m "Release v1.0.1" git push origin v1.0.1 ``` #### 2. Re-run the release workflow If the release workflow failed after the tag was created, re-run the workflow from the **Actions** page: - Find the run triggered by the tag push and choose **Re-run jobs** (or **Re-run failed jobs**) to retry the build and publish steps. - If logs show a reproducible failure, fix the underlying issue and then recreate the tag (delete and re-create the tag) to trigger a fresh run. #### 2a. Re-run the WinGet submission workflow If the GitHub Release succeeded but the WinGet submission failed or did not start: - Open the **Publish to WinGet** workflow in the Actions tab. - Use **Run workflow** and provide the release tag (for example `v1.9.0`). - If the workflow opens a `winget-pkgs` PR and the community validation later fails, treat that separately from TroubleScout's own release build. #### 3. Re-publish release assets (if needed) If the release completed but assets are missing or corrupted, you can recreate the release assets and upload them manually: - Rebuild the package locally as described in the build steps and create both zips (e.g., `TroubleScout-v1.9.0-win-x64.zip`, `TroubleScout-v1.9.0-win-arm64.zip`). - Upload the assets via the GitHub UI on the release page, or use the GitHub CLI: ```bash # Create or update a GitHub release with assets gh release create v1.0.1 "dist/TroubleScout-v1.0.1-win-x64.zip" --notes "Release v1.0.1" # Add arm64 asset gh release upload v1.0.1 "dist/TroubleScout-v1.0.1-win-arm64.zip" ``` #### 4. Notes & best practices - Prefer recreating and re-pushing an annotated tag to trigger a clean release run instead of manually attempting to patch runs. - Use the Actions logs to identify root causes before re-running. - If you need a temporary manual trigger without creating a permanent tag, create a timestamped tag (e.g., `v1.0.1-rc1`) and delete it after verification. - WinGet community validation failures are common enough that a failed `winget-pkgs` run does not automatically mean the TroubleScout release packaging is wrong. Re-run and inspect the external validation details before changing the app. - Keep the current portable one-EXE release strategy unless local validation or a reproducible WinGet-specific failure proves that TroubleScout itself needs a behavioral change. You can monitor workflow runs at: `https://github.com/sasler/TroubleScout/actions` ### Release Package Contents Each release includes two zip files named `TroubleScout-v{version}-win-x64.zip` and `TroubleScout-v{version}-win-arm64.zip` containing: - `TroubleScout.exe` - Self-contained executable (~54 MB) - `runtimes/` (when present) - PowerShell SDK native dependencies **Important**: Extract the full zip contents together. Some releases include `runtimes/` files and some do not, depending on publish output. ### Version Numbering TroubleScout follows semantic versioning (MAJOR.MINOR.PATCH): - **MAJOR**: Breaking changes or significant rewrites - **MINOR**: New features, backwards-compatible - **PATCH**: Bug fixes, performance improvements, backwards-compatible When updating the version in `TroubleScout.csproj`, choose the appropriate bump based on your changes. ### Post-Release Troubleshooting **No tag created after version update?** - Verify the change to `TroubleScout.csproj` was pushed to main - Make sure a release tag was created and pushed (we no longer create tags automatically) - Look for errors in the workflow logs - Verify the tag doesn't already exist: `git tag -l` **Tag already exists for version?** - The workflow will skip tag creation if it already exists - To create a new release, bump the version number in `TroubleScout.csproj` - Commit and push the updated version **Release workflow fails after tag creation?** - Verify `release.yml` workflow ran: Check Actions tab - Review build errors in workflow logs - If build fails, fix the issue and manually re-run the workflow from the Actions tab **WinGet validation fails after the PR is opened?** - Check the `winget-pkgs` PR and its linked Azure validation run. - Re-run the WinGet submission workflow if the first submission failed before opening the PR. - If the PR exists but validation failed, prefer re-running the `winget-pkgs` validation (`@wingetbot run`) or updating the manifest PR rather than cutting a brand-new TroubleScout release unless the release assets themselves changed. **Need to create a hotfix release?** - Update version in `TroubleScout.csproj` (e.g., 1.2.0 → 1.2.1) - Commit and push to main - Create an annotated tag and push it to trigger the release (see steps above)