#!/bin/bash # Assembles and signs Snapshot.app from the SwiftPM build products. # # restic is bundled at Contents/Helpers/restic and signed with the SAME identity # as the app. That is what makes Full Disk Access survive rebuilds: TCC matches # the app's designated requirement, which names the signing certificate rather # than a code hash, and restic's hash is sealed into the app's CodeResources. set -euo pipefail root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" config="${CONFIGURATION:-release}" identity="${CODESIGN_IDENTITY:-restic-backup}" bundle_id="rs.averyrive.Snapshot" version="${SNAPSHOT_VERSION:-0.1.0}" build_dir="$root/.build/$config" app="$root/.build/Snapshot.app" [[ -x "$build_dir/SnapshotApp" ]] || { echo "make-app: $build_dir/SnapshotApp not found; run 'swift build -c $config' first" >&2 exit 1 } [[ -x "$root/Vendor/restic" ]] || { echo "make-app: Vendor/restic not found; run Scripts/fetch-restic.sh first" >&2 exit 1 } rm -rf "$app" mkdir -p "$app/Contents/MacOS" "$app/Contents/Helpers" "$app/Contents/Resources/Licenses" cp "$build_dir/SnapshotApp" "$app/Contents/MacOS/Snapshot" cp "$root/Vendor/restic" "$app/Contents/Helpers/restic" cp "$root/Vendor/restic-LICENSE.txt" "$app/Contents/Resources/Licenses/restic-LICENSE.txt" if [[ -f "$root/.build/Snapshot.icns" ]]; then cp "$root/.build/Snapshot.icns" "$app/Contents/Resources/Snapshot.icns" else echo "make-app: no icon found; run Scripts/make-icon.sh" >&2 fi restic_version="$("$root/Vendor/restic" version | awk '{ print $2 }')" cat > "$app/Contents/Info.plist" < CFBundleIdentifier$bundle_id CFBundleNameSnapshot CFBundleDisplayNameSnapshot CFBundleExecutableSnapshot CFBundlePackageTypeAPPL CFBundleShortVersionString$version CFBundleVersion$version CFBundleIconFileSnapshot LSMinimumSystemVersion15.0 LSUIElement NSHumanReadableCopyright Bundles restic $restic_version (BSD-2-Clause); see Resources/Licenses. SNBundledResticVersion$restic_version PLIST # Inside-out: nested code first, then the bundle that seals it. codesign --force --options runtime --timestamp=none \ --identifier "$bundle_id.restic" \ --sign "$identity" "$app/Contents/Helpers/restic" codesign --force --options runtime --timestamp=none \ --identifier "$bundle_id" \ --sign "$identity" "$app" codesign --verify --deep --strict "$app" echo "make-app: built $app" echo "make-app: designated requirement:" codesign -d -r- "$app" 2>&1 | sed -n 's/^designated => / /p'