ci(release): retry Tauri's macOS app staple and log its output

Merged
GN
4d ago
+33-0

Summary

Makes the macOS release build retry stapling the notarization ticket onto the .app, and logs the stapler output that Tauri discards. The v0.4.50 Build (macos-x64) job failed three times in run 39110458854: twice on Termul Manager.app does not have a ticket stapled to it. and once on the DMG staple with Error 68.

Related Issue

Closes #1388

Type of Change

  • chore: maintenance or tooling

What Changed

  • New macOS-only step before the Tauri build, Retry stapler staple during the macOS build. It writes an xcrun shim to $RUNNER_TEMP and prepends it to PATH. The shim retries xcrun stapler staple up to 5 times with delays of 0, 15, 30, 60, and 120 seconds, and appends its output to $RUNNER_TEMP/stapler-staple.log. Every other xcrun call goes straight to /usr/bin/xcrun through exec.
  • Notarize and staple macOS DMG prints that log in a collapsed group. It fails if the log is empty, which would mean Tauri's staple bypassed the shim.
  • The shim stays on PATH for the rest of the job, so the DMG step's own xcrun stapler staple also retries and appends to the log, after the group is printed.

Why the build needs this:

  • tauri-macos-sign's staple_app runs xcrun stapler staple -v with Command::output() and never checks the exit status, so a failed staple leaves no trace.
  • Attempt 3 of the same run showed what the failure is. Our own DMG staple on macos-15-intel failed with NSURLErrorDomain Code=-1005 "The network connection was lost." against https://api.apple-cloudkit.com/database/1/com.apple.gk.ticket-delivery/production/public/records/lookup, then The staple and validate action failed! Error 68. Tauri's silent .app failures are likely the same transient fault: same tool, runner, and endpoint. This is inferred, because Tauri discards the output.
  • Tauri copies the .app into the DMG and the updater .app.tar.gz right after its staple attempt. Stapling later in the workflow would leave both shipped copies unstapled. Retrying inside Tauri's own call keeps the artifacts identical in shape to the v0.4.21 ones.

How It Was Tested

  • Generated the shim by running the step's exact run: block (parsed from the YAML) on Linux, then exercised it with a fake xcrun and sleep:
    • Two failures, then success: exit 0, sleeps 0 15 30, and the log holds both Record not found errors and the success line.
    • Always failing: exit 1 after 5 attempts with sleeps 0 15 30 60 120.
    • Success on the first try: exit 0, one sleep 0.
    • notarytool submit "a b.dmg" --wait and stapler validate: passed through with their exit codes, no retries, no log.
  • Ran the edited Notarize and staple macOS DMG block against the shim. With no log, it exits 1 with Tauri's stapler staple never reached the xcrun shim. With a log, it prints the group, then submits and staples the DMG through the shim.
  • A real macOS release run. The empty-log check makes the first one prove that the shim intercepted Tauri's call.

Checklist

  • Conventional-commit PR title
  • No unrelated modifications
  • Read AGENTS.md

Summary by cubic

Makes the macOS release build resilient to Tauri's stapler running before Apple's notary ticket is retrievable, which caused Build (macos-x64) to ship an unstapled .app in the DMG and updater archive.

  • Adds a macOS-only step that shadows xcrun with a shim retrying stapler staple up to 5 times (0–120s delays) and appends its output to stapler-staple.log.
  • Ensures the notarize-and-staple DMG step fails if the log is empty, proving the shim intercepted Tauri's call, and prints the log in a collapsible group for easier debugging.

Summary by CodeRabbit

  • Chores
    • macOS release packaging now retries app notarization at increasing intervals and reports each attempt. The packaging process also verifies that app stapling was performed and displays its output, helping surface notarization issues during release builds.