fix(msix): use full Partner Center identity for Store submission - #1044
Conversation
The Microsoft Store validates every Package/Identity field strictly (it does not remap Name/Publisher on ingestion, contrary to an earlier assumption), so the v1.9.0 MSIX was rejected for an invalid identity name, publisher, family name, and an unreserved Properties/DisplayName. - Default the build to the opengeos Partner Center identity: Name OpenGeospatialSolutions.GeoLibre, Publisher CN=E6AE8172-..., DisplayName GeoLibre (reserved). PublisherDisplayName was already correct. - Add a workflow_dispatch "Build Store MSIX" workflow that builds the package and uploads it as an artifact, so a Store-ready MSIX can be produced on demand without re-publishing a GitHub release. - Document the new defaults in the packaging README.
✅ Deploy Preview for geolibre-app ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughAdds a new GitHub Actions workflow to build a Store-ready MSIX package via manual dispatch, updates the MSIX packaging script's default Publisher/Name/DisplayName values to reserved Microsoft Store identity values, and revises the README to document these new defaults. ChangesStore MSIX Build
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant GHA as GitHub Actions
participant Tauri as Tauri Build
participant Script as build-msix.ps1
participant Artifact as Workflow Artifact
Dev->>GHA: Trigger workflow_dispatch
GHA->>Tauri: npm run tauri:build --no-sign
Tauri-->>GHA: release binary
GHA->>Script: Run with Store identity defaults
Script-->>GHA: msix_path output
GHA->>Artifact: Upload geolibre-store-msix
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
⚡ Cloudflare Pages preview
|
There was a problem hiding this comment.
Pull request overview
Fixes Microsoft Store submission rejections by aligning MSIX Package/Identity (and Properties/DisplayName) defaults with the reserved Partner Center identity, and adds an on-demand GitHub Actions workflow to generate a Store-ready MSIX artifact without publishing a release.
Changes:
- Update
packaging/msix/build-msix.ps1defaults to the Partner CenterName,Publisher, and reservedDisplayNamerequired for Store ingestion. - Update
packaging/msix/README.mdidentity table to reflect the Store identity defaults and override guidance. - Add
.github/workflows/msix-store.yml(workflow_dispatch) to build and upload a Store MSIX as a workflow artifact.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packaging/msix/README.md | Updates MSIX identity documentation/table for Store identity defaults and override notes. |
| packaging/msix/build-msix.ps1 | Switches MSIX manifest identity/display-name defaults to the reserved Partner Center values and preserves override behavior via empty-string fallback. |
| .github/workflows/msix-store.yml | Adds a manual workflow to build the Tauri app, run MSIX packaging, and upload the resulting MSIX as an artifact. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| The defaults are the opengeos Partner Center identity, so a bare | ||
| `./build-msix.ps1` produces a Store-ready package. Override them for a | ||
| self-signed sideload build or a different publisher. |
| # Identity/Publisher. The Microsoft Store validates this against the account's | ||
| # publisher ID, so it must be the seller CN=<GUID> from Partner Center | ||
| # (Product Identity), not a friendly name. Override for a self-signed sideload | ||
| # build. | ||
| [string] $Publisher = "CN=E6AE8172-DC4F-4F79-844B-9D84204BF95A", | ||
| # Properties/PublisherDisplayName. The Microsoft Store validates this strictly | ||
| # against the registered publisher display name, so it must match Partner | ||
| # Center exactly ("Open Geospatial Solutions"). Unlike Identity Name/Publisher, | ||
| # the Store does not remap it on ingestion. | ||
| [string] $PublisherDisplayName = "Open Geospatial Solutions", | ||
| # Identity Name. Defaults to the Tauri identifier; override with the reserved | ||
| # package name from Partner Center (Product Identity) for a Microsoft Store | ||
| # submission. | ||
| [string] $Name = "", | ||
| # Package display name (Properties/DisplayName). Defaults to the Tauri | ||
| # productName; for a Microsoft Store submission it must be a name you reserved | ||
| # in Partner Center (e.g. "GeoLibre"), which may differ from the product name. | ||
| [string] $DisplayName = "", | ||
| # Identity Name. Must be the reserved package name from Partner Center | ||
| # (Product Identity) for a Microsoft Store submission; the Store rejects the | ||
| # Tauri identifier. Pass "" to fall back to the Tauri identifier for a | ||
| # non-Store build. | ||
| [string] $Name = "OpenGeospatialSolutions.GeoLibre", | ||
| # Package display name (Properties/DisplayName). For a Microsoft Store | ||
| # submission it must be a name you reserved in Partner Center ("GeoLibre"), | ||
| # which differs from the Tauri productName ("GeoLibre Desktop"). Pass "" to | ||
| # fall back to the productName for a non-Store build. | ||
| [string] $DisplayName = "GeoLibre", |
There was a problem hiding this comment.
Bug (high confidence): release.yml's "Build MSIX package" step invokes this script with no parameters (./packaging/msix/build-msix.ps1), so it relies entirely on these defaults. Before this PR, the parameterless call produced the "self-signed / direct-download" MSIX described in the README (Tauri identifier for Name, CN=GeoLibre for Publisher, Tauri productName for DisplayName). After this PR, every future GitHub release's MSIX will silently carry the Microsoft Store's reserved identity (OpenGeospatialSolutions.GeoLibre / CN=E6AE8172-... / GeoLibre) as well, since release.yml was not updated to pass overrides.
That has real consequences beyond documentation drift:
- The package family name (derived from
Name+Publisher) for the GitHub-release MSIX now matches the Store package's family name. If a user has the Store build installed and then sideloads (or updates via) the GitHub-release MSIX, Windows will treat it as an update to the same package family — which will fail unless it's signed with a certificate whose Subject matchesCN=E6AE8172-...(which only the Store can produce during ingestion). - This isn't mentioned anywhere in the PR description, which only discusses the new on-demand Store workflow.
Consider either passing explicit overrides from release.yml's step (e.g. -Publisher "CN=GeoLibre" -Name "" -DisplayName "") to preserve the previous direct-download identity, or — if unifying the identity across both distribution channels is actually intended — call that out explicitly and update the README section that still describes the old defaults (see comment on README.md).
| The defaults are the opengeos Partner Center identity, so a bare | ||
| `./build-msix.ps1` produces a Store-ready package. Override them for a | ||
| self-signed sideload build or a different publisher. |
There was a problem hiding this comment.
This directly contradicts the still-unedited intro above (lines 10-12), which says the release.yml "Build MSIX package" step — the one that runs "a bare ./build-msix.ps1" — produces the self-signed / winget MSIX with Publisher = CN=GeoLibre and Tauri-config identity. Now that "a bare ./build-msix.ps1 produces a Store-ready package" (this line), release.yml's parameterless invocation will also produce the Store-identity package, since it has no overrides. Please reconcile: either update the intro section to reflect that both invocations now share the Store identity, or update release.yml to pass the old direct-download overrides so the two paragraphs describe consistent behavior.
Code reviewBugs
Security
Performance
Quality
CLAUDE.md
|
| # Identity/Publisher. The Microsoft Store validates this against the account's | ||
| # publisher ID, so it must be the seller CN=<GUID> from Partner Center | ||
| # (Product Identity), not a friendly name. Override for a self-signed sideload | ||
| # build. | ||
| [string] $Publisher = "CN=E6AE8172-DC4F-4F79-844B-9D84204BF95A", | ||
| # Properties/PublisherDisplayName. The Microsoft Store validates this strictly | ||
| # against the registered publisher display name, so it must match Partner | ||
| # Center exactly ("Open Geospatial Solutions"). Unlike Identity Name/Publisher, | ||
| # the Store does not remap it on ingestion. | ||
| [string] $PublisherDisplayName = "Open Geospatial Solutions", | ||
| # Identity Name. Defaults to the Tauri identifier; override with the reserved | ||
| # package name from Partner Center (Product Identity) for a Microsoft Store | ||
| # submission. | ||
| [string] $Name = "", | ||
| # Package display name (Properties/DisplayName). Defaults to the Tauri | ||
| # productName; for a Microsoft Store submission it must be a name you reserved | ||
| # in Partner Center (e.g. "GeoLibre"), which may differ from the product name. | ||
| [string] $DisplayName = "", | ||
| # Identity Name. Must be the reserved package name from Partner Center | ||
| # (Product Identity) for a Microsoft Store submission; the Store rejects the | ||
| # Tauri identifier. Pass "" to fall back to the Tauri identifier for a | ||
| # non-Store build. | ||
| [string] $Name = "OpenGeospatialSolutions.GeoLibre", | ||
| # Package display name (Properties/DisplayName). For a Microsoft Store | ||
| # submission it must be a name you reserved in Partner Center ("GeoLibre"), | ||
| # which differs from the Tauri productName ("GeoLibre Desktop"). Pass "" to | ||
| # fall back to the productName for a non-Store build. | ||
| [string] $DisplayName = "GeoLibre", |
There was a problem hiding this comment.
Bug (high confidence): release.yml's "Build MSIX package" step invokes this script with no parameters (./packaging/msix/build-msix.ps1), so it relies entirely on these defaults. Before this PR, the parameterless call produced the "self-signed / direct-download" MSIX described in the README (Tauri identifier for Name, CN=GeoLibre for Publisher, Tauri productName for DisplayName). After this PR, every future GitHub release's MSIX will silently carry the Microsoft Store's reserved identity (OpenGeospatialSolutions.GeoLibre / CN=E6AE8172-... / GeoLibre) as well, since release.yml was not updated to pass overrides.
That has real consequences beyond documentation drift:
- The package family name (derived from
Name+Publisher) for the GitHub-release MSIX now matches the Store package's family name. If a user has the Store build installed and then sideloads (or updates via) the GitHub-release MSIX, Windows will treat it as an update to the same package family — which will fail unless it's signed with a certificate whose Subject matchesCN=E6AE8172-...(which only the Store can produce during ingestion). - This isn't mentioned anywhere in the PR description, which only discusses the new on-demand Store workflow.
Consider either passing explicit overrides from release.yml's step (e.g. -Publisher "CN=GeoLibre" -Name "" -DisplayName "") to preserve the previous direct-download identity, or — if unifying the identity across both distribution channels is actually intended — call that out explicitly and update the README section that still describes the old defaults (see comment on README.md).
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/msix-store.yml:
- Around line 19-20: The Checkout repository step currently leaves Git
credentials available to later steps; update the actions/checkout usage in the
workflow to disable credential persistence by setting persist-credentials to
false on the checkout action. Keep the fix localized to the checkout step so npm
ci, cargo build, and MakeAppx run without the token being retained.
- Around line 29-30: The GitHub Actions step using dtolnay/rust-toolchain is
still referenced by a floating tag, which violates the repo’s pinning policy for
third-party actions. Update the Install Rust stable step in the workflow to use
dtolnay/rust-toolchain pinned to a specific commit SHA instead of `@stable`, and
keep the rest of the step unchanged.
In `@packaging/msix/build-msix.ps1`:
- Around line 6-25: The release workflow is still invoking the MSIX build with
only the default Store identity values, so the non-Store package needs explicit
overrides. Update the release job in the GitHub Actions workflow to pass the
sideload/self-signed values into build-msix.ps1, using the script’s Publisher,
PublisherDisplayName, Name, and DisplayName parameters so the released MSIX
matches the direct-download package.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9e3ddcd7-a21c-46e7-bf5f-d3b6c3b631de
📒 Files selected for processing (3)
.github/workflows/msix-store.ymlpackaging/msix/README.mdpackaging/msix/build-msix.ps1
| - name: Checkout repository | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | 💤 Low value
Consider disabling credential persistence on checkout.
The checkout step doesn't set persist-credentials: false; the token stays available to all subsequent steps (npm ci, cargo build, MakeAppx), including any third-party build-time code. Given permissions: contents: read, impact is limited, but it's a low-cost hardening step.
Suggested fix
- name: Checkout repository
uses: actions/checkout@v6
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 19-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 20-20: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/msix-store.yml around lines 19 - 20, The Checkout
repository step currently leaves Git credentials available to later steps;
update the actions/checkout usage in the workflow to disable credential
persistence by setting persist-credentials to false on the checkout action. Keep
the fix localized to the checkout step so npm ci, cargo build, and MakeAppx run
without the token being retained.
Source: Linters/SAST tools
| - name: Install Rust stable | ||
| uses: dtolnay/rust-toolchain@stable |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin dtolnay/rust-toolchain to a commit SHA.
Based on learnings, this repo's policy requires pinning third-party uses: references (e.g. dtolnay/rust-toolchain@<sha>) to a commit SHA, while first-party actions/* refs may stay tag-pinned. @stable here is a floating third-party ref and doesn't meet that bar.
Suggested fix
- - name: Install Rust stable
- uses: dtolnay/rust-toolchain@stable
+ - name: Install Rust stable
+ uses: dtolnay/rust-toolchain@<pinned-sha> # stable🧰 Tools
🪛 zizmor (1.26.1)
[error] 30-30: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 30-30: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step
(superfluous-actions)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/msix-store.yml around lines 29 - 30, The GitHub Actions
step using dtolnay/rust-toolchain is still referenced by a floating tag, which
violates the repo’s pinning policy for third-party actions. Update the Install
Rust stable step in the workflow to use dtolnay/rust-toolchain pinned to a
specific commit SHA instead of `@stable`, and keep the rest of the step unchanged.
Sources: Learnings, Linters/SAST tools
| # Identity/Publisher. The Microsoft Store validates this against the account's | ||
| # publisher ID, so it must be the seller CN=<GUID> from Partner Center | ||
| # (Product Identity), not a friendly name. Override for a self-signed sideload | ||
| # build. | ||
| [string] $Publisher = "CN=E6AE8172-DC4F-4F79-844B-9D84204BF95A", | ||
| # Properties/PublisherDisplayName. The Microsoft Store validates this strictly | ||
| # against the registered publisher display name, so it must match Partner | ||
| # Center exactly ("Open Geospatial Solutions"). Unlike Identity Name/Publisher, | ||
| # the Store does not remap it on ingestion. | ||
| [string] $PublisherDisplayName = "Open Geospatial Solutions", | ||
| # Identity Name. Defaults to the Tauri identifier; override with the reserved | ||
| # package name from Partner Center (Product Identity) for a Microsoft Store | ||
| # submission. | ||
| [string] $Name = "", | ||
| # Package display name (Properties/DisplayName). Defaults to the Tauri | ||
| # productName; for a Microsoft Store submission it must be a name you reserved | ||
| # in Partner Center (e.g. "GeoLibre"), which may differ from the product name. | ||
| [string] $DisplayName = "", | ||
| # Identity Name. Must be the reserved package name from Partner Center | ||
| # (Product Identity) for a Microsoft Store submission; the Store rejects the | ||
| # Tauri identifier. Pass "" to fall back to the Tauri identifier for a | ||
| # non-Store build. | ||
| [string] $Name = "OpenGeospatialSolutions.GeoLibre", | ||
| # Package display name (Properties/DisplayName). For a Microsoft Store | ||
| # submission it must be a name you reserved in Partner Center ("GeoLibre"), | ||
| # which differs from the Tauri productName ("GeoLibre Desktop"). Pass "" to | ||
| # fall back to the productName for a non-Store build. | ||
| [string] $DisplayName = "GeoLibre", |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd release.yml .github/workflows --exec cat -n {}Repository: opengeos/GeoLibre
Length of output: 16937
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== packaging/msix/build-msix.ps1 ==\n'
cat -n packaging/msix/build-msix.ps1 | sed -n '1,220p'
printf '\n== README mentions of release.yml / MSIX ==\n'
rg -n -A3 -B3 'release\.yml|Build MSIX package|MSIX|self-signed|winget' README* .github/workflows packaging -g '!**/node_modules/**'Repository: opengeos/GeoLibre
Length of output: 32411
Pass the non-Store MSIX overrides in .github/workflows/release.yml. build-msix.ps1 now defaults to the Store identity values, but the release workflow still calls it with no arguments, so the GitHub release MSIX will no longer be the self-signed package expected for direct download/winget.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packaging/msix/build-msix.ps1` around lines 6 - 25, The release workflow is
still invoking the MSIX build with only the default Store identity values, so
the non-Store package needs explicit overrides. Update the release job in the
GitHub Actions workflow to pass the sideload/self-signed values into
build-msix.ps1, using the script’s Publisher, PublisherDisplayName, Name, and
DisplayName parameters so the released MSIX matches the direct-download package.
Problem
The v1.9.0 Microsoft Store submission was rejected because the MSIX's
Package/Identitydid not match the reserved Partner Center identity. The Store validates every identity field strictly and does not remapName/Publisheron ingestion:org.geolibre.desktop(expectedOpenGeospatialSolutions.GeoLibre)org.geolibre.desktop_v6dsnp8ebbdfr(expectedOpenGeospatialSolutions.GeoLibre_wby2ff7ejknn4)CN=GeoLibre(expectedCN=E6AE8172-...)Properties/DisplayName:GeoLibre Desktop(must be the reservedGeoLibre)Fix
packaging/msix/build-msix.ps1now defaults to the opengeos Partner Center identity, so a bare./build-msix.ps1(as invoked byrelease.yml) produces a Store-ready package:Nameorg.geolibre.desktopOpenGeospatialSolutions.GeoLibrePublisherCN=GeoLibreCN=E6AE8172-DC4F-4F79-844B-9D84204BF95ADisplayNameGeoLibre DesktopGeoLibre(reserved)PublisherDisplayNameOpen Geospatial SolutionsThe package family name derives from
Name+Publisher, so it now resolves to the expectedOpenGeospatialSolutions.GeoLibre_wby2ff7ejknn4. The Start-menu name (VisualElements/@DisplayName) intentionally staysGeoLibre Desktop(not validated by the Store). Each value can still be overridden for a self-signed sideload build; the packaging README table is updated.On-demand build
Adds
.github/workflows/msix-store.yml, aworkflow_dispatchjob that builds the MSIX and uploads it as a workflow artifact. This lets a Store-ready package be produced without re-publishing a GitHub release (used to generate the corrected v1.9.0 upload).Verification
Built via the new workflow and confirmed the resulting
AppxManifest.xmlcarries all four required identity values. The package was uploaded to Partner Center and passed package validation.Summary by CodeRabbit
New Features
Documentation
Bug Fixes