Skip to content

Add WinGet packaging for Windows - #216

Merged
fernandotonon merged 5 commits into
masterfrom
feature/winget-packaging
Mar 24, 2026
Merged

Add WinGet packaging for Windows#216
fernandotonon merged 5 commits into
masterfrom
feature/winget-packaging

Conversation

@fernandotonon

@fernandotonon fernandotonon commented Mar 24, 2026

Copy link
Copy Markdown
Owner

Summary

Adds WinGet (Windows Package Manager) support so Windows users can install with:

winget install FernandoTonon.QtMeshEditor

What's included

WinGet manifest (winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/):

  • Version, locale (en-US), and installer YAML
  • Portable zip installer type — registers qtmesheditor and qtmesh commands
  • SHA256 hash of the 2.16.0 Windows zip

CI automation (deploy.ymlwinget-publish job):

  • Runs on release: published events
  • Uses wingetcreate to auto-submit updated manifest PR to microsoft/winget-pkgs
  • Requires WINGET_TOKEN secret (GitHub PAT with public_repo scope to fork winget-pkgs)

Helper script (scripts/update-winget.sh):

  • Generates manifest locally: ./scripts/update-winget.sh 2.16.0
  • Downloads zip, computes SHA256, creates all 3 YAML files

Documentation updates:

  • docs/index.html — Windows section now shows winget install command
  • README.md — Windows section updated with winget install/upgrade
  • CLAUDE.md — new WinGet section with key files and update process

Setup required

Add a WINGET_TOKEN repository secret — a GitHub Personal Access Token with public_repo scope. This is needed for wingetcreate to fork microsoft/winget-pkgs and submit PRs.

First submission

After merging, the initial manifest needs to be submitted manually to microsoft/winget-pkgs (the CI job will handle future releases automatically). Use:

./scripts/update-winget.sh 2.16.0

Then copy the generated manifests to a fork of winget-pkgs and submit a PR.

Test plan

  • Manifest YAML validates against WinGet schema
  • Build clean
  • CI passes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • WinGet distribution: install with winget install FernandoTonon.QtMeshEditor and upgrade with winget upgrade FernandoTonon.QtMeshEditor.
    • Windows now provides a standalone CLI launcher executable for invoking the app in CLI mode.
  • Documentation

    • Updated Windows install docs and site to show WinGet commands while keeping the zip download alternative.
    • Added WinGet distribution notes and release guidance.
  • Chores

    • Added manifest generation tooling and automatic WinGet submission to the release workflow.

WinGet manifest:
- winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/ — version,
  locale, and installer YAML for portable zip install
- Registers both QtMeshEditor.exe and qtmesh.cmd as portable commands

CI automation:
- winget-publish job in deploy.yml — runs wingetcreate on release to
  auto-submit updated manifest to microsoft/winget-pkgs
- Requires WINGET_TOKEN secret (GitHub PAT with public_repo scope)

Helper script:
- scripts/update-winget.sh — generates manifest locally with SHA256 hash

Documentation:
- docs/index.html: Windows section updated with winget install command
- README.md: Windows section updated with winget install/upgrade
- CLAUDE.md: new WinGet section, updated CI/CD description

Users can now install with: winget install FernandoTonon.QtMeshEditor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@fernandotonon has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 13 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40e6bbba-b4e4-491e-a2e4-712591480ad9

📥 Commits

Reviewing files that changed from the base of the PR and between 2217262 and ff1288a.

📒 Files selected for processing (4)
  • CMakeLists.txt
  • winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.1/FernandoTonon.QtMeshEditor.installer.yaml
  • winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.1/FernandoTonon.QtMeshEditor.locale.en-US.yaml
  • winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.1/FernandoTonon.QtMeshEditor.yaml
📝 Walkthrough

Walkthrough

Adds WinGet distribution support: CI job to auto-submit updates on release, a script to generate WinGet manifests and compute SHA256, initial manifests for v2.16.0, a compiled qtmesh launcher for Windows, and documentation/README updates to recommend WinGet installation.

Changes

Cohort / File(s) Summary
CI/CD Workflow
/.github/workflows/deploy.yml
Adds winget-publish job (runs after build-windows, conditional on release published) that downloads wingetcreate.exe and runs wingetcreate update --version $version --urls $url --submit --token ${{ secrets.WINGET_TOKEN }} with continue-on-error.
Manifest Generation Script
scripts/update-winget.sh
New executable script: accepts <version>, derives GitHub release ZIP URL, downloads and computes SHA256, validates hash, creates winget/manifests/.../<version>/ and writes version, default-locale, and installer YAML manifests; prints submission instructions.
WinGet Manifests
winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/*
Adds three manifests for v2.16.0: version manifest (*.yaml), default-locale (*.locale.en-US.yaml) with metadata/moniker/license, and installer manifest (*.installer.yaml) specifying a zip installer with portable nested executables (QtMeshEditor.exe, qtmesh.exe) and checksum.
Launcher & Build
src/CMakeLists.txt, src/qtmesh_launcher.cpp
On Windows, replaces .cmd wrapper with a compiled qtmesh launcher target and adds qtmesh_launcher.cpp implementing re-exec behavior to run the main binary in --cli mode (Windows via CreateProcess, non-Windows via execv fallback).
Documentation & README
README.md, CLAUDE.md, docs/index.html
Updates Windows installation instructions to recommend winget install FernandoTonon.QtMeshEditor and winget upgrade ..., documents WinGet distribution and CI integration, and retains .zip release download alternative.

Sequence Diagram

sequenceDiagram
    participant Release as Release Event
    participant GH as GitHub Actions
    participant Artifact as Release Artifact Storage
    participant WinGet as WinGet Service

    Release->>GH: release published (tag)
    GH->>GH: run build-windows
    GH->>Artifact: upload Windows ZIP artifact
    GH->>GH: trigger winget-publish job (if release published)
    GH->>GH: download wingetcreate.exe
    GH->>GH: derive ZIP URL & compute SHA256 (scripts/update-winget.sh)
    GH->>WinGet: wingetcreate update --version $version --urls $url --submit --token $WINGET_TOKEN
    WinGet-->>GH: accept or return error (continue-on-error)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰
I hopped through CI at break of day,
Wrote manifests, checksums, a script to play.
Winget doors swing open, versions glide—
QtMesh hops in, installs with pride.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add WinGet packaging for Windows' clearly and concisely describes the primary change—adding WinGet package manager support. It is specific, directly related to the main changeset, and avoids vague terms.
Description check ✅ Passed The PR description provides comprehensive coverage including a summary, detailed what's included section, setup requirements, and test plan. While it deviates from the template structure (no explicit 'Technical Details', 'Features', or 'Bugfixes' sections), the content is well-organized and complete.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/winget-packaging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
README.md (1)

172-174: Add language identifier to fenced code block.

The fenced code block is missing a language identifier. For consistency with other code blocks in this file and proper syntax highlighting, specify a language.

Suggested fix
-```
+```shell
 winget install FernandoTonon.QtMeshEditor
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 172 - 174, The fenced code block containing the
command "winget install FernandoTonon.QtMeshEditor" is missing a language
identifier; update that block to include a language (e.g., use "shell" or
"bash") by changing the opening fence from toshell so the command is
consistently highlighted with other blocks in README.md.


</details>

</blockquote></details>
<details>
<summary>scripts/update-winget.sh (1)</summary><blockquote>

`27-31`: **Consider portability: `shasum` may not be available on all systems.**

The script uses `shasum -a 256` which is standard on macOS but may not be available on some Linux distributions where `sha256sum` is the common alternative.


<details>
<summary>Suggested portable fix</summary>

```diff
 # Compute SHA256
 echo "Downloading and computing SHA256..."
-SHA256=$(curl -sL "${ZIP_URL}" | shasum -a 256 | cut -d' ' -f1 | tr 'a-f' 'A-F')
+if command -v shasum &>/dev/null; then
+    SHA256=$(curl -sL "${ZIP_URL}" | shasum -a 256 | cut -d' ' -f1 | tr 'a-f' 'A-F')
+elif command -v sha256sum &>/dev/null; then
+    SHA256=$(curl -sL "${ZIP_URL}" | sha256sum | cut -d' ' -f1 | tr 'a-f' 'A-F')
+else
+    echo "ERROR: Neither shasum nor sha256sum found"
+    exit 1
+fi
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@scripts/update-winget.sh` around lines 27 - 31, The SHA256 computation uses
shasum (SHA256=$(curl -sL "${ZIP_URL}" | shasum -a 256 ...)) which is not
available on all systems; update the script to detect and use an available tool
(prefer sha256sum, fall back to shasum, then openssl dgst -sha256) to compute
the checksum, and set SHA256 accordingly, preserving the existing uppercase
conversion and empty-check logic; reference the SHA256 variable and ZIP_URL
variable so the detection/selection logic appears before the existing SHA256
assignment and uses the chosen command to produce the same single-token hex
output.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @README.md:

  • Around line 172-174: The fenced code block containing the command "winget
    install FernandoTonon.QtMeshEditor" is missing a language identifier; update
    that block to include a language (e.g., use "shell" or "bash") by changing the
    opening fence from toshell so the command is consistently highlighted
    with other blocks in README.md.

In @scripts/update-winget.sh:

  • Around line 27-31: The SHA256 computation uses shasum (SHA256=$(curl -sL
    "${ZIP_URL}" | shasum -a 256 ...)) which is not available on all systems; update
    the script to detect and use an available tool (prefer sha256sum, fall back to
    shasum, then openssl dgst -sha256) to compute the checksum, and set SHA256
    accordingly, preserving the existing uppercase conversion and empty-check logic;
    reference the SHA256 variable and ZIP_URL variable so the detection/selection
    logic appears before the existing SHA256 assignment and uses the chosen command
    to produce the same single-token hex output.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `de76b25d-1b7e-4df4-ab7b-ee90ac221ce5`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 88da7e7c95e0984e40614acf47c124da906dcf6f and df00e8a5cf5255b6b1536dee4ec0fc2d5c23449a.

</details>

<details>
<summary>📒 Files selected for processing (8)</summary>

* `.github/workflows/deploy.yml`
* `CLAUDE.md`
* `README.md`
* `docs/index.html`
* `scripts/update-winget.sh`
* `winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/FernandoTonon.QtMeshEditor.installer.yaml`
* `winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/FernandoTonon.QtMeshEditor.locale.en-US.yaml`
* `winget/manifests/f/FernandoTonon/QtMeshEditor/2.16.0/FernandoTonon.QtMeshEditor.yaml`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df00e8a5cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/update-winget.sh

# Compute SHA256
echo "Downloading and computing SHA256..."
SHA256=$(curl -sL "${ZIP_URL}" | shasum -a 256 | cut -d' ' -f1 | tr 'a-f' 'A-F')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle HTTP errors before hashing release artifact

The hash computation uses curl -sL without -f, so a 404/500 response still produces output and gets hashed as if it were the Windows zip. Because the subsequent guard only checks whether the hash string is empty, a typoed/unpublished version will generate a manifest with an invalid InstallerSha256 instead of failing fast, which can break WinGet submissions and make debugging harder.

Useful? React with 👍 / 👎.

fernandotonon and others added 4 commits March 24, 2026 13:11
Microsoft's validation bot requires ManifestVersion 1.12.0.
Updated all three manifest files and the update-winget.sh script.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WinGet validation rejects .cmd as a NestedInstallerFiles entry.
Only the .exe portable is registered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WinGet portable manifests don't allow .cmd files. Instead of a
batch wrapper, build a tiny qtmesh.exe that launches
QtMeshEditor.exe --cli with the original arguments. This gives
Windows users the same `qtmesh` CLI alias as Linux/macOS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New release includes qtmesh.exe launcher for Windows so WinGet
can register both qtmesheditor and qtmesh portable commands.
SHA256 placeholder will be updated after CI builds the release.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@fernandotonon
fernandotonon merged commit c2ced18 into master Mar 24, 2026
4 checks passed
@fernandotonon
fernandotonon deleted the feature/winget-packaging branch March 24, 2026 18:14
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant