Skip to content

Commit b11c844

Browse files
authored
Merge pull request #124 from rudrankriyam/codex/foundation-lab-testflight
Add automated TestFlight workflow for Foundation Lab
2 parents a0e9e86 + f4c5fea commit b11c844

File tree

5 files changed

+202
-0
lines changed

5 files changed

+202
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>method</key>
6+
<string>app-store-connect</string>
7+
<key>signingStyle</key>
8+
<string>automatic</string>
9+
<key>teamID</key>
10+
<string>__TEAM_ID__</string>
11+
</dict>
12+
</plist>

.asc/workflow.json

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"env": {
3+
"PROJECT_PATH": "FoundationLab.xcodeproj",
4+
"SCHEME": "Foundation Lab",
5+
"CONFIGURATION": "Release",
6+
"EXPORT_OPTIONS_TEMPLATE": ".asc/ExportOptions/TestFlight.plist.template",
7+
"EXPORT_OPTIONS": ".asc/ExportOptions/TestFlight.generated.plist"
8+
},
9+
"before_all": "asc auth status --validate",
10+
"workflows": {
11+
"foundation_lab_testflight": {
12+
"description": "Archive, export, and upload Foundation Lab to the external TestFlight Beta group.",
13+
"steps": [
14+
{
15+
"name": "prepare_artifacts",
16+
"run": "mkdir -p .asc/artifacts .asc/runs"
17+
},
18+
{
19+
"name": "validate_inputs",
20+
"run": "for key in APP_ID TESTFLIGHT_GROUP TARGET_BUNDLE_ID TEAM_ID VERSION; do if [ -z \"${!key}\" ]; then echo \"$key is required\" >&2; exit 1; fi; done"
21+
},
22+
{
23+
"name": "render_export_options",
24+
"run": "sed \"s/__TEAM_ID__/$TEAM_ID/g\" \"$EXPORT_OPTIONS_TEMPLATE\" > \"$EXPORT_OPTIONS\" && plutil -lint \"$EXPORT_OPTIONS\" >/dev/null"
25+
},
26+
{
27+
"name": "resolve_next_build",
28+
"run": "asc builds next-build-number --app \"$APP_ID\" --version \"$VERSION\" --platform IOS --initial-build-number 1 --output json",
29+
"outputs": {
30+
"BUILD_NUMBER": "$.nextBuildNumber"
31+
}
32+
},
33+
{
34+
"name": "archive",
35+
"run": "asc xcode archive --project \"$PROJECT_PATH\" --scheme \"$SCHEME\" --configuration \"$CONFIGURATION\" --archive-path \".asc/artifacts/FoundationLab-$VERSION-${steps.resolve_next_build.BUILD_NUMBER}.xcarchive\" --clean --overwrite --xcodebuild-flag=-destination --xcodebuild-flag=generic/platform=iOS --xcodebuild-flag=-allowProvisioningUpdates --xcodebuild-flag=-authenticationKeyID --xcodebuild-flag=$ASC_KEY_ID --xcodebuild-flag=-authenticationKeyIssuerID --xcodebuild-flag=$ASC_ISSUER_ID --xcodebuild-flag=-authenticationKeyPath --xcodebuild-flag=$ASC_PRIVATE_KEY_PATH --xcodebuild-flag=PRODUCT_BUNDLE_IDENTIFIER=$TARGET_BUNDLE_ID --xcodebuild-flag=DEVELOPMENT_TEAM=$TEAM_ID --xcodebuild-flag=MARKETING_VERSION=$VERSION --xcodebuild-flag=CURRENT_PROJECT_VERSION=${steps.resolve_next_build.BUILD_NUMBER} --output json",
36+
"outputs": {
37+
"ARCHIVE_PATH": "$.archive_path",
38+
"VERSION": "$.version",
39+
"BUILD_NUMBER": "$.build_number"
40+
}
41+
},
42+
{
43+
"name": "export",
44+
"run": "asc xcode export --archive-path \"${steps.archive.ARCHIVE_PATH}\" --export-options \"$EXPORT_OPTIONS\" --ipa-path \".asc/artifacts/FoundationLab-$VERSION-${steps.archive.BUILD_NUMBER}.ipa\" --overwrite --xcodebuild-flag=-allowProvisioningUpdates --xcodebuild-flag=-authenticationKeyID --xcodebuild-flag=$ASC_KEY_ID --xcodebuild-flag=-authenticationKeyIssuerID --xcodebuild-flag=$ASC_ISSUER_ID --xcodebuild-flag=-authenticationKeyPath --xcodebuild-flag=$ASC_PRIVATE_KEY_PATH --output json",
45+
"outputs": {
46+
"IPA_PATH": "$.ipa_path",
47+
"VERSION": "$.version",
48+
"BUILD_NUMBER": "$.build_number"
49+
}
50+
},
51+
{
52+
"name": "publish",
53+
"run": "asc publish testflight --app \"$APP_ID\" --ipa \"${steps.export.IPA_PATH}\" --group \"$TESTFLIGHT_GROUP\" --wait --poll-interval 10s --output json",
54+
"outputs": {
55+
"BUILD_ID": "$.buildId",
56+
"BUILD_NUMBER": "$.buildNumber"
57+
}
58+
}
59+
]
60+
}
61+
}
62+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Foundation Lab TestFlight
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'Foundation Lab/**'
9+
- 'Foundation Lab.icon/**'
10+
- 'FoundationLabCore/**'
11+
- 'FoundationLab.xcodeproj/**'
12+
- 'SampleCode.xcconfig'
13+
- '.asc/**'
14+
- '.github/workflows/foundation-lab-testflight.yml'
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
19+
20+
concurrency:
21+
group: foundation-lab-testflight
22+
cancel-in-progress: false
23+
24+
jobs:
25+
upload:
26+
runs-on: macos-latest
27+
timeout-minutes: 90
28+
env:
29+
ASC_BYPASS_KEYCHAIN: "1"
30+
APP_ID: ${{ vars.FOUNDATION_LAB_APP_ID }}
31+
TESTFLIGHT_GROUP: ${{ vars.FOUNDATION_LAB_EXTERNAL_GROUP_ID }}
32+
TARGET_BUNDLE_ID: ${{ vars.FOUNDATION_LAB_BUNDLE_ID }}
33+
TEAM_ID: ${{ vars.FOUNDATION_LAB_TEAM_ID }}
34+
steps:
35+
- name: Check out repository
36+
uses: actions/checkout@v4
37+
38+
- name: Select Xcode
39+
uses: maxim-lobanov/setup-xcode@v1
40+
with:
41+
xcode-version: latest-stable
42+
43+
- name: Install asc
44+
run: |
45+
HOMEBREW_NO_AUTO_UPDATE=1 brew install asc
46+
asc --version
47+
48+
- name: Validate repository configuration
49+
env:
50+
ASC_KEY_ID_SECRET: ${{ secrets.ASC_KEY_ID }}
51+
ASC_ISSUER_ID_SECRET: ${{ secrets.ASC_ISSUER_ID }}
52+
ASC_PRIVATE_KEY_B64_SECRET: ${{ secrets.ASC_PRIVATE_KEY_B64 }}
53+
run: |
54+
for key in APP_ID TESTFLIGHT_GROUP TARGET_BUNDLE_ID TEAM_ID; do
55+
if [ -z "${!key}" ]; then
56+
echo "Missing required repository variable: $key" >&2
57+
exit 1
58+
fi
59+
done
60+
61+
for key in ASC_KEY_ID_SECRET ASC_ISSUER_ID_SECRET ASC_PRIVATE_KEY_B64_SECRET; do
62+
if [ -z "${!key}" ]; then
63+
echo "Missing required repository secret: ${key%_SECRET}" >&2
64+
exit 1
65+
fi
66+
done
67+
68+
- name: Materialize ASC key
69+
env:
70+
ASC_KEY_ID_SECRET: ${{ secrets.ASC_KEY_ID }}
71+
ASC_ISSUER_ID_SECRET: ${{ secrets.ASC_ISSUER_ID }}
72+
ASC_PRIVATE_KEY_B64_SECRET: ${{ secrets.ASC_PRIVATE_KEY_B64 }}
73+
run: |
74+
KEY_PATH="$RUNNER_TEMP/AuthKey_${ASC_KEY_ID_SECRET}.p8"
75+
printf '%s' "$ASC_PRIVATE_KEY_B64_SECRET" | base64 --decode > "$KEY_PATH"
76+
chmod 600 "$KEY_PATH"
77+
78+
{
79+
echo "ASC_KEY_ID=$ASC_KEY_ID_SECRET"
80+
echo "ASC_ISSUER_ID=$ASC_ISSUER_ID_SECRET"
81+
echo "ASC_PRIVATE_KEY_PATH=$KEY_PATH"
82+
} >> "$GITHUB_ENV"
83+
84+
- name: Resolve marketing version
85+
id: version
86+
run: |
87+
VERSION="$(xcodebuild -showBuildSettings \
88+
-project FoundationLab.xcodeproj \
89+
-scheme 'Foundation Lab' \
90+
-configuration Release \
91+
-destination 'generic/platform=iOS' | awk '/MARKETING_VERSION = / { print $3; exit }')"
92+
93+
if [ -z "$VERSION" ]; then
94+
echo "Failed to resolve MARKETING_VERSION" >&2
95+
exit 1
96+
fi
97+
98+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
99+
100+
- name: Validate ASC workflow
101+
run: asc workflow validate
102+
103+
- name: Dry run ASC workflow
104+
run: asc workflow run --dry-run foundation_lab_testflight VERSION:${{ steps.version.outputs.version }}
105+
106+
- name: Upload to TestFlight external group
107+
run: asc workflow run foundation_lab_testflight VERSION:${{ steps.version.outputs.version }}

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ xcuserdata/
1313
*.dSYM.zip
1414
*.dSYM
1515

16+
.asc/artifacts/
17+
.asc/ExportOptions/TestFlight.generated.plist
18+
.asc/runs/
19+
1620
## Playgrounds
1721
timeline.xctimeline
1822
playground.xcworkspace

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@ It is part of the [Exploring Foundation Models](https://academy.rudrank.com/prod
4747

4848
You can now try Foundation Lab on TestFlight! Join the beta: [https://testflight.apple.com/join/JWR9FpP3](https://testflight.apple.com/join/JWR9FpP3)
4949

50+
## Automated TestFlight uploads
51+
52+
This repo includes a repo-local ASC workflow in `.asc/workflow.json` and a GitHub Actions workflow in `.github/workflows/foundation-lab-testflight.yml` that uploads the iOS app to the external TestFlight Beta group whenever app changes land on `main`.
53+
54+
GitHub Actions expects these repository secrets:
55+
56+
- `ASC_KEY_ID`
57+
- `ASC_ISSUER_ID`
58+
- `ASC_PRIVATE_KEY_B64`
59+
60+
It also expects these repository variables:
61+
62+
- `FOUNDATION_LAB_APP_ID`
63+
- `FOUNDATION_LAB_EXTERNAL_GROUP_ID`
64+
- `FOUNDATION_LAB_BUNDLE_ID`
65+
- `FOUNDATION_LAB_TEAM_ID`
66+
5067
## Getting Started
5168

5269
- Clone the repository

0 commit comments

Comments
 (0)