#!/usr/bin/env bash # Build, sign, notarize, staple and (optionally) publish a macOS release of # neotalk to the Gitea releases page. Run on macOS. # # ./packaging/release-macos.sh v0.1.0 # # Credentials are read from the environment so nothing secret lives in the repo: # # NEOTALK_SIGN_IDENTITY Developer ID (defaults to Andros' Developer ID) # Notarization (pick one): # NEOTALK_NOTARY_PROFILE a notarytool keychain profile, created once with: # xcrun notarytool store-credentials neotalk \ # --apple-id you@example.com --team-id M3K3T47KXF --password APP-SPECIFIC-PW # or: # NEOTALK_APPLE_ID, NEOTALK_APPLE_PASSWORD Apple ID + app-specific password # Publishing (optional): # NEOTALK_GITEA_TOKEN Gitea token with repo write; uploads the .zip set -euo pipefail TAG="${1:?usage: release-macos.sh , e.g. v0.1.0}" HERE="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "$HERE/.." && pwd)" cd "$ROOT" APP="dist/neotalk.app" ZIP="dist/neotalk-macos-${TAG}.zip" TEAM_ID="M3K3T47KXF" GITEA_API="https://git.andros.dev/api/v1/repos/andros/neotalk" echo "==> Building" rm -rf dist build/pyinstaller uv run --extra build pyinstaller --noconfirm --clean \ --distpath dist --workpath build/pyinstaller packaging/neotalk.spec >/dev/null echo "==> Signing" "$HERE/sign-macos.sh" "$APP" echo "==> Zipping for notarization" /usr/bin/ditto -c -k --keepParent "$APP" "$ZIP" echo "==> Notarizing" if [ -n "${NEOTALK_NOTARY_PROFILE:-}" ]; then xcrun notarytool submit "$ZIP" --keychain-profile "$NEOTALK_NOTARY_PROFILE" --wait elif [ -n "${NEOTALK_APPLE_ID:-}" ] && [ -n "${NEOTALK_APPLE_PASSWORD:-}" ]; then xcrun notarytool submit "$ZIP" --apple-id "$NEOTALK_APPLE_ID" \ --team-id "$TEAM_ID" --password "$NEOTALK_APPLE_PASSWORD" --wait else echo "No notarization credentials set. Signed app is at $APP." >&2 echo "Set NEOTALK_NOTARY_PROFILE or NEOTALK_APPLE_ID/NEOTALK_APPLE_PASSWORD." >&2 exit 2 fi echo "==> Stapling" xcrun stapler staple "$APP" xcrun stapler validate "$APP" rm -f "$ZIP" /usr/bin/ditto -c -k --keepParent "$APP" "$ZIP" echo "Notarized, stapled artifact: $ZIP" if [ -z "${NEOTALK_GITEA_TOKEN:-}" ]; then echo "NEOTALK_GITEA_TOKEN not set; skipping upload. Upload $ZIP by hand if you like." exit 0 fi echo "==> Publishing release $TAG to Gitea" release_id=$( curl -fsS -X POST "$GITEA_API/releases" \ -H "Authorization: token $NEOTALK_GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"tag_name\":\"$TAG\",\"name\":\"neotalk $TAG\",\"draft\":false,\"prerelease\":false}" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" ) curl -fsS -X POST \ "$GITEA_API/releases/$release_id/assets?name=$(basename "$ZIP")" \ -H "Authorization: token $NEOTALK_GITEA_TOKEN" \ -F "attachment=@$ZIP" >/dev/null echo "Published: https://git.andros.dev/andros/neotalk/releases/tag/$TAG"