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.
96 lines
3.1 KiB
Bash
Executable File
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"
|