mirror of
https://github.com/block/buzz.git
synced 2026-10-30 14:01:37 +00:00
refactor(push): simplify internal notification stack
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
This commit is contained in:
@@ -107,9 +107,6 @@ run_unit_tests() {
|
||||
run_test_step "buzz-push-gateway tests" \
|
||||
cargo test -p buzz-push-gateway -- --nocapture
|
||||
|
||||
run_test_step "buzz-push-gateway dev App Attest bypass tests" \
|
||||
cargo test -p buzz-push-gateway --features dev-app-attest-bypass -- --nocapture
|
||||
|
||||
# Kubernetes backend provider: pure decision layers driven by a fake
|
||||
# substrate, no cluster. Mirrors the nextest path in `just test-unit` —
|
||||
# the two lists must stay in step or the fallback silently covers less.
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate the semantic iOS target/configuration table via macOS plutil."""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PBXPROJ = Path("mobile/ios/Runner.xcodeproj/project.pbxproj")
|
||||
# This asserts plutil-resolved pbxproj declarations, not object-key uniqueness or
|
||||
# the final xcconfig-expanded bundle identity.
|
||||
EXPECTED_ROWS = """\
|
||||
NotificationService Debug Flutter/Debug.xcconfig $(BUZZ_DEVELOPMENT_TEAM) NotificationService/NotificationService.entitlements $(BUNDLE_IDENTIFIER).NotificationService
|
||||
NotificationService Profile Flutter/Release.xcconfig $(BUZZ_DEVELOPMENT_TEAM) NotificationService/NotificationService.entitlements $(BUNDLE_IDENTIFIER).NotificationService
|
||||
NotificationService Release Flutter/Release.xcconfig $(BUZZ_DEVELOPMENT_TEAM) NotificationService/NotificationService.entitlements $(BUNDLE_IDENTIFIER).NotificationService
|
||||
Runner Debug Flutter/Debug.xcconfig $(BUZZ_DEVELOPMENT_TEAM) Runner/Runner.entitlements $(BUNDLE_IDENTIFIER)
|
||||
Runner Profile Flutter/Release.xcconfig $(BUZZ_DEVELOPMENT_TEAM) Runner/Runner.entitlements $(BUNDLE_IDENTIFIER)
|
||||
Runner Release Flutter/Release.xcconfig $(BUZZ_DEVELOPMENT_TEAM) Runner/Runner.entitlements $(BUNDLE_IDENTIFIER)
|
||||
RunnerTests Debug Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig - - $(BUNDLE_IDENTIFIER).RunnerTests
|
||||
RunnerTests Profile Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig - - $(BUNDLE_IDENTIFIER).RunnerTests
|
||||
RunnerTests Release Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig - - $(BUNDLE_IDENTIFIER).RunnerTests
|
||||
""".splitlines()
|
||||
|
||||
|
||||
def parse_project(path: Path) -> dict:
|
||||
result = subprocess.run(
|
||||
["plutil", "-convert", "json", "-o", "-", str(path)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
detail = result.stderr.strip() or "no error detail"
|
||||
raise RuntimeError(f"plutil failed to parse {path}: {detail}")
|
||||
if not result.stdout:
|
||||
raise RuntimeError(f"plutil returned no JSON for {path}")
|
||||
return json.loads(result.stdout)
|
||||
|
||||
|
||||
def semantic_rows(project: dict) -> list[str]:
|
||||
objects = project["objects"]
|
||||
root = objects[project["rootObject"]]
|
||||
rows = []
|
||||
for target_id in root["targets"]:
|
||||
target = objects[target_id]
|
||||
if target.get("isa") != "PBXNativeTarget":
|
||||
continue
|
||||
configuration_list = objects[target["buildConfigurationList"]]
|
||||
for configuration_id in configuration_list["buildConfigurations"]:
|
||||
configuration = objects[configuration_id]
|
||||
settings = configuration.get("buildSettings", {})
|
||||
base_reference = configuration.get("baseConfigurationReference")
|
||||
base_path = objects.get(base_reference, {}).get("path", "-")
|
||||
rows.append(
|
||||
" ".join(
|
||||
[
|
||||
target.get("name", "-"),
|
||||
configuration.get("name", "-"),
|
||||
base_path,
|
||||
settings.get("DEVELOPMENT_TEAM", "-"),
|
||||
settings.get("CODE_SIGN_ENTITLEMENTS", "-"),
|
||||
settings.get("PRODUCT_BUNDLE_IDENTIFIER", "-"),
|
||||
]
|
||||
)
|
||||
)
|
||||
return sorted(rows)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
path = Path(sys.argv[1]) if len(sys.argv) > 1 else PBXPROJ
|
||||
try:
|
||||
actual = semantic_rows(parse_project(path))
|
||||
except (KeyError, TypeError, json.JSONDecodeError, RuntimeError) as error:
|
||||
print(f"FAIL: {error}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if actual != EXPECTED_ROWS:
|
||||
print("FAIL: unexpected iOS target configuration semantics", file=sys.stderr)
|
||||
print("expected:", *EXPECTED_ROWS, sep="\n", file=sys.stderr)
|
||||
print("actual:", *actual, sep="\n", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print("iOS target configuration semantics match")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -152,8 +152,6 @@ fi
|
||||
# ── Tracked build files: overrides are debug-only, release stays production ──
|
||||
debug_xcconfig="$repo_root/mobile/ios/Flutter/Debug.xcconfig"
|
||||
release_xcconfig="$repo_root/mobile/ios/Flutter/Release.xcconfig"
|
||||
pbxproj="$repo_root/mobile/ios/Runner.xcodeproj/project.pbxproj"
|
||||
runner_entitlements="$repo_root/mobile/ios/Runner/Runner.entitlements"
|
||||
gradle="$repo_root/mobile/android/app/build.gradle.kts"
|
||||
manifest="$repo_root/mobile/android/app/src/main/AndroidManifest.xml"
|
||||
plist="$repo_root/mobile/ios/Runner/Info.plist"
|
||||
@@ -185,348 +183,6 @@ grep -q '^APP_DISPLAY_NAME = Buzz$' "$release_xcconfig" \
|
||||
&& pass "Release.xcconfig keeps the production display name" \
|
||||
|| fail "Release.xcconfig must keep APP_DISPLAY_NAME = Buzz"
|
||||
|
||||
# These checks assert declarations in the two tracked xcconfigs only. They do
|
||||
# not prove resolved build settings. The later gitignored includes
|
||||
# (WorktreeOverrides.xcconfig and AppOverrides.xcconfig) can override these
|
||||
# declarations and are explicitly outside this tracked-source assertion. The
|
||||
# value check and declaration census are complementary: xcconfig is last-wins,
|
||||
# while the census deliberately flags even a harmless duplicate declaration so
|
||||
# a human reviews the changed declaration surface.
|
||||
assert_xcconfig_value() {
|
||||
# $1: file, $2: anchored value regex, $3: pass/failure description
|
||||
if grep -qE "$2" "$1"; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_xcconfig_declaration_count() {
|
||||
# $1: file, $2: key, $3: expected count, $4: configuration label
|
||||
local file="$1" key="$2" expected="$3" label="$4" count
|
||||
count=$(grep -cE "^[[:space:]]*$key([[:space:]]*\[[^]]*\])*[[:space:]]*=" "$file" || true)
|
||||
if [[ "$count" -eq "$expected" ]]; then
|
||||
if [[ "$expected" -eq 0 ]]; then
|
||||
pass "$label $key has no tracked declaration sites"
|
||||
elif [[ "$expected" -eq 1 ]]; then
|
||||
pass "$label $key has one tracked declaration site"
|
||||
else
|
||||
pass "$label $key has $count tracked declaration sites"
|
||||
fi
|
||||
elif [[ "$expected" -eq 0 ]]; then
|
||||
fail "$label $key has $count tracked declaration sites; expected zero"
|
||||
elif [[ "$expected" -eq 1 ]]; then
|
||||
fail "$label $key has $count tracked declaration sites; expected exactly one"
|
||||
else
|
||||
fail "$label $key has $count tracked declaration sites; expected $expected"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_single_xcconfig_declaration() {
|
||||
# $1: file, $2: key, $3: configuration label
|
||||
assert_xcconfig_declaration_count "$1" "$2" 1 "$3"
|
||||
}
|
||||
|
||||
for config in "$debug_xcconfig" "$release_xcconfig"; do
|
||||
assert_xcconfig_value "$config" \
|
||||
'^BUZZ_APP_GROUP_IDENTIFIER = group\.\$\(BUNDLE_IDENTIFIER\)$' \
|
||||
"$(basename "$config") derives the push App Group from the bundle"
|
||||
assert_xcconfig_value "$config" \
|
||||
'^BUZZ_KEYCHAIN_ACCESS_GROUP = \$\(BUNDLE_IDENTIFIER\)$' \
|
||||
"$(basename "$config") derives the push Keychain group from the bundle"
|
||||
done
|
||||
assert_xcconfig_value "$debug_xcconfig" \
|
||||
'^BUZZ_IOS_PUSH_ENVIRONMENT = development$' \
|
||||
"Debug uses sandbox APNs"
|
||||
assert_xcconfig_value "$debug_xcconfig" \
|
||||
'^BUZZ_APP_ATTEST_ENVIRONMENT = development$' \
|
||||
"Debug uses development App Attest"
|
||||
assert_xcconfig_value "$release_xcconfig" \
|
||||
'^BUZZ_IOS_PUSH_ENVIRONMENT = production$' \
|
||||
"Release uses production APNs"
|
||||
assert_xcconfig_value "$release_xcconfig" \
|
||||
'^BUZZ_APP_ATTEST_ENVIRONMENT = production$' \
|
||||
"Release uses production App Attest"
|
||||
assert_xcconfig_value "$release_xcconfig" \
|
||||
'^CODE_SIGN_STYLE = Automatic$' \
|
||||
"Release code signing style is declared as automatic"
|
||||
assert_xcconfig_value "$release_xcconfig" \
|
||||
'^CODE_SIGN_IDENTITY = iPhone Developer$' \
|
||||
"Release code signing identity is declared as iPhone Developer"
|
||||
|
||||
for key in BUNDLE_IDENTIFIER; do
|
||||
assert_single_xcconfig_declaration "$debug_xcconfig" "$key" "Debug"
|
||||
assert_single_xcconfig_declaration "$release_xcconfig" "$key" "Release"
|
||||
done
|
||||
|
||||
for key in BUZZ_KEYCHAIN_ACCESS_GROUP BUZZ_IOS_PUSH_ENVIRONMENT BUZZ_APP_ATTEST_ENVIRONMENT BUZZ_APP_GROUP_IDENTIFIER; do
|
||||
assert_single_xcconfig_declaration "$debug_xcconfig" "$key" "Debug"
|
||||
assert_single_xcconfig_declaration "$release_xcconfig" "$key" "Release"
|
||||
done
|
||||
|
||||
for key in BUZZ_PUSH_ENABLED BUZZ_CODE_SIGN_ENTITLEMENTS EXCLUDED_SOURCE_FILE_NAMES DART_DEFINES; do
|
||||
assert_xcconfig_declaration_count "$debug_xcconfig" "$key" 0 "Debug"
|
||||
assert_xcconfig_declaration_count "$release_xcconfig" "$key" 0 "Release"
|
||||
done
|
||||
|
||||
for key in CODE_SIGN_STYLE CODE_SIGN_IDENTITY; do
|
||||
assert_xcconfig_declaration_count "$debug_xcconfig" "$key" 0 "Debug"
|
||||
assert_single_xcconfig_declaration "$release_xcconfig" "$key" "Release"
|
||||
done
|
||||
|
||||
assert_xcconfig_declaration_count \
|
||||
"$debug_xcconfig" PROVISIONING_PROFILE_SPECIFIER 0 "Debug"
|
||||
assert_xcconfig_declaration_count \
|
||||
"$release_xcconfig" PROVISIONING_PROFILE_SPECIFIER 0 "Release"
|
||||
assert_single_xcconfig_declaration "$debug_xcconfig" APP_DISPLAY_NAME "Debug"
|
||||
assert_single_xcconfig_declaration "$release_xcconfig" APP_DISPLAY_NAME "Release"
|
||||
|
||||
# SWIFT_ACTIVE_COMPILATION_CONDITIONS is checked separately from the closed
|
||||
# identity census above. This is a tracked-source assertion only; resolved Xcode
|
||||
# build settings are intentionally outside this Linux-compatible test.
|
||||
assert_xcconfig_value "$debug_xcconfig" \
|
||||
'^SWIFT_ACTIVE_COMPILATION_CONDITIONS = \$\(inherited\) DEBUG$' \
|
||||
"Debug Swift compilation conditions inherit DEBUG"
|
||||
|
||||
debug_swift_condition_count=$(grep -cE \
|
||||
'^[[:space:]]*SWIFT_ACTIVE_COMPILATION_CONDITIONS([[:space:]]*\[[^]]*\])*[[:space:]]*=' \
|
||||
"$debug_xcconfig" || true)
|
||||
if [[ "$debug_swift_condition_count" -eq 1 ]]; then
|
||||
pass "Debug SWIFT_ACTIVE_COMPILATION_CONDITIONS has one tracked declaration site"
|
||||
else
|
||||
fail "Debug SWIFT_ACTIVE_COMPILATION_CONDITIONS has $debug_swift_condition_count tracked declaration sites; expected exactly one"
|
||||
fi
|
||||
|
||||
release_swift_condition_count=$(grep -cE \
|
||||
'^[[:space:]]*SWIFT_ACTIVE_COMPILATION_CONDITIONS([[:space:]]*\[[^]]*\])*[[:space:]]*=' \
|
||||
"$release_xcconfig" || true)
|
||||
if [[ "$release_swift_condition_count" -eq 0 ]]; then
|
||||
pass "Release SWIFT_ACTIVE_COMPILATION_CONDITIONS has no tracked declaration sites"
|
||||
else
|
||||
fail "Release SWIFT_ACTIVE_COMPILATION_CONDITIONS has $release_swift_condition_count tracked declaration sites; expected zero"
|
||||
fi
|
||||
|
||||
grep -q '<key>aps-environment</key>' "$runner_entitlements" \
|
||||
&& pass "Runner entitlements always include APNs support" \
|
||||
|| fail "Runner entitlements must include aps-environment"
|
||||
|
||||
# Split the retired identifiers so the regression test does not match itself.
|
||||
retired_bundle_id='com.buzz.buzz'"Mobile"
|
||||
if git -C "$repo_root" grep -q -F "$retired_bundle_id"; then
|
||||
fail "tracked files must not retain the retired iOS bundle identifier"
|
||||
else
|
||||
pass "tracked files do not retain the retired iOS bundle identifier"
|
||||
fi
|
||||
grep -q '<key>com.apple.developer.devicecheck.appattest-environment</key>' "$runner_entitlements" \
|
||||
&& pass "Runner uses the App Attest entitlement key accepted by Apple" \
|
||||
|| fail "Runner must use com.apple.developer.devicecheck.appattest-environment"
|
||||
retired_entitlement_key='com.apple.developer.app-attest.'"environment"
|
||||
if grep -q "$retired_entitlement_key" "$runner_entitlements"; then
|
||||
fail "Runner must not retain the invalid App Attest entitlement key"
|
||||
else
|
||||
pass "Runner omits the invalid App Attest entitlement key"
|
||||
fi
|
||||
|
||||
duplicate_pbx_object_ids=$(awk '
|
||||
# This bounded source-level smoke check recognizes the current two-tab
|
||||
# object-key spellings. It is not a general OpenStep uniqueness check:
|
||||
# measured exclusions include a comment before the key, a presentation
|
||||
# comment spanning lines, and one-tab indentation (jb_b1/jb_b2/jb_b6).
|
||||
# The macOS semantic check below owns their resolved build consequences.
|
||||
function decomment(s, head, tailpart) {
|
||||
while (match(s, /\/\*/)) {
|
||||
head = substr(s, 1, RSTART - 1)
|
||||
tailpart = substr(s, RSTART + 2)
|
||||
if (!match(tailpart, /\*\//)) return head " "
|
||||
s = head " " substr(tailpart, RSTART + RLENGTH)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
/^\t\t/ {
|
||||
line = decomment($0)
|
||||
if (match(line, /^\t\t"?[[:alnum:]]+"?[[:space:]]*=/)) {
|
||||
object_id = substr(line, RSTART, RLENGTH)
|
||||
sub(/^\t\t"?/, "", object_id)
|
||||
sub(/"?[[:space:]]*=$/, "", object_id)
|
||||
if (++object_id_count[object_id] == 2) print object_id
|
||||
}
|
||||
}
|
||||
' "$pbxproj" | sort)
|
||||
if [[ -n "$duplicate_pbx_object_ids" ]]; then
|
||||
fail "recognized iOS project object identifiers repeat: $(printf '%s\n' "$duplicate_pbx_object_ids" | paste -sd ' ' -)"
|
||||
else
|
||||
pass "recognized iOS project object identifiers do not repeat"
|
||||
fi
|
||||
|
||||
signing_map=$(awk '
|
||||
# PBX comments are separators, not text: strip them before parsing any
|
||||
# object so a comment cannot hide a duplicate key from the ambiguity count.
|
||||
function decomment(s, head, tailpart) {
|
||||
while (match(s, /\/\*/)) {
|
||||
head = substr(s, 1, RSTART - 1)
|
||||
tailpart = substr(s, RSTART + 2)
|
||||
if (!match(tailpart, /\*\//)) { return head " " }
|
||||
s = head " " substr(tailpart, RSTART + RLENGTH)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
FNR == 1 { pass++ }
|
||||
|
||||
# Pass 1 indexes xcconfig paths and follows each PBXNativeTarget to its
|
||||
# actual configuration-list object. Target names come from object fields,
|
||||
# not presentation comments.
|
||||
pass == 1 {
|
||||
if (/isa[[:space:]]*=[[:space:]]*PBXFileReference/ && /\.xcconfig/) {
|
||||
declaration = decomment($0)
|
||||
if (match(declaration, /=[[:space:]]*\{[[:space:]]*isa[[:space:]]*=[[:space:]]*PBXFileReference[[:space:]]*;/)) {
|
||||
declaration = substr(declaration, RSTART + RLENGTH)
|
||||
} else {
|
||||
declaration = ""
|
||||
}
|
||||
sub(/\}.*/, "", declaration)
|
||||
xcconfig_path = "MISSING_PATH"
|
||||
rest = declaration
|
||||
path_matches = 0
|
||||
while (match(rest, /(^|;)[[:space:]]*path[[:space:]]*=[[:space:]]*[^;]+/)) {
|
||||
candidate = substr(rest, RSTART, RLENGTH)
|
||||
rest = substr(rest, RSTART + RLENGTH)
|
||||
sub(/^;?[[:space:]]*path[[:space:]]*=[[:space:]]*/, "", candidate)
|
||||
gsub(/"/, "", candidate)
|
||||
sub(/[[:space:]]+$/, "", candidate)
|
||||
path_matches++
|
||||
xcconfig_path = candidate
|
||||
}
|
||||
# More than one `path =` in one object means a decoy (a quoted value or
|
||||
# an embedded comment) is shadowing the real key. Never guess which one
|
||||
# the build uses: fail the row loudly instead.
|
||||
if (path_matches > 1) xcconfig_path = "AMBIGUOUS_PATH"
|
||||
xcconfig_paths[$1] = xcconfig_path
|
||||
}
|
||||
|
||||
if (/\/\* Begin PBXNativeTarget section \*\//) {
|
||||
in_native_targets = 1
|
||||
next
|
||||
}
|
||||
if (/\/\* End PBXNativeTarget section \*\//) {
|
||||
in_native_targets = 0
|
||||
next
|
||||
}
|
||||
if (!in_native_targets) next
|
||||
|
||||
if (/^\t\t[^[:space:]]+ .* = \{$/) {
|
||||
native_target_id = $1
|
||||
native_target_name = ""
|
||||
native_target_list = ""
|
||||
next
|
||||
}
|
||||
if (native_target_id != "" && /^\t\t\tname = /) {
|
||||
native_target_name = $0
|
||||
sub(/^.*= */, "", native_target_name)
|
||||
sub(/;.*/, "", native_target_name)
|
||||
gsub(/"/, "", native_target_name)
|
||||
next
|
||||
}
|
||||
if (native_target_id != "" && /^\t\t\tbuildConfigurationList = /) {
|
||||
native_target_list = $3
|
||||
next
|
||||
}
|
||||
if (native_target_id != "" && /^\t\t\};/) {
|
||||
if (native_target_list != "") {
|
||||
if (native_target_name == "") native_target_name = "UNNAMED:" native_target_id
|
||||
if (native_target_list in list_owners) {
|
||||
list_owners[native_target_list] = "DUPLICATE:" list_owners[native_target_list] "+" native_target_name
|
||||
} else {
|
||||
list_owners[native_target_list] = native_target_name
|
||||
}
|
||||
}
|
||||
native_target_id = ""
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
# Pass 2 maps build-configuration object IDs through only those lists that
|
||||
# real native targets own. PBXProject and other unowned lists are ignored.
|
||||
pass == 2 {
|
||||
if (/\/\* Begin XCConfigurationList section \*\//) {
|
||||
in_configuration_lists = 1
|
||||
next
|
||||
}
|
||||
if (/\/\* End XCConfigurationList section \*\//) {
|
||||
in_configuration_lists = 0
|
||||
next
|
||||
}
|
||||
if (!in_configuration_lists) next
|
||||
|
||||
if (/^\t\t[^[:space:]]+ .* = \{$/) {
|
||||
configuration_list_id = $1
|
||||
configuration_list_owner = configuration_list_id in list_owners ? list_owners[configuration_list_id] : ""
|
||||
next
|
||||
}
|
||||
if (/buildConfigurations = \(/) {
|
||||
in_list_configurations = 1
|
||||
next
|
||||
}
|
||||
if (in_list_configurations && /\);/) {
|
||||
in_list_configurations = 0
|
||||
next
|
||||
}
|
||||
if (in_list_configurations && $1 ~ /^[[:alnum:]]+$/ && configuration_list_owner != "") {
|
||||
if ($1 in targets) targets[$1] = "DUPLICATE:" targets[$1] "+" configuration_list_owner
|
||||
else targets[$1] = configuration_list_owner
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
# Pass 3 emits one row for each team-bearing build configuration.
|
||||
!in_build_configuration && /\/\* (Debug|Release|Profile) \*\/ = \{/ {
|
||||
in_build_configuration = 1
|
||||
configuration_id = $1
|
||||
configuration = $3
|
||||
base_configuration = "NONE"
|
||||
team = ""
|
||||
entitlements = "NONE"
|
||||
depth = 0
|
||||
}
|
||||
|
||||
in_build_configuration {
|
||||
if (/baseConfigurationReference =/) {
|
||||
base_configuration = $3 in xcconfig_paths ? xcconfig_paths[$3] : "UNRESOLVED:" $3
|
||||
}
|
||||
if (/DEVELOPMENT_TEAM =/) {
|
||||
team = $0
|
||||
sub(/^.*= */, "", team)
|
||||
sub(/;.*/, "", team)
|
||||
}
|
||||
if (/CODE_SIGN_ENTITLEMENTS =/) {
|
||||
entitlements = $0
|
||||
sub(/^.*= */, "", entitlements)
|
||||
sub(/;.*/, "", entitlements)
|
||||
}
|
||||
|
||||
depth += gsub(/\{/, "{") - gsub(/\}/, "}")
|
||||
if (depth == 0) {
|
||||
if (team != "") {
|
||||
target_name = configuration_id in targets ? targets[configuration_id] : "UNMAPPED:" configuration_id
|
||||
print target_name, configuration, base_configuration, team, entitlements
|
||||
}
|
||||
in_build_configuration = 0
|
||||
}
|
||||
}
|
||||
' "$pbxproj" "$pbxproj" "$pbxproj" | sort)
|
||||
expected_signing_map=$(printf '%s\n' \
|
||||
'NotificationService Debug Flutter/Debug.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" NotificationService/NotificationService.entitlements' \
|
||||
'NotificationService Profile Flutter/Release.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" NotificationService/NotificationService.entitlements' \
|
||||
'NotificationService Release Flutter/Release.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" NotificationService/NotificationService.entitlements' \
|
||||
'Runner Debug Flutter/Debug.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" Runner/Runner.entitlements' \
|
||||
'Runner Profile Flutter/Release.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" Runner/Runner.entitlements' \
|
||||
'Runner Release Flutter/Release.xcconfig "$(BUZZ_DEVELOPMENT_TEAM)" Runner/Runner.entitlements')
|
||||
if [[ "$signing_map" == "$expected_signing_map" ]]; then
|
||||
pass "Runner and NotificationService signing settings match each build configuration"
|
||||
else
|
||||
fail "unexpected iOS signing map: $signing_map"
|
||||
fi
|
||||
grep -q '<string>$(APP_DISPLAY_NAME)</string>' "$plist" \
|
||||
&& pass "Info.plist display name resolves from build settings" \
|
||||
|| fail "Info.plist CFBundleDisplayName must be \$(APP_DISPLAY_NAME)"
|
||||
|
||||
Reference in New Issue
Block a user