diff --git a/AGENTS.md b/AGENTS.md index c4594cf2..0fc228b8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,6 +25,8 @@ make test-cli-integration # Run CLI integration tests (socket round-trip) make bump-version # Bump version (date-based YYYY.M.DD) and create git tag; used by release.sh ``` +Debug builds are ad-hoc signed by default, so building needs no certificate. An ad-hoc signature's designated requirement is its cdhash, which changes on every rebuild, so macOS re-asks for Desktop/Documents/Downloads access from Prowl Debug — and from the commands running in its panes — after each build. If your worktrees live in those folders, set `PROWL_DEVELOPMENT_TEAM=` (environment or `Config/Secrets.env`) and `make build-app` / `make test` sign the Debug app and test host with your Apple Development identity instead; the Team ID is the certificate's OU, not the ID in parentheses after your name. With it set, replace the `CODE_SIGNING_*` settings in ad-hoc `xcodebuild test` invocations like the one below with `DEVELOPMENT_TEAM=` so the test host keeps the same signature. + Run a single test class or method: ```bash diff --git a/Config/Secrets.env.template b/Config/Secrets.env.template index 5332a853..f63448a6 100644 --- a/Config/Secrets.env.template +++ b/Config/Secrets.env.template @@ -1,11 +1,12 @@ -# Analytics and crash reporting credentials for Release builds. +# Local build configuration: analytics and crash reporting credentials for Release +# builds, plus optional Debug signing. # # Setup: # 1. Copy this file: cp Config/Secrets.env.template Config/Secrets.env # 2. Fill in the real values below. # 3. Config/Secrets.env is gitignored. # -# These values are injected into Info.plist at build time by the Makefile's +# The analytics values are injected into Info.plist at build time by the Makefile's # `archive` target and read at runtime from Bundle.main. # # Debug builds never initialize the SDKs, so empty values are fine during @@ -14,3 +15,10 @@ PROWL_SENTRY_DSN= PROWL_POSTHOG_API_KEY= PROWL_POSTHOG_HOST=https://us.i.posthog.com + +# Optional: Team ID of an Apple Development certificate in your keychain. When set, +# `make build-app` and `make test` sign the Debug app and test host with it, so the +# macOS folder-access grants (Desktop, Documents, Downloads, ...) survive rebuilds; +# ad-hoc Debug builds are re-asked after every rebuild. Use the certificate's OU +# (the Team ID), not the ID in parentheses after your name. Empty keeps ad-hoc. +PROWL_DEVELOPMENT_TEAM= diff --git a/Makefile b/Makefile index 2abe5ffb..489729cf 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,23 @@ PROWL_SENTRY_DSN ?= PROWL_POSTHOG_API_KEY ?= PROWL_POSTHOG_HOST ?= +# Local Debug signing. Debug products are ad-hoc signed by default, and an ad-hoc +# signature's designated requirement is its cdhash, which changes on every rebuild: +# TCC then treats each build as a new app and re-asks for Desktop/Documents/Downloads +# access from Prowl Debug and from the commands running in its panes. Setting +# PROWL_DEVELOPMENT_TEAM (environment or Config/Secrets.env) makes build-app and +# test-app sign the app and the test host with that team's Apple Development identity +# through Xcode's automatic signing, so the grants survive rebuilds. Empty keeps +# ad-hoc signing, which needs no certificate (CI, contributors). +PROWL_DEVELOPMENT_TEAM ?= +ifneq ($(strip $(PROWL_DEVELOPMENT_TEAM)),) +DEBUG_SIGNING_ARGS := DEVELOPMENT_TEAM=$(PROWL_DEVELOPMENT_TEAM) +TEST_SIGNING_ARGS := $(DEBUG_SIGNING_ARGS) +else +DEBUG_SIGNING_ARGS := +TEST_SIGNING_ARGS := CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" +endif + .DEFAULT_GOAL := help .PHONY: build-ghostty-xcframework ensure-ghostty sync-ghostty _record-ghostty-hash build-app build-cli build-cli-release embed-cli-debug embed-cli embed-docs run-app install-dev-build install-release archive export-archive format format-changed format-lint lint check test test-app test-scripts test-cli-smoke test-cli-integration benchmark-build bump-version log-stream @@ -112,7 +129,7 @@ embed-docs: # Stage docs/ into Resources for bundling into the app (.app/Content echo "embedded docs at $$dst" build-app: ensure-ghostty embed-cli-debug embed-docs # Build the macOS app (Debug) - bash -o pipefail -c 'xcodebuild -project supacode.xcodeproj -scheme supacode -configuration Debug build -skipMacroValidation -clonedSourcePackagesDirPath $(SPM_CACHE_DIR) SWIFT_COMPILATION_MODE=incremental 2>&1 | mise exec -- xcsift -w --format toon' + bash -o pipefail -c 'xcodebuild -project supacode.xcodeproj -scheme supacode -configuration Debug build -skipMacroValidation -clonedSourcePackagesDirPath $(SPM_CACHE_DIR) SWIFT_COMPILATION_MODE=incremental $(DEBUG_SIGNING_ARGS) 2>&1 | mise exec -- xcsift -w --format toon' sync-cli-version: # Sync app MARKETING_VERSION into ProwlCLIShared/ProwlVersion.swift @version="$$(/usr/bin/awk -F' = ' '/MARKETING_VERSION = [0-9.]*;/{gsub(/;/,"",$$2);print $$2; exit}' \ @@ -335,7 +352,7 @@ test-app: ensure-ghostty # Run app/unit tests via xcodebuild mkdir -p "$$(dirname "$$result_bundle")"; \ rm -rf "$$result_bundle"; \ set +e; \ - xcodebuild test -project supacode.xcodeproj -scheme supacode -destination "platform=macOS" -resultBundlePath "$$result_bundle" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" -skipMacroValidation -clonedSourcePackagesDirPath $(SPM_CACHE_DIR) SWIFT_COMPILATION_MODE=incremental 2>&1 | mise exec -- xcsift -w --format toon; \ + xcodebuild test -project supacode.xcodeproj -scheme supacode -destination "platform=macOS" -resultBundlePath "$$result_bundle" $(TEST_SIGNING_ARGS) -skipMacroValidation -clonedSourcePackagesDirPath $(SPM_CACHE_DIR) SWIFT_COMPILATION_MODE=incremental 2>&1 | mise exec -- xcsift -w --format toon; \ xcodebuild_status=$${PIPESTATUS[0]}; \ set -e; \ if [ "$$xcodebuild_status" -ne 0 ]; then \