diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 4125eb3a..d45a509c 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -88,6 +88,9 @@ jobs: python-version: '3.13' - name: Build app + # Skip (green) when Apple signing secrets aren't in CI: Mac ships via local + # publish.sh, so a secret-less CI run should no-op, not fail red. + if: ${{ env.APPLE_ID != '' }} shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -101,8 +104,10 @@ jobs: version="$(node -p "require('./electron/package.json').version")" if [[ "$version" == *-* ]]; then - export EP_PRE_RELEASE=true - echo "Version $version is EXPERIMENTAL; setting EP_PRE_RELEASE=true" + # Do NOT set EP_PRE_RELEASE: the GH pre-release checkbox hides the release + # from the releases.atom feed electron-updater reads, so even experimental + # clients can't discover it (matches release-windows.yml fix). + echo "Version $version is EXPERIMENTAL (semver-suffix channel; NOT a GH pre-release)" else echo "Version $version is STABLE" fi @@ -123,6 +128,7 @@ jobs: # NOTE: like the rest of this workflow, this mac path is unverified locally # (no Mac on hand); first exercise it via workflow_dispatch publish=false. - name: Verify the shipped app is signed + notarized + if: ${{ env.APPLE_ID != '' }} shell: bash run: | set -euo pipefail diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index af605413..0c58fb01 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -134,32 +134,20 @@ jobs: GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.GOOGLE_OAUTH_CLIENT_SECRET }} run: | $ErrorActionPreference = 'Stop' - $shouldPublish = ($env:GITHUB_EVENT_NAME -eq 'push') -or ` - ($env:GITHUB_EVENT_NAME -eq 'workflow_dispatch' -and $env:PUBLISH_INPUT -eq 'true') - # Do NOT set EP_PRE_RELEASE for suffixed versions. It marks the GitHub - # "pre-release" checkbox, and GitHub then HIDES that release from the - # releases.atom feed electron-updater reads, so even experimental - # (allowPrerelease) clients can never discover it. Experimental builds - # ship as a NORMAL release distinguished by their semver suffix + a - # channel yml (rc.yml / exp.yml), kept off "Latest" after publish so - # stable clients (which read /releases/latest) never pull them. $version = (Get-Content electron/package.json | ConvertFrom-Json).version if ($version -match '-') { Write-Host "Version $version is EXPERIMENTAL (semver-suffix channel; NOT a GH pre-release)" } else { Write-Host "Version $version is STABLE" } - # -Squirrel passes --config.win.target=squirrel (string form), which makes - # electron-builder honor win.artifactName -> OpenSwarm-Setup-x64.exe. The - # object-form win.target in package.json does NOT, and falls back to - # openswarm-Setup-1.1.71.exe, which mismatches the landing page + latest.yml. - if ($shouldPublish) { - Write-Host "Build mode: PUBLISH" - pwsh -NoProfile -File scripts\build-app-win.ps1 -Publish -Squirrel - } else { - Write-Host "Build mode: SIGN (artifact only)" - pwsh -NoProfile -File scripts\build-app-win.ps1 -Sign -Squirrel - } + # Always build SIGNED with -Squirrel (--publish never). We deliberately do + # NOT let electron-builder publish: its squirrel publisher RENAMES the + # installer to openswarm-Setup-.exe on upload (even though the + # local file is correctly named OpenSwarm-Setup-x64.exe), which breaks the + # landing page + latest.yml. We publish via gh below, which preserves the + # local name. EP_PRE_RELEASE is intentionally never set (the GH pre-release + # checkbox hides a release from the atom feed electron-updater reads). + pwsh -NoProfile -File scripts\build-app-win.ps1 -Sign -Squirrel if ($LASTEXITCODE -ne 0) { throw "build-app-win.ps1 failed ($LASTEXITCODE)" } # SmartScreen gate: after electron-builder + the Azure sign hook run, prove @@ -196,9 +184,10 @@ jobs: } Get-Content "$dir/latest.yml" - # electron-builder published Setup + RELEASES + nupkg to the draft release; - # attach the latest.yml it cannot emit so NSIS clients can migrate. - - name: Upload latest.yml to the release (publish runs) + # Publish the squirrel assets ourselves via gh (NOT electron-builder), so the + # installer keeps its OpenSwarm-Setup-x64.exe name. Find-or-create a DRAFT so + # the mac publish.sh run can converge into the same release; Eric flips it live. + - name: Publish squirrel assets to the GitHub release (draft, publish runs) if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true') shell: pwsh env: @@ -208,17 +197,24 @@ jobs: $version = (Get-Content electron/package.json | ConvertFrom-Json).version $tag = "v$version" $dir = 'electron/dist/squirrel-windows' - gh release upload $tag "$dir/latest.yml" --clobber - if ($LASTEXITCODE -ne 0) { throw "failed to upload latest.yml to $tag" } + $setup = "$dir/OpenSwarm-Setup-x64.exe" + $nupkg = (Get-ChildItem $dir -Filter '*-full.nupkg' | Select-Object -First 1).FullName + gh release view $tag 2>$null + if ($LASTEXITCODE -ne 0) { + gh release create $tag --draft --title "$version" --notes "OpenSwarm $version" + if ($LASTEXITCODE -ne 0) { throw "gh release create failed" } + } + gh release upload $tag $setup "$dir/RELEASES" "$dir/latest.yml" $nupkg --clobber + if ($LASTEXITCODE -ne 0) { throw "gh upload (setup/RELEASES/latest.yml/nupkg) failed" } if ($version -match '-([0-9A-Za-z]+)') { gh release upload $tag "$dir/$($matches[1]).yml" --clobber if ($LASTEXITCODE -ne 0) { throw "failed to upload $($matches[1]).yml to $tag" } # Keep experimental builds OFF "Latest" so stable clients never pull them; # only allowPrerelease clients (atom feed) discover them. gh release edit $tag --prerelease=false --latest=false - Write-Host "Attached $($matches[1]).yml and kept $tag off Latest (experimental channel)" + Write-Host "Published $($matches[1]).yml + Setup + kept $tag off Latest (experimental)" } else { - Write-Host "Attached latest.yml to release $tag (stable; becomes Latest on publish)" + Write-Host "Published Setup + RELEASES + nupkg + latest.yml to draft $tag (stable)" } - name: Upload artifact (non-publish runs)