Files
konverter/release.sh
T
TZGyn 2d031e58a4 Add Konverter: a local-only menu bar file converter
Drag files in Finder, hold a modifier, and drop on a wheel of outputs.
Conversions run entirely on-device through ImageIO, PDFKit, AVFoundation,
the bundled CLI tools, and optional ffmpeg/LibreOffice.

Includes a --self-test suite (41 checks) and a --convert CLI mode so the
conversion matrix can be verified without the UI.
2026-10-20 00:36:40 +08:00

96 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# Builds, signs, notarizes, staples, and zips Konverter for release.
#
# ./release.sh 0.1.0
#
# Notarization is required. If it fails, this script fails: do not publish the
# tag, release, or cask from an unnotarized build.
set -euo pipefail
cd "$(dirname "$0")"
if [ "$#" -ne 1 ]; then
echo "usage: $0 <version> e.g. ./release.sh 0.1.0" >&2
exit 1
fi
VERSION="$1"
APP="Konverter.app"
ZIP="dist/Konverter.zip"
IDENT=$(security find-identity -v -p codesigning 2>/dev/null \
| awk '/Developer ID Application:/ { print $2; exit }')
if [ -z "$IDENT" ]; then
echo "release.sh: no Developer ID Application identity in the keychain." >&2
echo "An ad-hoc signed build cannot be notarized; install the certificate first." >&2
exit 1
fi
KEY_PATH="${KONVERTER_NOTARY_API_KEY_PATH:-$HOME/.config/kapture/AuthKey_K5KXMMSB28.p8}"
KEY_ID="${KONVERTER_NOTARY_API_KEY_ID:-K5KXMMSB28}"
ISSUER="${KONVERTER_NOTARY_API_ISSUER:-3e25e5dc-8b75-453f-a71c-c7f3feaac628}"
if [ ! -f "$KEY_PATH" ]; then
echo "release.sh: notary API key not found at $KEY_PATH" >&2
exit 1
fi
if ! xcrun --find notarytool >/dev/null 2>&1; then
echo "release.sh: xcrun notarytool not found (requires Xcode 13+)." >&2
exit 1
fi
./build-app.sh "$VERSION"
# The zip submitted to Apple must contain the signed bundle only.
mkdir -p dist
rm -f "$ZIP"
ditto -c -k --keepParent "$APP" "$ZIP"
echo "Submitting to Apple for notarization (first run can take minutes)..."
RESULT=$(mktemp)
trap 'rm -f "$RESULT"' EXIT
xcrun notarytool submit "$ZIP" \
--key "$KEY_PATH" \
--key-id "$KEY_ID" \
--issuer "$ISSUER" \
--wait \
--output-format json > "$RESULT"
STATUS=$(/usr/bin/python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("status","unknown"))' "$RESULT" 2>/dev/null || echo unknown)
if [ "$STATUS" != "Accepted" ]; then
echo "release.sh: notarization returned '$STATUS' — release aborted." >&2
cat "$RESULT" >&2
SUBMIT_ID=$(/usr/bin/python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("id",""))' "$RESULT" 2>/dev/null || true)
if [ -n "$SUBMIT_ID" ]; then
echo "Detail:" >&2
xcrun notarytool log "$SUBMIT_ID" --key "$KEY_PATH" --key-id "$KEY_ID" --issuer "$ISSUER" >&2 || true
fi
exit 1
fi
echo "Notarization accepted — stapling ticket onto the app..."
xcrun stapler staple "$APP"
xcrun stapler validate "$APP"
# Re-zip so the distributed archive carries the stapled ticket.
rm -f "$ZIP"
ditto -c -k --keepParent "$APP" "$ZIP"
echo "Verifying Gatekeeper assessment..."
if ! spctl -a -vv "$APP" 2>&1 | grep -q 'source=Notarized Developer ID'; then
echo "release.sh: spctl does not report 'source=Notarized Developer ID' — release aborted." >&2
spctl -a -vv "$APP" >&2 || true
exit 1
fi
spctl -a -vv "$APP" 2>&1 | sed 's/^/ /'
echo
echo "Done — notarized and stapled."
shasum -a 256 "$ZIP"
echo
echo "Publish with:"
echo " git tag v$VERSION && git push origin v$VERSION"
echo " tea releases create --tag v$VERSION --title \"Konverter $VERSION\" \\"
echo " --note \"<what changed>\" --asset $ZIP \\"
echo " --repo TZGyn/konverter --login gitea.tzgyn.dev"