mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
Merge pull request #37 from sudosylabs/feat/microsoft-store-publishing
ci: automate Microsoft Store updates
This commit is contained in:
109
.github/workflows/release.yml
vendored
109
.github/workflows/release.yml
vendored
@@ -246,6 +246,114 @@ jobs:
|
|||||||
retention-days: 90
|
retention-days: 90
|
||||||
compression-level: 0
|
compression-level: 0
|
||||||
|
|
||||||
|
publish-microsoft-store:
|
||||||
|
name: Submit Microsoft Store update
|
||||||
|
needs:
|
||||||
|
- preflight
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
|
- macos
|
||||||
|
- play-closed-testing
|
||||||
|
runs-on: windows-2025
|
||||||
|
timeout-minutes: 30
|
||||||
|
environment: microsoft-store
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download Windows Store package
|
||||||
|
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
||||||
|
with:
|
||||||
|
name: vnidrop-${{ needs.preflight.outputs.version }}-windows-store-x64
|
||||||
|
path: build/release/windows
|
||||||
|
|
||||||
|
- name: Validate Microsoft Store configuration
|
||||||
|
id: store-package
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AD_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
|
||||||
|
AZURE_AD_APPLICATION_CLIENT_ID: ${{ secrets.AZURE_AD_APPLICATION_CLIENT_ID }}
|
||||||
|
AZURE_AD_APPLICATION_SECRET: ${{ secrets.AZURE_AD_APPLICATION_SECRET }}
|
||||||
|
SELLER_ID: ${{ secrets.SELLER_ID }}
|
||||||
|
MICROSOFT_STORE_PRODUCT_ID: ${{ vars.MICROSOFT_STORE_PRODUCT_ID }}
|
||||||
|
run: |
|
||||||
|
$configuration = @{
|
||||||
|
AZURE_AD_TENANT_ID = $env:AZURE_AD_TENANT_ID
|
||||||
|
AZURE_AD_APPLICATION_CLIENT_ID = $env:AZURE_AD_APPLICATION_CLIENT_ID
|
||||||
|
AZURE_AD_APPLICATION_SECRET = $env:AZURE_AD_APPLICATION_SECRET
|
||||||
|
SELLER_ID = $env:SELLER_ID
|
||||||
|
MICROSOFT_STORE_PRODUCT_ID = $env:MICROSOFT_STORE_PRODUCT_ID
|
||||||
|
}
|
||||||
|
foreach ($entry in $configuration.GetEnumerator()) {
|
||||||
|
if ([string]::IsNullOrWhiteSpace($entry.Value) -or $entry.Value -eq "REPLACE_ME") {
|
||||||
|
throw "Missing Microsoft Store configuration: $($entry.Key)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($env:MICROSOFT_STORE_PRODUCT_ID -ne "9NJ5Q0FG7TGL") {
|
||||||
|
throw "Unexpected Microsoft Store product ID: $env:MICROSOFT_STORE_PRODUCT_ID"
|
||||||
|
}
|
||||||
|
$packages = @(
|
||||||
|
Get-ChildItem build/release/windows -File -Filter *.msixupload -Recurse
|
||||||
|
)
|
||||||
|
if ($packages.Count -ne 1) {
|
||||||
|
throw "Expected exactly one msixupload package, found $($packages.Count)"
|
||||||
|
}
|
||||||
|
"path=$($packages[0].FullName)" >> $env:GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Set up Microsoft Store Developer CLI
|
||||||
|
uses: microsoft/microsoft-store-apppublisher@15abd1c50fcc164b19cb240fb04ef3c49bf715a2 # v1.1
|
||||||
|
with:
|
||||||
|
version: v0.3.9
|
||||||
|
|
||||||
|
- name: Authenticate and verify Store access
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
AZURE_AD_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
|
||||||
|
AZURE_AD_APPLICATION_CLIENT_ID: ${{ secrets.AZURE_AD_APPLICATION_CLIENT_ID }}
|
||||||
|
AZURE_AD_APPLICATION_SECRET: ${{ secrets.AZURE_AD_APPLICATION_SECRET }}
|
||||||
|
SELLER_ID: ${{ secrets.SELLER_ID }}
|
||||||
|
MICROSOFT_STORE_PRODUCT_ID: ${{ vars.MICROSOFT_STORE_PRODUCT_ID }}
|
||||||
|
run: |
|
||||||
|
msstore settings --enableTelemetry false
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Failed to disable Microsoft Store CLI telemetry"
|
||||||
|
}
|
||||||
|
msstore reconfigure `
|
||||||
|
--tenantId "$env:AZURE_AD_TENANT_ID" `
|
||||||
|
--sellerId "$env:SELLER_ID" `
|
||||||
|
--clientId "$env:AZURE_AD_APPLICATION_CLIENT_ID" `
|
||||||
|
--clientSecret "$env:AZURE_AD_APPLICATION_SECRET"
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Microsoft Store authentication failed"
|
||||||
|
}
|
||||||
|
msstore apps get "$env:MICROSOFT_STORE_PRODUCT_ID"
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "The Microsoft Store application is not accessible"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Publish package to Microsoft Store
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
MICROSOFT_STORE_PRODUCT_ID: ${{ vars.MICROSOFT_STORE_PRODUCT_ID }}
|
||||||
|
STORE_PACKAGE: ${{ steps.store-package.outputs.path }}
|
||||||
|
run: |
|
||||||
|
msstore publish "$env:STORE_PACKAGE" `
|
||||||
|
--appId "$env:MICROSOFT_STORE_PRODUCT_ID"
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Microsoft Store package publication failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Summarize Store submission
|
||||||
|
shell: pwsh
|
||||||
|
env:
|
||||||
|
VERSION: ${{ needs.preflight.outputs.version }}
|
||||||
|
MICROSOFT_STORE_PRODUCT_ID: ${{ vars.MICROSOFT_STORE_PRODUCT_ID }}
|
||||||
|
run: |
|
||||||
|
"### Microsoft Store submission" >> $env:GITHUB_STEP_SUMMARY
|
||||||
|
"- App version: $env:VERSION" >> $env:GITHUB_STEP_SUMMARY
|
||||||
|
"- Product ID: $env:MICROSOFT_STORE_PRODUCT_ID" >> $env:GITHUB_STEP_SUMMARY
|
||||||
|
"- Package submitted for certification" >> $env:GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
publish-github:
|
publish-github:
|
||||||
name: Publish coordinated GitHub Release
|
name: Publish coordinated GitHub Release
|
||||||
needs:
|
needs:
|
||||||
@@ -254,6 +362,7 @@ jobs:
|
|||||||
- windows
|
- windows
|
||||||
- macos
|
- macos
|
||||||
- play-closed-testing
|
- play-closed-testing
|
||||||
|
- publish-microsoft-store
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
@@ -13,19 +13,23 @@ Platform workflows upload private workflow artifacts. After every native build
|
|||||||
passes, the release pipeline:
|
passes, the release pipeline:
|
||||||
|
|
||||||
1. stages the signed AAB as a draft on the configured Play closed-test track;
|
1. stages the signed AAB as a draft on the configured Play closed-test track;
|
||||||
2. downloads the universal APK signed by Play;
|
2. submits the unsigned `.msixupload` package to Microsoft Store certification;
|
||||||
3. verifies and assembles the public artifacts;
|
3. downloads the universal APK signed by Play;
|
||||||
4. generates checksums and GitHub build-provenance attestations;
|
4. verifies and assembles the public artifacts;
|
||||||
5. creates exactly one GitHub Release;
|
5. generates checksums and GitHub build-provenance attestations;
|
||||||
6. updates the Homebrew cask.
|
6. creates exactly one GitHub Release;
|
||||||
|
7. updates the Homebrew cask.
|
||||||
|
|
||||||
Public GitHub Release assets are the DEB, RPM, notarized DMG, Sparkle appcast,
|
Public GitHub Release assets are the DEB, RPM, notarized DMG, Sparkle appcast,
|
||||||
Play-signed universal APK, checksum file, and release manifest.
|
Play-signed universal APK, checksum file, and release manifest.
|
||||||
|
|
||||||
The unsigned Microsoft `.msixupload` and upload-signed Android AAB remain
|
The unsigned Microsoft `.msixupload` and upload-signed Android AAB remain
|
||||||
private workflow artifacts. Partner Center submission stays manual until the
|
private workflow artifacts. The protected `microsoft-store` GitHub Environment
|
||||||
first Microsoft Store release is certified. The Play release remains a draft
|
supplies the Partner Center credentials and Store product ID used to submit the
|
||||||
on a closed-testing track; this pipeline cannot publish to production.
|
Windows package. Microsoft publishes the update after certification; the job
|
||||||
|
does not change Store listings, pricing, or availability. The Play release
|
||||||
|
remains a draft on a closed-testing track; this pipeline cannot publish it to
|
||||||
|
production.
|
||||||
|
|
||||||
To release, prepare and merge the new product version. Android, Microsoft Store,
|
To release, prepare and merge the new product version. Android, Microsoft Store,
|
||||||
and Apple build/package versions are derived automatically:
|
and Apple build/package versions are derived automatically:
|
||||||
|
|||||||
@@ -74,16 +74,21 @@ Use this restricted-capability justification in Submission options:
|
|||||||
> Rust and JVM libraries and needs normal user-level filesystem and network
|
> Rust and JVM libraries and needs normal user-level filesystem and network
|
||||||
> access to transfer user-selected files directly between devices.
|
> access to transfer user-selected files directly between devices.
|
||||||
|
|
||||||
After the first release is certified and live, Store publication can be added
|
After the first release is certified and live, the coordinated release
|
||||||
as a separate protected job. Keep its Partner Center credentials in a GitHub
|
workflow submits the generated `.msixupload` from a separate protected job.
|
||||||
Environment, not in this build job:
|
Keep its Partner Center credentials in the `microsoft-store` GitHub
|
||||||
|
Environment, not in the build job:
|
||||||
|
|
||||||
- AZURE_AD_TENANT_ID
|
- AZURE_AD_TENANT_ID
|
||||||
- AZURE_AD_APPLICATION_CLIENT_ID
|
- AZURE_AD_APPLICATION_CLIENT_ID
|
||||||
- AZURE_AD_APPLICATION_SECRET
|
- AZURE_AD_APPLICATION_SECRET
|
||||||
- SELLER_ID
|
- SELLER_ID
|
||||||
|
|
||||||
The Store ID is a non-secret variable.
|
Set `MICROSOFT_STORE_PRODUCT_ID` to `9NJ5Q0FG7TGL` as a non-secret variable in
|
||||||
|
the same environment. The publishing job validates the product ID,
|
||||||
|
authenticates with the pinned Microsoft Store Developer CLI, verifies access to
|
||||||
|
the product, and submits only the package for certification. Existing listings,
|
||||||
|
pricing, and availability are preserved.
|
||||||
|
|
||||||
## Manual build on Windows
|
## Manual build on Windows
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user