-
Notifications
You must be signed in to change notification settings - Fork 77
Make macOS release resilient to stapler failures and add assistant.zip artifact #1860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -79,6 +79,12 @@ jobs: | |||||
| echo "build_version=$BUILD_VERSION" >> "$GITHUB_OUTPUT" | ||||||
| echo "Display version: $DISPLAY_VERSION / Build version: $BUILD_VERSION" | ||||||
|
|
||||||
| - name: Zip assistant directory | ||||||
| run: | | ||||||
| mkdir -p build | ||||||
| (cd ../.. && zip -r clients/macos/build/assistant.zip assistant/) | ||||||
| ls -lh build/assistant.zip | ||||||
|
|
||||||
| - name: Install Bun | ||||||
| uses: oven-sh/setup-bun@v2 | ||||||
| with: | ||||||
|
|
@@ -215,20 +221,27 @@ jobs: | |||||
| echo "Notarization succeeded" | ||||||
|
|
||||||
| - name: Staple notarization ticket | ||||||
| id: staple | ||||||
| continue-on-error: true | ||||||
| run: | | ||||||
| # Apple's CDN can take several minutes to propagate the ticket after notarization | ||||||
| MAX_ATTEMPTS=15 | ||||||
| WAIT_SECS=60 | ||||||
| for i in $(seq 1 $MAX_ATTEMPTS); do | ||||||
| if xcrun stapler staple "$DMG_PATH" 2>&1; then | ||||||
| STAPLE_OUTPUT=$(xcrun stapler staple "$DMG_PATH" 2>&1) | ||||||
| STAPLE_EXIT=$? | ||||||
| if [ $STAPLE_EXIT -eq 0 ]; then | ||||||
| echo "Stapling succeeded on attempt $i" | ||||||
| echo "$STAPLE_OUTPUT" | ||||||
| break | ||||||
| fi | ||||||
| echo "::warning::Stapling attempt $i/$MAX_ATTEMPTS failed (exit code $STAPLE_EXIT):" | ||||||
| echo "$STAPLE_OUTPUT" | ||||||
| if [ "$i" -eq "$MAX_ATTEMPTS" ]; then | ||||||
| echo "::error::Stapling failed after $MAX_ATTEMPTS attempts" | ||||||
| exit 1 | ||||||
| fi | ||||||
| echo "Stapling attempt $i failed, waiting ${WAIT_SECS}s for CDN propagation..." | ||||||
| echo "Waiting ${WAIT_SECS}s for CDN propagation..." | ||||||
| sleep $WAIT_SECS | ||||||
| # Increase wait time for subsequent attempts (60, 75, 90, 105, ...) | ||||||
| WAIT_SECS=$((WAIT_SECS + 15)) | ||||||
|
|
@@ -308,7 +321,7 @@ jobs: | |||||
| echo "Appcast generated for $REPO" | ||||||
|
|
||||||
| - name: Create GitHub Release on public repos | ||||||
| if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') | ||||||
| if: always() && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Using Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The release step at line 324 uses Root Cause and ImpactIf the build or notarization step fails (e.g., Xcode compilation error, notarization rejection), the DMG, Sparkle ZIP, and appcast won't exist. The intermediate steps ("Build ZIP for Sparkle", "Generate appcast.xml") use The result is:
This replaces a fully functional release (with DMG, Sparkle auto-update ZIP, and appcast) with one containing only a source archive. Users downloading the The intent was to be resilient only to stapler failures (the step with if: (success() || steps.staple.outcome == 'failure') && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. |
||||||
| env: | ||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||
| run: | | ||||||
|
|
@@ -333,11 +346,17 @@ jobs: | |||||
| gh release delete latest --repo "$REPO" --yes 2>/dev/null || true | ||||||
| gh api "repos/$REPO/git/refs/tags/latest" -X DELETE 2>/dev/null || true | ||||||
|
|
||||||
| # Create new release with DMG + ZIP + appcast | ||||||
| # Build asset list from available files | ||||||
| ASSETS=() | ||||||
| [ -f "$DMG_PATH" ] && ASSETS+=("$DMG_PATH") | ||||||
| [ -f "dist/vellum-assistant.zip" ] && ASSETS+=("dist/vellum-assistant.zip") | ||||||
| [ -f "$APPCAST" ] && ASSETS+=("$APPCAST#appcast.xml") | ||||||
| [ -f "build/assistant.zip" ] && ASSETS+=("build/assistant.zip#assistant.zip") | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DevinAI this looks redundant? Looks like we have the assistant artifact on here twice
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are actually two different files:
Want me to remove one, or rename |
||||||
|
|
||||||
| echo "Release assets: ${ASSETS[*]}" | ||||||
|
|
||||||
| gh release create latest \ | ||||||
| "$DMG_PATH" \ | ||||||
| dist/vellum-assistant.zip \ | ||||||
| "$APPCAST#appcast.xml" \ | ||||||
| "${ASSETS[@]}" \ | ||||||
| --repo "$REPO" \ | ||||||
| --title "Vellum $VERSION" \ | ||||||
| --notes "$RELEASE_NOTES" \ | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment runs outside an
ifguard, and GitHub Actionsbashsteps use-e, so a non-zero stapler exit aborts the script immediately on the first failed attempt. As a result, the retry loop and its diagnostics are skipped for transient CDN propagation failures, and because the step iscontinue-on-error, the workflow can proceed to release without ever completing the intended stapling/validation retries.Useful? React with 👍 / 👎.