Skip to content

Commit e6cb0e9

Browse files
Scope TestFlight provisioning to the app target
1 parent d689535 commit e6cb0e9

3 files changed

Lines changed: 82 additions & 2 deletions

File tree

.github/workflows/ios-release-safety.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ jobs:
3737
run: |
3838
set -euo pipefail
3939
bash scripts/test-ios-release-identity-audit.sh
40+
bash scripts/test-ios-release-archive-signing-contract.sh
4041
bash scripts/test-ios-signed-release-artifact-audit.sh
4142
bash scripts/test-coredata-release-gate.sh
4243
bash scripts/test-coredata-simulator-rehearsal.sh

scripts/ci/build-audited-ios-release-archive.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,13 @@ xcodebuild_arguments+=(
130130
"MARKETING_VERSION=$EXPECTED_VERSION"
131131
"FEARLESS_GIT_COMMIT=$source_commit"
132132
"DEVELOPMENT_TEAM=$EXPECTED_TEAM"
133-
"CODE_SIGN_STYLE=Manual"
133+
# Keep the application target's reviewed Automatic signing style. A
134+
# PROVISIONING_PROFILE_SPECIFIER passed on the xcodebuild command line is a
135+
# workspace-wide override: Xcode applies it to Pods and Swift-package
136+
# resource bundles too, and those targets correctly reject provisioning
137+
# profiles. The post-build audit below still fails closed unless Xcode chose
138+
# the exact reviewed App Store profile and distribution certificate.
134139
"CODE_SIGN_IDENTITY=$EXPECTED_SIGNING_IDENTITY"
135-
"PROVISIONING_PROFILE_SPECIFIER=$EXPECTED_PROFILE_NAME"
136140
clean
137141
archive
138142
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
5+
readonly BUILD_SCRIPT="$SCRIPT_DIR/ci/build-audited-ios-release-archive.sh"
6+
readonly IDENTITY_AUDIT="$SCRIPT_DIR/ci/audit-ios-release-identity.sh"
7+
readonly FIXTURES="$(mktemp -d "${TMPDIR:-/tmp}/fearless-release-archive-signing-tests.XXXXXX")"
8+
trap 'rm -rf "$FIXTURES"' EXIT
9+
10+
fail() {
11+
printf '%s ERROR: %s\n' "[ios-release-archive-signing-test]" "$*" >&2
12+
exit 1
13+
}
14+
15+
contains_workspace_signing_override() {
16+
grep -Eq \
17+
'^[[:space:]]*"?(CODE_SIGN_STYLE|PROVISIONING_PROFILE(_SPECIFIER)?)=' \
18+
"$1"
19+
}
20+
21+
[[ -f "$BUILD_SCRIPT" && ! -L "$BUILD_SCRIPT" ]] ||
22+
fail "archive build script is missing or unsafe"
23+
[[ -f "$IDENTITY_AUDIT" && ! -L "$IDENTITY_AUDIT" ]] ||
24+
fail "release identity audit is missing or unsafe"
25+
26+
# Command-line build-setting overrides apply to every target in a workspace.
27+
# Profiles and manual signing must remain target-scoped, so neither is allowed
28+
# in the xcodebuild argument vector assembled by this script.
29+
if contains_workspace_signing_override "$BUILD_SCRIPT"; then
30+
fail "archive script contains a workspace-wide signing/profile override"
31+
fi
32+
33+
# Prove the gate rejects both quoted/unquoted spellings and the legacy profile
34+
# key. These mutations reproduce the class of command-line override that makes
35+
# dependency targets fail with "does not support provisioning profiles."
36+
override_number=0
37+
while IFS= read -r override; do
38+
override_number=$((override_number + 1))
39+
mutant="$FIXTURES/override-$override_number.sh"
40+
cp "$BUILD_SCRIPT" "$mutant"
41+
printf '%s\n' "$override" >>"$mutant"
42+
contains_workspace_signing_override "$mutant" ||
43+
fail "gate accepted workspace-wide override mutation: $override"
44+
done <<'OVERRIDES'
45+
CODE_SIGN_STYLE=Manual
46+
"CODE_SIGN_STYLE=Automatic"
47+
PROVISIONING_PROFILE=01234567-89AB-CDEF-0123-456789ABCDEF
48+
"PROVISIONING_PROFILE=01234567-89AB-CDEF-0123-456789ABCDEF"
49+
PROVISIONING_PROFILE_SPECIFIER=Fearless App Store
50+
"PROVISIONING_PROFILE_SPECIFIER=Fearless App Store"
51+
OVERRIDES
52+
53+
grep -Fq '"CODE_SIGN_IDENTITY=$EXPECTED_SIGNING_IDENTITY"' "$BUILD_SCRIPT" ||
54+
fail "archive script does not bind the reviewed distribution identity"
55+
grep -Fq \
56+
'bash "$SCRIPT_DIR/audit-ios-signed-release-artifact.sh"' \
57+
"$BUILD_SCRIPT" ||
58+
fail "archive script no longer invokes the signed-artifact audit"
59+
grep -Fq -- \
60+
'--expected-signing-certificate-sha1 "$EXPECTED_SIGNING_CERTIFICATE_SHA1"' \
61+
"$BUILD_SCRIPT" ||
62+
fail "signed-artifact audit is not bound to the reviewed certificate"
63+
grep -Fq -- \
64+
'--expected-profile-uuid "$EXPECTED_PROFILE_UUID"' \
65+
"$BUILD_SCRIPT" ||
66+
fail "signed-artifact audit is not bound to the reviewed profile UUID"
67+
grep -Fq -- \
68+
'--expected-profile-name "$EXPECTED_PROFILE_NAME"' \
69+
"$BUILD_SCRIPT" ||
70+
fail "signed-artifact audit is not bound to the reviewed profile name"
71+
grep -Fq 'require_setting CODE_SIGN_STYLE "Automatic"' "$IDENTITY_AUDIT" ||
72+
fail "release identity no longer requires target-scoped Automatic signing"
73+
74+
printf '%s\n' \
75+
"[ios-release-archive-signing-test] PASS: canonical contract and $override_number workspace-wide override mutations"

0 commit comments

Comments
 (0)