Skip to content

Commit d0fdc49

Browse files
Use fastlane to build and distribute iOS app
1 parent 72771ec commit d0fdc49

File tree

6 files changed

+91
-128
lines changed

6 files changed

+91
-128
lines changed

.github/workflows/ci.yaml

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -160,33 +160,10 @@ jobs:
160160
run: |
161161
API_KEY_PATH=$RUNNER_TEMP/AuthKey_${IOS_API_KEY_ID}.p8
162162
echo -n "$IOS_API_KEY_BASE64" | base64 --decode -o $API_KEY_PATH
163-
- run: make react-native-set-CFBundleVersion
164-
- name: Run xcodebuild archive
165-
run: |
166-
export REACT_NATIVE_ARCHIVE_PATH="$RUNNER_TEMP/reactNativeExample.xcarchive"
167-
make react-native-archive
168-
- name: Run xcodebuild -exportArchive
169-
run: |
170-
export REACT_NATIVE_ARCHIVE_PATH="$RUNNER_TEMP/reactNativeExample.xcarchive"
171-
export REACT_NATIVE_EXPORT_PATH="$RUNNER_TEMP/reactNativeExample.export"
172-
make react-native-export-archive
173-
- name: Validate .ipa
174-
env:
175-
API_ISSUER: ${{ secrets.IOS_API_KEY_ISSUER }}
176-
API_KEY: ${{ secrets.IOS_API_KEY_ID }}
177-
run: |
178-
export API_PRIVATE_KEYS_DIR="$RUNNER_TEMP"
179-
export IPA_PATH="$RUNNER_TEMP/reactNativeExample.export/reactNativeExample.ipa"
180-
make validate-app
163+
- run: make react-native-build-ios-app
181164
- name: Upload to TestFlight
182-
if: ${{ github.ref == 'refs/heads/master' }}
183-
env:
184-
API_ISSUER: ${{ secrets.IOS_API_KEY_ISSUER }}
185-
API_KEY: ${{ secrets.IOS_API_KEY_ID }}
186-
run: |
187-
export API_PRIVATE_KEYS_DIR="$RUNNER_TEMP"
188-
export IPA_PATH="$RUNNER_TEMP/reactNativeExample.export/reactNativeExample.ipa"
189-
make upload-app
165+
if: ${{ github.ref == 'refs/heads/main' }}
166+
run: make react-native-upload-ios-app
190167
- name: Clean up keychain and provisioning profile
191168
if: ${{ always() }}
192169
run: |
@@ -278,33 +255,10 @@ jobs:
278255
run: |
279256
API_KEY_PATH=$RUNNER_TEMP/AuthKey_${IOS_API_KEY_ID}.p8
280257
echo -n "$IOS_API_KEY_BASE64" | base64 --decode -o $API_KEY_PATH
281-
- run: make capacitor-set-CFBundleVersion
282-
- name: Run xcodebuild archive
283-
run: |
284-
export CAPACITOR_ARCHIVE_PATH="$RUNNER_TEMP/App.xcarchive"
285-
make capacitor-archive
286-
- name: Run xcodebuild -exportArchive
287-
run: |
288-
export CAPACITOR_ARCHIVE_PATH="$RUNNER_TEMP/App.xcarchive"
289-
export CAPACITOR_EXPORT_PATH="$RUNNER_TEMP/App.export"
290-
make capacitor-exportArchive
291-
- name: Validate .ipa
292-
env:
293-
API_ISSUER: ${{ secrets.IOS_API_KEY_ISSUER }}
294-
API_KEY: ${{ secrets.IOS_API_KEY_ID }}
295-
run: |
296-
export API_PRIVATE_KEYS_DIR="$RUNNER_TEMP"
297-
export IPA_PATH="$RUNNER_TEMP/App.export/App.ipa"
298-
make validate-app
258+
- run: make capacitor-build-ios-app
299259
- name: Upload to TestFlight
300-
if: ${{ github.ref == 'refs/heads/master' }}
301-
env:
302-
API_ISSUER: ${{ secrets.IOS_API_KEY_ISSUER }}
303-
API_KEY: ${{ secrets.IOS_API_KEY_ID }}
304-
run: |
305-
export API_PRIVATE_KEYS_DIR="$RUNNER_TEMP"
306-
export IPA_PATH="$RUNNER_TEMP/App.export/App.ipa"
307-
make upload-app
260+
if: ${{ github.ref == 'refs/heads/main' }}
261+
run: make capacitor-upload-ios-app
308262
- name: Clean up keychain and provisioning profile
309263
if: ${{ always() }}
310264
run: |

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,11 @@ xcuserdata/
1515
xcshareddata/
1616
temp/
1717

18+
build/
19+
1820
# Ruby
1921
vendor/bundle/
22+
23+
# fastlane
24+
/fastlane/README.md
25+
/fastlane/report.xml

Makefile

Lines changed: 29 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@ REF := $(shell git describe --all --exact-match | sed -e "s|^heads/||")
22
GIT_HASH ?= git-$(shell git rev-parse --short=12 HEAD)
33
IMAGE ?= quay.io/theauthgear/authgear-demo-webapp:$(GIT_HASH)
44

5-
API_ISSUER ?= invalid
6-
API_KEY ?= invalid
7-
8-
REACT_NATIVE_ARCHIVE_PATH ?= ./build/Release/iOS/reactNativeExample.xcarchive
9-
REACT_NATIVE_EXPORT_PATH ?= ./build/Release/iOS/reactNativeExample.export
10-
11-
CAPACITOR_ARCHIVE_PATH ?= ./build/Release/iOS/App/App.xcarchive
12-
CAPACITOR_EXPORT_PATH ?= ./build/Release/iOS/App/App.export
5+
API_ISSUER ?= "invalid"
6+
API_KEY ?= "invalid"
7+
API_KEY_PATH ?= ./AuthKey_invalid.p8
138

149
# The documentation build pipeline works in the following way.
1510
#
@@ -77,8 +72,16 @@ push-image:
7772

7873
.PHONY: clean
7974
clean:
80-
rm -rf ./example/reactnative/ios/build
81-
rm -rf ./example/capacitor/ios/App/App/build
75+
rm -rf ./build
76+
77+
.PHONY: fastlane-api-key-json
78+
fastlane-api-key-json:
79+
mkdir -p ./build
80+
jq --slurp --raw-input > ./build/fastlane-api-key.json \
81+
--arg key_id $(API_KEY) \
82+
--arg issuer_id $(API_ISSUER) \
83+
'{key_id: $$key_id, issuer_id: $$issuer_id, key: .}' \
84+
$(API_KEY_PATH)
8285

8386
.PHONY: sdk-build
8487
sdk-build:
@@ -122,27 +125,13 @@ react-native-bundle-install:
122125
react-native-pod-install:
123126
cd ./example/reactnative/ios; bundle exec pod install
124127

125-
.PHONY: react-native-set-CFBundleVersion
126-
react-native-set-CFBundleVersion:
127-
/usr/libexec/Plistbuddy -c "Set CFBundleVersion $(shell date +%s)" ./example/reactnative/ios/reactNativeExample/Info.plist
128-
129-
.PHONY: react-native-archive
130-
react-native-archive:
131-
cd ./example/reactnative/ios; \
132-
xcodebuild archive \
133-
-destination "generic/platform=iOS" \
134-
-workspace reactNativeExample.xcworkspace \
135-
-scheme reactNativeExample \
136-
-configuration Release \
137-
-archivePath $(REACT_NATIVE_ARCHIVE_PATH)
138-
139-
.PHONY: react-native-export-archive
140-
react-native-export-archive:
141-
cd ./example/reactnative/ios; \
142-
xcodebuild -exportArchive \
143-
-archivePath $(REACT_NATIVE_ARCHIVE_PATH) \
144-
-exportPath $(REACT_NATIVE_EXPORT_PATH) \
145-
-exportOptionsPlist ./ExportOptions.plist
128+
.PHONY: react-native-build-ios-app
129+
react-native-build-ios-app:
130+
bundle exec fastlane react_native_build_ios_app CURRENT_PROJECT_VERSION:$(shell date +%s)
131+
132+
.PHONY: react-native-upload-ios-app
133+
react-native-upload-ios-app:
134+
bundle exec fastlane upload_ios_app ipa:./build/Release/iOS/reactNativeExample/reactNativeExample.ipa
146135

147136
.PHONY: capacitor-npm-ci
148137
capacitor-npm-ci:
@@ -163,33 +152,15 @@ capacitor-build-js:
163152

164153
.PHONY: capacitor-build-ios-simulator
165154
capacitor-build-ios-simulator:
166-
cd ./example/capacitor/ios/App; \
167-
xcodebuild build \
168-
-destination "generic/platform=iOS Simulator" \
169-
-workspace App.xcworkspace \
170-
-scheme App
171-
172-
.PHONY: capacitor-set-CFBundleVersion
173-
capacitor-set-CFBundleVersion:
174-
/usr/libexec/Plistbuddy -c "Set CFBundleVersion $(shell date +%s)" ./example/capacitor/ios/App/App/Info.plist
175-
176-
.PHONY: capacitor-archive
177-
capacitor-archive:
178-
cd ./example/capacitor/ios/App; \
179-
xcodebuild archive \
180-
-destination "generic/platform=iOS" \
181-
-workspace App.xcworkspace \
182-
-scheme App \
183-
-configuration Release \
184-
-archivePath $(CAPACITOR_ARCHIVE_PATH)
185-
186-
.PHONY: capacitor-exportArchive
187-
capacitor-exportArchive:
188-
cd ./example/capacitor/ios/App; \
189-
xcodebuild -exportArchive \
190-
-archivePath $(CAPACITOR_ARCHIVE_PATH) \
191-
-exportPath $(CAPACITOR_EXPORT_PATH) \
192-
-exportOptionsPlist ./ExportOptions.plist
155+
bundle exec fastlane capacitor_build_ios_simulator
156+
157+
.PHONY: capacitor-build-ios-app
158+
capacitor-build-ios-app:
159+
bundle exec fastlane capacitor_build_ios_app CURRENT_PROJECT_VERSION:$(shell date +%s)
160+
161+
.PHONY: capacitor-upload-ios-app
162+
capacitor-upload-ios-app:
163+
bundle exec fastlane upload_ios_app ipa:./build/Release/iOS/capacitor/capacitor.ipa
193164

194165
.PHONY: capacitor-build-unsigned-apk
195166
capacitor-build-unsigned-apk:
@@ -213,19 +184,3 @@ capacitor-apksigner:
213184
--key-pass pass:$(ANDROID_KEY_PASSWORD) \
214185
--out ./example/capacitor/android/app/build/outputs/apk/release/app-release-signed.apk \
215186
./example/capacitor/android/app/build/outputs/apk/release/app-release-unsigned.apk
216-
217-
.PHONY: validate-app
218-
validate-app:
219-
xcrun altool --validate-app \
220-
--file $(IPA_PATH) \
221-
--type ios \
222-
--apiKey $(API_KEY) \
223-
--apiIssuer $(API_ISSUER)
224-
225-
.PHONY: upload-app
226-
upload-app:
227-
xcrun altool --upload-app \
228-
--file $(IPA_PATH) \
229-
--type ios \
230-
--apiKey $(API_KEY) \
231-
--apiIssuer $(API_ISSUER)

example/capacitor/ios/App/ExportOptions.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<plist version="1.0">
44
<dict>
55
<key>method</key>
6-
<string>app-store-connect</string>
6+
<string>app-store</string>
77
<key>provisioningProfiles</key>
88
<dict>
99
<key>com.authgear.sdk.exampleapp.capacitor</key>

example/reactnative/ios/ExportOptions.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<plist version="1.0">
44
<dict>
55
<key>method</key>
6-
<string>app-store-connect</string>
6+
<string>app-store</string>
77
<key>provisioningProfiles</key>
88
<dict>
99
<key>com.authgear.sdk.exampleapp.reactnative</key>

fastlane/Fastfile

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
default_platform(:ios)
2+
3+
platform :ios do
4+
lane :react_native_build_ios_app do |options|
5+
build_app(
6+
destination: "generic/platform=iOS",
7+
workspace: "./example/reactnative/ios/reactNativeExample.xcworkspace",
8+
scheme: "reactNativeExample",
9+
configuration: "Release",
10+
export_options: "./example/reactnative/ios/ExportOptions.plist",
11+
clean: true,
12+
output_directory: "./build/Release/iOS/reactNativeExample",
13+
output_name: "reactNativeExample.ipa",
14+
xcargs: "CURRENT_PROJECT_VERSION=#{options[:CURRENT_PROJECT_VERSION]}",
15+
)
16+
end
17+
18+
lane :capacitor_build_ios_simulator do
19+
xcodebuild(
20+
build: true,
21+
destination: "generic/platform=iOS Simulator",
22+
workspace: "./example/capacitor/ios/App/App.xcworkspace",
23+
scheme: "App",
24+
)
25+
end
26+
27+
lane :capacitor_build_ios_app do |options|
28+
build_app(
29+
destination: "generic/platform=iOS",
30+
workspace: "./example/capacitor/ios/App/App.xcworkspace",
31+
scheme: "App",
32+
configuration: "Release",
33+
export_options: "./example/capacitor/ios/App/ExportOptions.plist",
34+
clean: true,
35+
output_directory: "./build/Release/iOS/capacitor",
36+
output_name: "capacitor.ipa",
37+
xcargs: "CURRENT_PROJECT_VERSION=#{options[:CURRENT_PROJECT_VERSION]}",
38+
)
39+
end
40+
41+
lane :upload_ios_app do |options|
42+
upload_to_testflight(
43+
skip_waiting_for_build_processing: true,
44+
api_key_path: "./build/fastlane-api-key.json",
45+
ipa: options[:ipa],
46+
)
47+
end
48+
end

0 commit comments

Comments
 (0)