@@ -73,40 +73,35 @@ jobs:
7373 run : pnpm run uv:download:linux
7474
7575 # macOS specific steps
76+ # --publish never: prevent electron-builder from auto-publishing to GitHub.
77+ # All artifacts are collected and published atomically in the publish job.
7678 - name : Build macOS
7779 if : matrix.platform == 'mac'
7880 env :
7981 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
80- # Code signing
8182 CSC_LINK : ${{ secrets.MAC_CERTS }}
8283 CSC_KEY_PASSWORD : ${{ secrets.MAC_CERTS_PASSWORD }}
83- # Notarization
8484 APPLE_ID : ${{ secrets.APPLE_ID }}
8585 APPLE_APP_SPECIFIC_PASSWORD : ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
8686 APPLE_TEAM_ID : ${{ secrets.APPLE_TEAM_ID }}
8787 run : |
88- # Increase file descriptor limit to handle large number of files during code signing
8988 ulimit -n 65536
9089 echo "File descriptor limit: $(ulimit -n)"
91-
92- pnpm run package:mac
90+ pnpm run build:vite && zx scripts/bundle-openclaw.mjs && electron-builder --mac --publish never
9391
9492 # Windows specific steps
9593 - name : Build Windows
9694 if : matrix.platform == 'win'
9795 env :
9896 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
99- # For code signing (optional)
100- # CSC_LINK: ${{ secrets.WIN_CERTS }}
101- # CSC_KEY_PASSWORD: ${{ secrets.WIN_CERTS_PASSWORD }}
102- run : pnpm run package:win
97+ run : pnpm run build:vite && zx scripts/bundle-openclaw.mjs && electron-builder --win --publish never
10398
10499 # Linux specific steps
105100 - name : Build Linux
106101 if : matrix.platform == 'linux'
107102 env :
108103 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
109- run : pnpm run package: linux
104+ run : pnpm run build:vite && zx scripts/bundle-openclaw.mjs && electron-builder -- linux --publish never
110105
111106 - name : Upload artifacts
112107 uses : actions/upload-artifact@v4
@@ -152,7 +147,7 @@ jobs:
152147 echo "Removing builder-debug.yml files to avoid duplicate asset upload conflicts..."
153148 find release-artifacts/ -name "builder-debug.yml" -delete -print || true
154149
155- - name : Create GitHub Release
150+ - name : Create GitHub Release (as pre-release)
156151 uses : softprops/action-gh-release@v2
157152 if : startsWith(github.ref, 'refs/tags/')
158153 with :
@@ -165,8 +160,8 @@ jobs:
165160 release-artifacts/**/*.rpm
166161 release-artifacts/**/*.yml
167162 draft : false
168- prerelease : ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
169- make_latest : ${{ !(contains(github.ref, 'alpha') || contains(github.ref, 'beta')) }}
163+ prerelease : true
164+ make_latest : false
170165 generate_release_notes : true
171166 body : |
172167 ## 🚀 ClawX ${{ github.ref_name }}
@@ -399,3 +394,39 @@ jobs:
399394
400395 echo ""
401396 echo "All files uploaded and verified successfully!"
397+
398+ # ──────────────────────────────────────────────────────────────
399+ # Job: Finalize Release
400+ # Promotes the GitHub Release from pre-release to latest AFTER
401+ # both GitHub Release assets and OSS uploads are fully complete.
402+ # This ensures /releases/latest API never returns an incomplete
403+ # release — the website and electron-updater only see it when
404+ # all platform artifacts are ready.
405+ # ──────────────────────────────────────────────────────────────
406+ finalize :
407+ needs : [publish, upload-oss]
408+ runs-on : ubuntu-latest
409+ if : startsWith(github.ref, 'refs/tags/')
410+
411+ steps :
412+ - name : Promote release from pre-release to latest
413+ env :
414+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
415+ run : |
416+ TAG="${GITHUB_REF#refs/tags/}"
417+ IS_PRERELEASE_CHANNEL=false
418+
419+ if [[ "$TAG" == *"alpha"* ]] || [[ "$TAG" == *"beta"* ]]; then
420+ IS_PRERELEASE_CHANNEL=true
421+ fi
422+
423+ if [ "$IS_PRERELEASE_CHANNEL" = "true" ]; then
424+ echo "Tag $TAG is an alpha/beta release — keeping as pre-release."
425+ else
426+ echo "Promoting $TAG from pre-release to latest release..."
427+ gh release edit "$TAG" \
428+ --prerelease=false \
429+ --latest \
430+ --repo "${{ github.repository }}"
431+ echo "Release $TAG is now the latest release."
432+ fi
0 commit comments