From e87cd49cdf27cbd0565138218bbf2c741a463adf Mon Sep 17 00:00:00 2001 From: Natalie Aguinaldo Date: Fri, 18 Sep 2026 09:34:30 -0700 Subject: [PATCH] chore(msix): rename download files to OpenClaw Reapply the rename-only change from 19da0469 on current upstream main. Update both Store and Dev filenames, metadata, installation instructions, alpha staging, CI upload paths, documentation, and tests without changing package versions, identities, UI, signing, or EXE names. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cb0e5a80-d2cf-41b0-9fb0-21eb32623526 --- .github/workflows/ci.yml | 4 +- DEVELOPMENT.md | 10 +++- build.ps1 | 2 +- docs/RELEASING.md | 6 +- scripts/Build-StoreMsix.ps1 | 2 +- scripts/Export-DevMsixArtifact.ps1 | 2 +- scripts/Stage-StoreMsixReleaseAssets.ps1 | 4 +- scripts/test-ci-workflow-contract.ps1 | 6 +- scripts/test-msix-alpha-release.ps1 | 18 +++--- scripts/test-msix-ci-artifacts.ps1 | 57 +++++++++++-------- .../MsixDevelopmentSigningTests.cs | 3 +- .../ReleaseSigningWorkflowTests.cs | 4 +- 12 files changed, 68 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5915ab931..7993ebe97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -859,7 +859,7 @@ jobs: with: name: openclaw-msix-store-unsigned-${{ matrix.architecture }} path: | - artifacts/msix/${{ matrix.architecture }}/OpenClawCompanion-${{ matrix.architecture }}.msix + artifacts/msix/${{ matrix.architecture }}/OpenClaw-${{ matrix.architecture }}.msix artifacts/msix/${{ matrix.architecture }}/msix-metadata.json if-no-files-found: error @@ -891,7 +891,7 @@ jobs: with: name: openclaw-msix-dev-${{ matrix.architecture }} path: | - artifacts/msix-dev/${{ matrix.architecture }}/OpenClawCompanion-Dev-${{ matrix.architecture }}.msix + artifacts/msix-dev/${{ matrix.architecture }}/OpenClaw-Dev-${{ matrix.architecture }}.msix artifacts/msix-dev/${{ matrix.architecture }}/OpenClaw-Dev.cer artifacts/msix-dev/${{ matrix.architecture }}/msix-metadata.json artifacts/msix-dev/${{ matrix.architecture }}/INSTALL.txt diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 0c09c2b83..10e51513b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -291,7 +291,7 @@ Partner Center rejects any submission whose revision is non-zero. `-Msix Store` forces `-Configuration Release`, refuses to combine with `-DevBuild`, and delegates to `scripts\Build-StoreMsix.ps1` once per architecture. Each run produces one unsigned self-contained package at -`artifacts\msix\\OpenClawCompanion-.msix` alongside an +`artifacts\msix\\OpenClaw-.msix` alongside an `msix-metadata.json` provenance sidecar recording the source commit, whether the tree was dirty, the package version, publisher, and the package SHA-256. @@ -330,8 +330,12 @@ Download the desired ZIP from the workflow run's **Artifacts**: | Artifact | Contents and purpose | |---|---| -| `openclaw-msix-dev-x64` / `openclaw-msix-dev-arm64` | Signed Dev `.msix`, public `OpenClaw-Dev.cer`, `msix-metadata.json`, and `INSTALL.txt` for opt-in tester installation. | -| `openclaw-msix-store-unsigned-x64` / `openclaw-msix-store-unsigned-arm64` | Unsigned Store `.msix` and the validated provenance sidecar from `Build-StoreMsix.ps1`. Submission inputs, not directly installable tester packages. | +| `openclaw-msix-dev-x64` / `openclaw-msix-dev-arm64` | Signed `OpenClaw-Dev-.msix`, public `OpenClaw-Dev.cer`, `msix-metadata.json`, and `INSTALL.txt` for opt-in tester installation. | +| `openclaw-msix-store-unsigned-x64` / `openclaw-msix-store-unsigned-arm64` | Unsigned `OpenClaw-.msix` and the validated provenance sidecar from `Build-StoreMsix.ps1`. Submission inputs, not directly installable tester packages. | + +These MSIX filenames use `OpenClaw`, not the previous `OpenClawCompanion` +prefix. Only the download filenames changed: package identities, versions, +and EXE installer filenames are unchanged. Existing downloads are not renamed. Each disposable runner uses `setup-dev-msix-cert.ps1` to generate and trust a non-exportable Dev certificate. Only its public `.cer` is included. The key and diff --git a/build.ps1 b/build.ps1 index 562ac40ba..9161ec2b2 100644 --- a/build.ps1 +++ b/build.ps1 @@ -597,7 +597,7 @@ if ($buildStoreMsix) { Write-Error "Store MSIX ($storeArchitecture) packaging failed: $($_.Exception.Message)" exit 1 } - $storePackages += Join-Path $repoRoot "artifacts\msix\$storeArchitecture\OpenClawCompanion-$storeArchitecture.msix" + $storePackages += Join-Path $repoRoot "artifacts\msix\$storeArchitecture\OpenClaw-$storeArchitecture.msix" } Write-Header "Store MSIX Packages" diff --git a/docs/RELEASING.md b/docs/RELEASING.md index e5953d87b..e5b81aa06 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -175,9 +175,9 @@ Current release artifacts are: Canonical alpha releases additionally contain: -- `OpenClawCompanion-x64.msix` and `OpenClawCompanion-arm64.msix` -- `OpenClawCompanion-x64.msix-metadata.json` and - `OpenClawCompanion-arm64.msix-metadata.json` +- `OpenClaw-x64.msix` and `OpenClaw-arm64.msix` +- `OpenClaw-x64.msix-metadata.json` and + `OpenClaw-arm64.msix-metadata.json` These are **unsigned Store submission inputs, not installers**. Download the MSIX files and upload them manually to Partner Center. Microsoft signs accepted diff --git a/scripts/Build-StoreMsix.ps1 b/scripts/Build-StoreMsix.ps1 index adbd8d06d..af0ba85f8 100644 --- a/scripts/Build-StoreMsix.ps1 +++ b/scripts/Build-StoreMsix.ps1 @@ -208,7 +208,7 @@ try { ) } - $msixName = "OpenClawCompanion-$Architecture.msix" + $msixName = "OpenClaw-$Architecture.msix" $msixPath = Join-Path $OutputDirectory $msixName Copy-Item -LiteralPath $builtPackages[0].FullName -Destination $msixPath -Force diff --git a/scripts/Export-DevMsixArtifact.ps1 b/scripts/Export-DevMsixArtifact.ps1 index 53811659b..6366dddcf 100644 --- a/scripts/Export-DevMsixArtifact.ps1 +++ b/scripts/Export-DevMsixArtifact.ps1 @@ -77,7 +77,7 @@ if ($LASTEXITCODE -ne 0 -or $sourceCommit -notmatch '^[0-9a-fA-F]{40}$') { $sourceTreeDirty = [bool](& git -C $repositoryRoot status --porcelain) if ($LASTEXITCODE -ne 0) { throw 'Unable to inspect the current source tree.' } -$packageName = "OpenClawCompanion-Dev-$Architecture.msix" +$packageName = "OpenClaw-Dev-$Architecture.msix" New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null Copy-Item -LiteralPath $package.FullName -Destination (Join-Path $OutputDirectory $packageName) $certificatePath = Join-Path $OutputDirectory 'OpenClaw-Dev.cer' diff --git a/scripts/Stage-StoreMsixReleaseAssets.ps1 b/scripts/Stage-StoreMsixReleaseAssets.ps1 index 1e49c1f40..2e749bdbe 100644 --- a/scripts/Stage-StoreMsixReleaseAssets.ps1 +++ b/scripts/Stage-StoreMsixReleaseAssets.ps1 @@ -32,7 +32,7 @@ if ((Test-Path -LiteralPath $OutputDirectory) -and $expectedVersion = ($Version -replace '-alpha\.\d+$', '') + '.0' $packages = foreach ($architecture in @('x64', 'arm64')) { $directory = Join-Path $ArtifactDirectory "openclaw-msix-store-unsigned-$architecture" - $packageName = "OpenClawCompanion-$architecture.msix" + $packageName = "OpenClaw-$architecture.msix" $expectedFiles = @($packageName, 'msix-metadata.json') | Sort-Object $entries = @(Get-ChildItem -LiteralPath $directory -Force) if ($entries.Count -ne 2 -or @@ -80,7 +80,7 @@ $files = foreach ($package in $packages) { Notes = @" ### Unsigned Store submission packages (alpha only) -OpenClawCompanion-x64.msix and OpenClawCompanion-arm64.msix are unsigned +OpenClaw-x64.msix and OpenClaw-arm64.msix are unsigned Partner Center submission inputs, not installers. Their architecture-specific metadata files record the source commit, package version, and SHA-256. Upload the MSIX files manually to Partner Center; Microsoft signs accepted diff --git a/scripts/test-ci-workflow-contract.ps1 b/scripts/test-ci-workflow-contract.ps1 index fa62adac7..fc284b92d 100644 --- a/scripts/test-ci-workflow-contract.ps1 +++ b/scripts/test-ci-workflow-contract.ps1 @@ -668,6 +668,8 @@ foreach ($token in @( '-CertificateThumbprint $thumbprint', 'name: openclaw-msix-store-unsigned-${{ matrix.architecture }}', 'name: openclaw-msix-dev-${{ matrix.architecture }}', + 'artifacts/msix/${{ matrix.architecture }}/OpenClaw-${{ matrix.architecture }}.msix', + 'artifacts/msix-dev/${{ matrix.architecture }}/OpenClaw-Dev-${{ matrix.architecture }}.msix', 'msix-metadata.json', 'OpenClaw-Dev.cer', 'INSTALL.txt', @@ -726,8 +728,8 @@ Assert-Contains -Text $createRelease -Expected '${{ steps.msix_alpha.outputs.fil Assert-Contains -Text $createRelease -Expected '${{ steps.msix_alpha.outputs.notes }}' -Message "Only alpha release notes may mention MSIX downloads." Assert-Contains -Text $createRelease -Expected 'fail_on_unmatched_files: true' -Message "Missing release files must fail publication." Assert-Contains -Text $createRelease -Expected "make_latest: `${{ needs.metadata.outputs.isPrerelease == 'true' && 'false' || 'true' }}" -Message "Alpha releases must not become Latest." -Assert-NotContains -Text $createRelease -Unexpected 'OpenClawCompanion-x64.msix' -Message "MSIX must not be an unconditional stable release asset." -Assert-NotContains -Text $createRelease -Unexpected 'OpenClawCompanion-arm64.msix' -Message "MSIX must not be an unconditional stable release asset." +Assert-NotContains -Text $createRelease -Unexpected 'OpenClaw-x64.msix' -Message "MSIX must not be an unconditional stable release asset." +Assert-NotContains -Text $createRelease -Unexpected 'OpenClaw-arm64.msix' -Message "MSIX must not be an unconditional stable release asset." Assert-Contains -Text $workflow -Expected "./scripts/test-msix-ci-artifacts.ps1" -Message "Fast validation must exercise the Dev artifact contracts." Assert-Contains -Text $workflow -Expected "./scripts/test-msix-alpha-release.ps1" -Message "Fast validation must exercise alpha release staging." diff --git a/scripts/test-msix-alpha-release.ps1 b/scripts/test-msix-alpha-release.ps1 index 660aca423..9f8d042a0 100644 --- a/scripts/test-msix-alpha-release.ps1 +++ b/scripts/test-msix-alpha-release.ps1 @@ -36,7 +36,7 @@ function New-Fixture { foreach ($architecture in @('x64', 'arm64')) { $directory = Join-Path $inputPath "openclaw-msix-store-unsigned-$architecture" New-Item -ItemType Directory -Path $directory -Force | Out-Null - $packageName = "OpenClawCompanion-$architecture.msix" + $packageName = "OpenClaw-$architecture.msix" $packagePath = Join-Path $directory $packageName Set-Content -LiteralPath $packagePath -Value "Synthetic $architecture package fixture." [ordered]@{ @@ -69,18 +69,18 @@ try { $assets = & $stager @arguments $names = @($assets.Files | ForEach-Object { [IO.Path]::GetFileName($_) } | Sort-Object) $expected = @( - 'OpenClawCompanion-arm64.msix', - 'OpenClawCompanion-arm64.msix-metadata.json', - 'OpenClawCompanion-x64.msix', - 'OpenClawCompanion-x64.msix-metadata.json' + 'OpenClaw-arm64.msix', + 'OpenClaw-arm64.msix-metadata.json', + 'OpenClaw-x64.msix', + 'OpenClaw-x64.msix-metadata.json' ) if (@(Compare-Object $expected $names).Count -gt 0 -or @(Get-ChildItem -LiteralPath $arguments.OutputDirectory).Count -ne 4) { throw 'Release assets did not match the exact public Store allowlist.' } foreach ($architecture in @('x64', 'arm64')) { - $original = Join-Path $arguments.ArtifactDirectory "openclaw-msix-store-unsigned-$architecture\OpenClawCompanion-$architecture.msix" - $copy = Join-Path $arguments.OutputDirectory "OpenClawCompanion-$architecture.msix" + $original = Join-Path $arguments.ArtifactDirectory "openclaw-msix-store-unsigned-$architecture\OpenClaw-$architecture.msix" + $copy = Join-Path $arguments.OutputDirectory "OpenClaw-$architecture.msix" if ((Get-FileHash -LiteralPath $original).Hash -ne (Get-FileHash -LiteralPath $copy).Hash) { throw 'Staging changed the validated package bytes.' } @@ -90,7 +90,7 @@ try { throw 'Published metadata did not describe the released file.' } } - foreach ($warning in @('unsigned', 'not installers', '2026.7.2.0', 'same Store version', 'Dev-signed tester downloads remain in Actions')) { + foreach ($warning in @('OpenClaw-x64.msix', 'OpenClaw-arm64.msix', 'unsigned', 'not installers', '2026.7.2.0', 'same Store version', 'Dev-signed tester downloads remain in Actions')) { if (-not $assets.Notes.Contains($warning)) { throw "Release notes are missing '$warning'." } } Assert-Fails { & $stager @arguments } 'absent or empty' @@ -126,7 +126,7 @@ try { Set-Content -LiteralPath (Join-Path $arguments.ArtifactDirectory 'openclaw-msix-store-unsigned-x64\extra.pfx') 'not a real key' Assert-Fails { & $stager @arguments } 'exactly' $arguments = New-Fixture - Remove-Item -LiteralPath (Join-Path $arguments.ArtifactDirectory 'openclaw-msix-store-unsigned-arm64\OpenClawCompanion-arm64.msix') + Remove-Item -LiteralPath (Join-Path $arguments.ArtifactDirectory 'openclaw-msix-store-unsigned-arm64\OpenClaw-arm64.msix') Assert-Fails { & $stager @arguments } 'exactly' $arguments = New-Fixture $arguments.Version = '2026.7.3-alpha.4' diff --git a/scripts/test-msix-ci-artifacts.ps1 b/scripts/test-msix-ci-artifacts.ps1 index 36f805f49..c6234ebdd 100644 --- a/scripts/test-msix-ci-artifacts.ps1 +++ b/scripts/test-msix-ci-artifacts.ps1 @@ -83,31 +83,42 @@ function New-Arguments { try { Add-Type -AssemblyName System.IO.Compression.FileSystem - $arguments = New-Arguments - New-Package -Directory $arguments.PackageDirectory - # Unrelated build output must not be uploaded, even if it contains a key. - Set-Content (Join-Path $arguments.PackageDirectory 'do-not-publish.pfx') 'not a real key' - & $exporter @arguments - $files = @(Get-ChildItem -LiteralPath $arguments.OutputDirectory -File | Sort-Object Name | Select-Object -ExpandProperty Name) - if (($files -join ',') -ne 'INSTALL.txt,msix-metadata.json,OpenClaw-Dev.cer,OpenClawCompanion-Dev-x64.msix') { - throw "Unexpected Dev artifact contents: $($files -join ',')" - } - $metadata = Get-Content (Join-Path $arguments.OutputDirectory 'msix-metadata.json') -Raw | ConvertFrom-Json - $publicCertificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new( - (Join-Path $arguments.OutputDirectory 'OpenClaw-Dev.cer')) - try { - if ($publicCertificate.HasPrivateKey -or $publicCertificate.Thumbprint -ne $certificate.Thumbprint) { - throw 'The exported certificate is not the expected public-only signer.' + foreach ($architecture in @('x64', 'arm64')) { + $arguments = New-Arguments + $arguments.Architecture = $architecture + New-Package -Directory $arguments.PackageDirectory -Architecture $architecture + # Unrelated build output must not be uploaded, even if it contains a key. + Set-Content (Join-Path $arguments.PackageDirectory 'do-not-publish.pfx') 'not a real key' + & $exporter @arguments + $packageName = "OpenClaw-Dev-$architecture.msix" + $expectedFiles = @('INSTALL.txt', 'msix-metadata.json', 'OpenClaw-Dev.cer', $packageName) + $files = @(Get-ChildItem -LiteralPath $arguments.OutputDirectory -File | Select-Object -ExpandProperty Name) + if (@(Compare-Object $expectedFiles $files).Count -gt 0) { + throw "Unexpected Dev artifact contents: $($files -join ',')" } + $metadata = Get-Content (Join-Path $arguments.OutputDirectory 'msix-metadata.json') -Raw | ConvertFrom-Json + $publicCertificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new( + (Join-Path $arguments.OutputDirectory 'OpenClaw-Dev.cer')) + try { + if ($publicCertificate.HasPrivateKey -or $publicCertificate.Thumbprint -ne $certificate.Thumbprint) { + throw 'The exported certificate is not the expected public-only signer.' + } + } + finally { $publicCertificate.Dispose() } + $actualHash = (Get-FileHash (Join-Path $arguments.OutputDirectory $metadata.archive) -Algorithm SHA256).Hash + if (-not $metadata.signed -or $metadata.signing -ne 'development-only' -or + $metadata.archive -ne $packageName -or $metadata.architecture -ne $architecture -or + $metadata.identityName -ne 'OpenClawFoundation.OpenClaw.Dev' -or + $metadata.packageVersion -ne '2026.7.2.123' -or $metadata.sha256 -ne $actualHash -or + $metadata.certificateThumbprint -ne $certificate.Thumbprint -or $metadata.sourceCommit -notmatch '^[0-9a-f]{40}$') { + throw 'Dev package provenance did not match its inputs.' + } + $instructions = Get-Content (Join-Path $arguments.OutputDirectory 'INSTALL.txt') -Raw + if (-not $instructions.Contains("Add-AppxPackage -Path .\$packageName")) { + throw 'Dev installation instructions did not name the exported package.' + } + Assert-Fails { & $exporter @arguments } 'must be absent or empty' } - finally { $publicCertificate.Dispose() } - $actualHash = (Get-FileHash (Join-Path $arguments.OutputDirectory $metadata.archive) -Algorithm SHA256).Hash - if (-not $metadata.signed -or $metadata.signing -ne 'development-only' -or - $metadata.packageVersion -ne '2026.7.2.123' -or $metadata.sha256 -ne $actualHash -or - $metadata.certificateThumbprint -ne $certificate.Thumbprint -or $metadata.sourceCommit -notmatch '^[0-9a-f]{40}$') { - throw 'Dev package provenance did not match its inputs.' - } - Assert-Fails { & $exporter @arguments } 'must be absent or empty' $arguments = New-Arguments New-Item -ItemType Directory -Path $arguments.PackageDirectory | Out-Null diff --git a/tests/OpenClaw.Tray.Tests/MsixDevelopmentSigningTests.cs b/tests/OpenClaw.Tray.Tests/MsixDevelopmentSigningTests.cs index 2ec9421e3..6a9cd325d 100644 --- a/tests/OpenClaw.Tray.Tests/MsixDevelopmentSigningTests.cs +++ b/tests/OpenClaw.Tray.Tests/MsixDevelopmentSigningTests.cs @@ -94,7 +94,8 @@ public void BuildScript_StoreMsixPathIsUnsignedReleaseIdentityForBothArchitectur // Exactly one package per architecture, deterministically named, with provenance. Assert.Contains("$builtPackages.Count -ne 1", packagingScript); - Assert.Contains("\"OpenClawCompanion-$Architecture.msix\"", packagingScript); + Assert.Contains("\"OpenClaw-$Architecture.msix\"", packagingScript); + Assert.Contains(@"artifacts\msix\$storeArchitecture\OpenClaw-$storeArchitecture.msix", buildScript); Assert.Contains("msix-metadata.json", packagingScript); Assert.Contains("signed = $false", packagingScript); Assert.Contains("sourceTreeDirty = $sourceTreeDirty", packagingScript); diff --git a/tests/OpenClaw.Tray.Tests/ReleaseSigningWorkflowTests.cs b/tests/OpenClaw.Tray.Tests/ReleaseSigningWorkflowTests.cs index 6876d9b98..1c2242294 100644 --- a/tests/OpenClaw.Tray.Tests/ReleaseSigningWorkflowTests.cs +++ b/tests/OpenClaw.Tray.Tests/ReleaseSigningWorkflowTests.cs @@ -137,8 +137,8 @@ public void ReleaseWorkflow_PublishesOnlyUnsignedStoreMsixForAlphaTags() var releaseStep = ExtractReleaseStep(workflow); Assert.Contains("${{ steps.msix_alpha.outputs.files }}", releaseStep); Assert.Contains("${{ steps.msix_alpha.outputs.notes }}", releaseStep); - Assert.DoesNotContain("OpenClawCompanion-x64.msix", releaseStep); - Assert.DoesNotContain("OpenClawCompanion-arm64.msix", releaseStep); + Assert.DoesNotContain("OpenClaw-x64.msix", releaseStep); + Assert.DoesNotContain("OpenClaw-arm64.msix", releaseStep); Assert.DoesNotContain("openclaw-msix-dev-", releaseStep); }