Keep internal TestFlight off external beta review
Some checks failed
Build Rust / Cargo Test (push) Successful in 4m2s
Build Site / Next.js Build (push) Failing after 4s
Lint Governance / BEP Metadata (push) Successful in 1s

This commit is contained in:
Conrad Kramer 2026-06-07 20:34:59 -07:00
parent 0924e40463
commit ff4896a901
6 changed files with 40 additions and 10 deletions

View file

@ -478,7 +478,6 @@ jobs:
BUILD_NUMBER: ${{ needs.prepare.outputs.build_number }}
TESTFLIGHT_DISTRIBUTE_EXTERNAL: ${{ github.event.inputs.testflight_distribute_external || 'false' }}
TESTFLIGHT_GROUPS: ${{ github.event.inputs.testflight_groups || '' }}
TESTFLIGHT_INTERNAL_GROUP: Internal
IOS_USES_NON_EXEMPT_ENCRYPTION: ${{ github.event.inputs.ios_uses_non_exempt_encryption || 'false' }}
run: Scripts/ci/distribute-testflight.sh

View file

@ -67,6 +67,5 @@ jobs:
BUILD_NUMBER: ${{ inputs.build_number }}
TESTFLIGHT_DISTRIBUTE_EXTERNAL: ${{ inputs.testflight_distribute_external || 'false' }}
TESTFLIGHT_GROUPS: ${{ inputs.testflight_groups || '' }}
TESTFLIGHT_INTERNAL_GROUP: Internal
IOS_USES_NON_EXEMPT_ENCRYPTION: ${{ inputs.ios_uses_non_exempt_encryption || 'false' }}
run: Scripts/ci/distribute-testflight.sh

View file

@ -262,7 +262,6 @@ jobs:
BUILD_NUMBER: ${{ inputs.build_number }}
TESTFLIGHT_DISTRIBUTE_EXTERNAL: ${{ inputs.testflight_distribute_external || 'false' }}
TESTFLIGHT_GROUPS: ${{ inputs.testflight_groups || '' }}
TESTFLIGHT_INTERNAL_GROUP: Internal
IOS_USES_NON_EXEMPT_ENCRYPTION: ${{ inputs.ios_uses_non_exempt_encryption || 'false' }}
run: Scripts/ci/distribute-testflight.sh
@ -300,7 +299,6 @@ jobs:
BUILD_NUMBER: ${{ inputs.build_number }}
TESTFLIGHT_DISTRIBUTE_EXTERNAL: ${{ inputs.testflight_distribute_external || 'false' }}
TESTFLIGHT_GROUPS: ${{ inputs.testflight_groups || '' }}
TESTFLIGHT_INTERNAL_GROUP: Internal
IOS_USES_NON_EXEMPT_ENCRYPTION: ${{ inputs.ios_uses_non_exempt_encryption || 'false' }}
run: Scripts/ci/distribute-testflight.sh

View file

@ -6,16 +6,31 @@ Scripts/ci/check-release-config.sh app-store
build_number="${BUILD_NUMBER:?BUILD_NUMBER is required}"
distribute_external="${TESTFLIGHT_DISTRIBUTE_EXTERNAL:-false}"
testflight_groups="${TESTFLIGHT_GROUPS:-}"
testflight_internal_group="${TESTFLIGHT_INTERNAL_GROUP:-Internal}"
uses_non_exempt="${IOS_USES_NON_EXEMPT_ENCRYPTION:-false}"
wait_processing_timeout="${TESTFLIGHT_WAIT_PROCESSING_TIMEOUT_SECONDS:-7200}"
if [[ -z "$distribute_external" ]]; then
distribute_external="false"
fi
case "$distribute_external" in
true|false)
;;
*)
echo "::error ::TESTFLIGHT_DISTRIBUTE_EXTERNAL must be true or false." >&2
exit 1
;;
esac
if [[ -z "$uses_non_exempt" ]]; then
uses_non_exempt="false"
fi
case "$uses_non_exempt" in
true|false)
;;
*)
echo "::error ::IOS_USES_NON_EXEMPT_ENCRYPTION must be true or false." >&2
exit 1
;;
esac
case "$wait_processing_timeout" in
""|*[!0-9]*)
echo "::error ::TESTFLIGHT_WAIT_PROCESSING_TIMEOUT_SECONDS must be an integer number of seconds." >&2
@ -51,10 +66,20 @@ args=(
"uses_non_exempt_encryption:${uses_non_exempt}"
)
if [[ -n "$testflight_groups" ]]; then
if [[ "$distribute_external" == "true" ]]; then
if [[ -z "$testflight_groups" ]]; then
echo "::error ::TESTFLIGHT_GROUPS is required for external TestFlight distribution." >&2
exit 1
fi
args+=("groups:${testflight_groups}")
elif [[ "$distribute_external" != "true" && -n "$testflight_internal_group" ]]; then
args+=("groups:${testflight_internal_group}")
else
args+=(
"skip_submission:true"
"notify_external_testers:false"
)
if [[ -n "$testflight_groups" ]]; then
echo "::warning ::Ignoring TESTFLIGHT_GROUPS for internal-only TestFlight distribution; App Store Connect manages internal tester group availability." >&2
fi
fi
nix run nixpkgs#fastlane -- "${args[@]}"

View file

@ -205,6 +205,12 @@ The same change also makes the forge itself the release authority: release tags
upload/signing jobs cannot suppress distribution of an already-uploaded build.
`distribute-testflight` is the narrower one-job retry workflow when only App
Store Connect processing and tester assignment need to be retried.
- Internal TestFlight distribution must not submit the build for external beta
review. The internal lane waits for processing, sets export-compliance
metadata, uses Fastlane `skip_submission:true`, and relies on App Store
Connect's configured internal tester group availability. External TestFlight
distribution requires explicit groups plus beta-review metadata before it can
be enabled.
- Add `infra/releases` as the OpenTofu boundary for the GCS release and package repository backup buckets. Garage is the required S3-compatible primary distribution target after host bootstrap. `infra/identity` remains the boundary for Google KMS signing keys, the Authentik WIF pool/provider, and the runner service account.
- Serve `releases.burrow.net` and `packages.burrow.net` from the forge Caddy
edge as stable Burrow domains backed by the GCS release and package buckets.

View file

@ -14,5 +14,8 @@ Forgejo secrets should only provide the runner age identity fallback, not the
App Store key itself.
The initial release pipeline can upload `.ipa` and `.pkg` artifacts once the
Apple build lane produces signed outputs. TestFlight external distribution must
remain explicit until review metadata, groups, and tester policy are complete.
Apple build lane produces signed outputs. Internal TestFlight distribution waits
for processing and skips external beta-review submission; App Store Connect then
exposes the valid build through the configured internal tester group. TestFlight
external distribution must remain explicit until review metadata, groups, and
tester policy are complete.