From bf368e760957664d4948953aae0f55dbba4755ae Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 3 Jun 2026 22:39:58 +0100 Subject: [PATCH] ci(release): promote Windows node installers --- .../release-openclaw-maintainer/SKILL.md | 17 ++- .github/workflows/windows-node-release.yml | 126 ++++++++++++++++++ docs/reference/RELEASING.md | 21 ++- 3 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/windows-node-release.yml diff --git a/.agents/skills/release-openclaw-maintainer/SKILL.md b/.agents/skills/release-openclaw-maintainer/SKILL.md index 0018849f0e79..1ba3c8cb48e1 100644 --- a/.agents/skills/release-openclaw-maintainer/SKILL.md +++ b/.agents/skills/release-openclaw-maintainer/SKILL.md @@ -111,9 +111,10 @@ Use this skill for release and publish-time workflow. Load `$release-private` if - For fallback correction tags like `vYYYY.M.D-N`, the repo version locations still stay at `YYYY.M.D`. - “Bump version everywhere” means all version locations above except `appcast.xml`. - Release signing and notary credentials live outside the repo in the private maintainer docs. -- Every stable OpenClaw release ships the npm package and macOS app together. - Beta releases normally ship npm/package artifacts first and skip mac app - build/sign/notarize unless the operator requests mac beta validation. +- Every stable OpenClaw release ships the npm package, macOS app, and signed + Windows Hub installers together. Beta releases normally ship npm/package + artifacts first and skip native app build/sign/notarize/promote unless the + operator requests native beta validation. - Do not let the slower macOS signing/notary path block npm publication once the npm preflight has passed. Keep mac validation/publish running in parallel, publish npm from the successful npm preflight, then start published @@ -143,6 +144,16 @@ Use this skill for release and publish-time workflow. Load `$release-private` if at `YYYY.M.D`, but the mac release must use a strictly higher numeric `APP_BUILD` / Sparkle build than the original release so existing installs see it as newer. +- Stable Windows Hub release closeout requires the signed + `OpenClawCompanion-Setup-x64.exe`, `OpenClawCompanion-Setup-arm64.exe`, and + `OpenClawCompanion-SHA256SUMS.txt` assets on the canonical + `openclaw/openclaw` GitHub Release. Use the public `Windows Node Release` + workflow after the matching `openclaw/openclaw-windows-node` release exists; + it verifies Authenticode signatures on Windows before uploading assets. +- Website Windows Hub download links should target the canonical + `openclaw/openclaw/releases/latest/download/...` assets so the installable + signed Windows artifact is visible from both the GitHub release page and + openclaw.ai. ## Build changelog-backed release notes diff --git a/.github/workflows/windows-node-release.yml b/.github/workflows/windows-node-release.yml new file mode 100644 index 000000000000..61411a3cc7ca --- /dev/null +++ b/.github/workflows/windows-node-release.yml @@ -0,0 +1,126 @@ +name: Windows Node Release + +on: + workflow_dispatch: + inputs: + tag: + description: Existing OpenClaw release tag to receive Windows Hub installers, for example v2026.6.1 + required: true + type: string + windows_node_tag: + description: openclaw-windows-node release tag to promote, or latest + required: true + default: latest + type: string + +permissions: + contents: write + +concurrency: + group: windows-node-release-${{ inputs.tag }} + cancel-in-progress: false + +jobs: + promote_signed_windows_installers: + name: Promote signed Windows installers + runs-on: windows-latest + timeout-minutes: 30 + steps: + - name: Validate inputs + shell: pwsh + env: + RELEASE_TAG: ${{ inputs.tag }} + WINDOWS_NODE_TAG: ${{ inputs.windows_node_tag }} + GH_TOKEN: ${{ github.token }} + run: | + if ($env:RELEASE_TAG -notmatch '^v[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*((-(alpha|beta)\.[1-9][0-9]*)|(-[1-9][0-9]*))?$') { + throw "Invalid OpenClaw release tag: $env:RELEASE_TAG" + } + if ($env:WINDOWS_NODE_TAG -ne "latest" -and $env:WINDOWS_NODE_TAG -notmatch '^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$') { + throw "Invalid openclaw-windows-node release tag: $env:WINDOWS_NODE_TAG" + } + gh release view $env:RELEASE_TAG --repo $env:GITHUB_REPOSITORY | Out-Null + + - name: Download Windows Hub release installers + shell: pwsh + env: + WINDOWS_NODE_TAG: ${{ inputs.windows_node_tag }} + GH_TOKEN: ${{ github.token }} + run: | + New-Item -ItemType Directory -Force -Path dist | Out-Null + $tagArgs = @() + if ($env:WINDOWS_NODE_TAG -ne "latest") { + $tagArgs += $env:WINDOWS_NODE_TAG + } + gh release download @tagArgs ` + --repo openclaw/openclaw-windows-node ` + --pattern "OpenClawCompanion-Setup-*.exe" ` + --dir dist + + $expected = @( + "dist/OpenClawCompanion-Setup-x64.exe", + "dist/OpenClawCompanion-Setup-arm64.exe" + ) + foreach ($file in $expected) { + if (-not (Test-Path -LiteralPath $file)) { + throw "Missing expected Windows installer: $file" + } + } + + - name: Verify Authenticode signatures + shell: pwsh + run: | + Get-ChildItem -LiteralPath dist -Filter "OpenClawCompanion-Setup-*.exe" | ForEach-Object { + $signature = Get-AuthenticodeSignature -LiteralPath $_.FullName + if ($signature.Status -ne "Valid") { + throw "$($_.Name) Authenticode signature was $($signature.Status)." + } + if (-not $signature.SignerCertificate) { + throw "$($_.Name) has no signer certificate." + } + [pscustomobject]@{ + File = $_.Name + Signer = $signature.SignerCertificate.Subject + Thumbprint = $signature.SignerCertificate.Thumbprint + } | Format-List + } + + - name: Write SHA-256 manifest + shell: pwsh + run: | + Get-ChildItem -LiteralPath dist -Filter "OpenClawCompanion-Setup-*.exe" | + Sort-Object Name | + ForEach-Object { + $hash = Get-FileHash -Algorithm SHA256 -LiteralPath $_.FullName + "$($hash.Hash.ToLowerInvariant()) $($_.Name)" + } | Set-Content -Encoding utf8NoBOM -Path dist/OpenClawCompanion-SHA256SUMS.txt + + - name: Upload to OpenClaw release + shell: pwsh + env: + RELEASE_TAG: ${{ inputs.tag }} + GH_TOKEN: ${{ github.token }} + run: | + gh release upload $env:RELEASE_TAG ` + dist/OpenClawCompanion-Setup-x64.exe ` + dist/OpenClawCompanion-Setup-arm64.exe ` + dist/OpenClawCompanion-SHA256SUMS.txt ` + --repo $env:GITHUB_REPOSITORY ` + --clobber + + - name: Summary + shell: pwsh + env: + RELEASE_TAG: ${{ inputs.tag }} + WINDOWS_NODE_TAG: ${{ inputs.windows_node_tag }} + run: | + @" + ## Windows Hub installers promoted + + OpenClaw release: $env:RELEASE_TAG + Source release: openclaw/openclaw-windows-node@$env:WINDOWS_NODE_TAG + + - https://github.com/openclaw/openclaw/releases/download/$env:RELEASE_TAG/OpenClawCompanion-Setup-x64.exe + - https://github.com/openclaw/openclaw/releases/download/$env:RELEASE_TAG/OpenClawCompanion-Setup-arm64.exe + - https://github.com/openclaw/openclaw/releases/download/$env:RELEASE_TAG/OpenClawCompanion-SHA256SUMS.txt + "@ >> $env:GITHUB_STEP_SUMMARY diff --git a/docs/reference/RELEASING.md b/docs/reference/RELEASING.md index 05aadbf4134b..9a162b2a6e87 100644 --- a/docs/reference/RELEASING.md +++ b/docs/reference/RELEASING.md @@ -25,9 +25,10 @@ OpenClaw has three public release lanes: - `latest` means the current promoted stable npm release - `beta` means the current beta install target - Stable and stable correction releases publish to npm `beta` by default; release operators can target `latest` explicitly, or promote a vetted beta build later -- Every stable OpenClaw release ships the npm package and macOS app together; - beta releases normally validate and publish the npm/package path first, with - mac app build/sign/notarize reserved for stable unless explicitly requested +- Every stable OpenClaw release ships the npm package, macOS app, and signed + Windows Hub installers together; beta releases normally validate and publish + the npm/package path first, with native app build/sign/notarize/promote + reserved for stable unless explicitly requested ## Release cadence @@ -119,7 +120,12 @@ vYYYY.M.D-beta.N` from the matching `release/YYYY.M.D` branch. The helper runs packaged `.zip`, `.dmg`, `.dSYM.zip`, and updated `appcast.xml` on `main`. The macOS publish workflow publishes the signed appcast to public `main` automatically after release assets verify; if branch protection blocks the - direct push, it opens or updates an appcast PR. + direct push, it opens or updates an appcast PR. Stable Windows Hub + readiness requires the signed `OpenClawCompanion-Setup-x64.exe`, + `OpenClawCompanion-Setup-arm64.exe`, and + `OpenClawCompanion-SHA256SUMS.txt` assets on the OpenClaw GitHub release; + promote them with the `Windows Node Release` workflow after the matching + `openclaw/openclaw-windows-node` release has passed its signing workflow. 11. After publish, run the npm post-publish verifier, optional standalone published-npm Telegram E2E when you need post-publish channel proof, dist-tag promotion when needed, verify the generated GitHub release page, @@ -232,6 +238,13 @@ vYYYY.M.D-beta.N` from the matching `release/YYYY.M.D` branch. The helper runs workflow serializes plugin npm publish, plugin ClawHub publish, and OpenClaw npm publish so the core package is not published before its externalized plugins. +- Run the manual `Windows Node Release` workflow for stable releases after the + matching `openclaw/openclaw-windows-node` release exists. It downloads the + signed Windows Hub installers from the companion repo, verifies their + Authenticode signatures on a Windows runner, writes a SHA-256 manifest, and + uploads the installers plus manifest onto the canonical OpenClaw GitHub + release. Website download links should target the OpenClaw release assets, not + only the companion repo release page. - Release checks now run in a separate manual workflow: `OpenClaw Release Checks` - `OpenClaw Release Checks` also runs the QA Lab mock parity lane plus the fast