Skip to content

Commit 58cc631

Browse files
authored
ci: parallelize xcframework slice builds (#5218)
1 parent 603fec8 commit 58cc631

20 files changed

+711
-369
lines changed

.github/workflows/api-stability.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
- Sentry.xcworkspace/**
1010
- Sentry.xcodeproj/**
1111
- "Package.swift"
12-
- "scripts/build-xcframework.sh"
12+
- "scripts/build-xcframework-local.sh"
1313

1414
jobs:
1515
api-stability:
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: "Assemble Sentry Cocoa XCFramework variant"
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
name:
7+
description: |-
8+
The Sentry project target to build an XCFramework slice for.
9+
Possible values: Sentry, SentrySwiftUI.
10+
required: true
11+
type: string
12+
13+
suffix:
14+
description: |-
15+
The suffix to add to the build product name.
16+
E.g. "-Dynamic" or "-WithoutUIKitOrAppKit".
17+
required: false
18+
type: string
19+
20+
configuration-suffix:
21+
description: |-
22+
The suffix to add to the build product name to build an alternate configuration of the target.
23+
E.g. "WithoutUIKit".
24+
required: false
25+
type: string
26+
27+
variant-id:
28+
description: |-
29+
The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly.
30+
E.g. "sentry-static", "sentry-dynamic" or "sentry-withoutuikit-dynamic"
31+
required: true
32+
type: string
33+
34+
signed:
35+
description: |-
36+
Whether or not the assembled XCFramework should be signed.
37+
required: false
38+
type: boolean
39+
default: false
40+
41+
sdks:
42+
description: |-
43+
The SDK slices to assemble into an XCFramework.
44+
required: false
45+
type: string
46+
default: "iphoneos,iphonesimulator,macosx,maccatalyst,appletvos,appletvsimulator,watchos,watchsimulator,xros,xrsimulator"
47+
48+
jobs:
49+
assemble-xcframework-variant:
50+
name: Assemble ${{inputs.name}}${{inputs.suffix}} XCFramework Variant
51+
52+
runs-on: macos-14
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- uses: ruby/setup-ruby@v1
57+
if: ${{ inputs.signed }}
58+
with:
59+
bundler-cache: true
60+
61+
- name: "Download Fastlane Certificate"
62+
if: ${{ inputs.signed }}
63+
run: bundle exec fastlane prepare_xcframework_signing
64+
env:
65+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
66+
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
67+
APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }}
68+
FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }}
69+
MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }}
70+
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
71+
MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
72+
73+
- name: Download ${{inputs.variant-id}} Slices
74+
uses: actions/download-artifact@v4
75+
with:
76+
pattern: xcframework-${{inputs.variant-id}}-slice-*
77+
path: xcframework-slices
78+
79+
- name: Unzip slice artifact ZIP archives
80+
run: |
81+
find xcframework-slices -type f -print0 | xargs -t0I @ unzip @ -d xcframework-slices
82+
shell: bash
83+
84+
- name: Assemble XCFramework
85+
run: ./scripts/assemble-xcframework.sh "${{inputs.name}}" "${{inputs.suffix}}" "${{inputs.configuration-suffix}}" "${{inputs.sdks}}" "/Users/runner/work/sentry-cocoa/sentry-cocoa/xcframework-slices/SDK_NAME.xcarchive"
86+
shell: bash
87+
88+
- name: Zip XCFramework
89+
run: ./scripts/compress-xcframework.sh ${{inputs.signed && '--sign' || '--not-signed'}} ${{inputs.name}}${{inputs.suffix}}
90+
shell: bash
91+
92+
- name: Upload XCFramework
93+
uses: actions/upload-artifact@v4
94+
with:
95+
overwrite: true
96+
name: xcframework-${{github.sha}}-${{inputs.variant-id}}
97+
if-no-files-found: error
98+
path: ${{inputs.name}}${{inputs.suffix}}.xcframework.zip

.github/workflows/benchmarking.yml

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ on:
1515
- ".sauce/benchmarking-config.yml"
1616
- "fastlane/**"
1717
- "scripts/ci-select-xcode.sh"
18-
- "scripts/build-xcframework.sh"
18+
- "Samples/iOS-Swift/iOS-Swift.yml"
19+
- "Samples/iOS-Swift/iOS-Swift.xcconfig"
20+
- "Samples/iOS-Swift/iOS-SwiftClilp.xcconfig"
21+
- "Samples/iOS-Swift/iOS-Benchmarking.xcconfig"
22+
- "scripts/build-xcframework-slice.sh"
23+
- "scripts/assemble-xcframework.sh"
24+
- ".github/workflows/build-xcframework-variant-slices.yml"
25+
- ".github/workflows/assemble-xcframework-variant.yml"
1926

2027
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
2128
concurrency:
@@ -165,9 +172,27 @@ jobs:
165172
--tags benchmark \
166173
--verbose
167174
175+
build-xcframework-variant-slices:
176+
uses: ./.github/workflows/build-xcframework-variant-slices.yml
177+
with:
178+
name: Sentry
179+
suffix: "-Dynamic"
180+
variant-id: sentry-dynamic
181+
sdk-list: '["iphoneos", "iphonesimulator"]'
182+
183+
assemble-xcframework-variant:
184+
needs: build-xcframework-variant-slices
185+
uses: ./.github/workflows/assemble-xcframework-variant.yml
186+
with:
187+
name: Sentry
188+
suffix: "-Dynamic"
189+
variant-id: sentry-dynamic
190+
sdks: "iphoneos,iphonesimulator"
191+
168192
app-metrics:
169193
name: Collect app metrics
170194
runs-on: macos-15
195+
needs: assemble-xcframework-variant
171196
steps:
172197
- name: Git checkout
173198
uses: actions/checkout@v4
@@ -191,17 +216,11 @@ jobs:
191216
MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }}
192217
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
193218
MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
194-
- name: Build Framework
195-
run: ./scripts/build-xcframework.sh iOSOnly
196-
197-
- name: Archive build log if failed
198-
uses: actions/upload-artifact@v4
199-
if: ${{ failure() || cancelled() }}
219+
- uses: actions/download-artifact@v4
200220
with:
201-
name: raw-build-output-build-xcframework
202-
path: |
203-
build-xcframework.log
204-
221+
pattern: xcframework-${{github.sha}}-sentry-dynamic
222+
path: Carthage/
223+
- run: find Carthage -name "Sentry-Dynamic.xcframework.zip" -print0 | xargs -t0I @ unzip @ -d Carthage
205224
- name: Build test app with sentry
206225
run: bundle exec fastlane build_perf_test_app_sentry
207226
env:
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
name: "Build Sentry Cocoa XCFramework variant slices"
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
sdk-list:
7+
description: |-
8+
The list of Apple platform SDKs for which to build slices and assemble into an XCFramework. This must be a JSON array of strings, itself in a string since GitHub Actions doesn't support arrays as inputs.
9+
Possible values: iphoneos, iphonesimulator, macosx, appletvos, appletvsimulator, watchos, watchsimulator, xros, xrsimulator.
10+
required: false
11+
default: '["iphoneos", "iphonesimulator", "macosx", "maccatalyst", "appletvos", "appletvsimulator", "watchos", "watchsimulator", "xros", "xrsimulator"]'
12+
type: string
13+
14+
name:
15+
description: |-
16+
The Sentry project target to build an XCFramework slice for.
17+
Possible values: Sentry, SentrySwiftUI.
18+
required: true
19+
type: string
20+
21+
suffix:
22+
description: |-
23+
The suffix to add to the build product name.
24+
E.g. "-Dynamic" or "-WithoutUIKitOrAppKit".
25+
required: false
26+
type: string
27+
28+
macho-type:
29+
description: |-
30+
The Mach-O type of the build product.
31+
Possible values: mh_dylib, staticlib.
32+
required: false
33+
type: string
34+
default: "mh_dylib"
35+
36+
configuration-suffix:
37+
description: |-
38+
The suffix to add to the build product name to build an alternate configuration of the target.
39+
E.g. "WithoutUIKit".
40+
required: false
41+
type: string
42+
43+
variant-id:
44+
description: |-
45+
The ID of the variant to build an XCFramework slice for. Used to collect appropriate slices for final deliverable assembly.
46+
required: true
47+
type: string
48+
49+
release-version:
50+
description: |-
51+
For release workflows, the version to inject into the SDK.
52+
required: false
53+
type: string
54+
55+
jobs:
56+
build-xcframework-variant-slices:
57+
name: ${{matrix.sdk}}
58+
59+
# We must compile this on an arm64 runner, cause it's required for visionOS. macos-14 uses arm64.
60+
# To see the available runners see https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories.
61+
runs-on: macos-14
62+
63+
strategy:
64+
matrix:
65+
sdk: ${{ fromJson(inputs.sdk-list) }}
66+
67+
steps:
68+
- uses: actions/checkout@v4
69+
70+
# We have to compile on Xcode 15.2 because compiling on Xcode 15.4 fails with
71+
# Data+SentryTracing.swift:21:62: error: 'ReadingOptions' aliases 'Foundation.ReadingOptions'
72+
# and cannot be used here because C++ types from imported module 'Foundation' do not support
73+
# library evolution; this is an error in the Swift 6 language mode
74+
# We also can't use Xcode 16.x because validating the XCFramework then fails with Xcode 15.x.
75+
- run: ./scripts/ci-select-xcode.sh 15.2
76+
shell: bash
77+
78+
- name: Get version
79+
id: get-version
80+
run: |
81+
if [ -n "${{ inputs.release-version }}" ]; then
82+
echo "VERSION=${{ inputs.release-version }}" >> $GITHUB_ENV
83+
else
84+
echo "VERSION=$(grep MARKETING_VERSION Sources/Configuration/Versioning.xcconfig | cut -d ' ' -f 3)+${{ github.sha }}" >> $GITHUB_ENV
85+
fi
86+
shell: sh
87+
88+
- name: Bump version
89+
run: |
90+
./scripts/ci-select-xcode.sh 15.2
91+
make bump-version TO=${{ env.VERSION }}
92+
93+
- name: Build ${{inputs.name}}${{inputs.suffix}} XCFramework slice for ${{matrix.sdk}}
94+
if: startsWith(github.ref, 'refs/heads/release/') == false
95+
run: ./scripts/build-xcframework-slice.sh ${{matrix.sdk}} ${{inputs.name}} "${{inputs.suffix}}" "${{inputs.macho-type}}" "${{inputs.configuration-suffix}}"
96+
shell: bash
97+
98+
# The SentrySwiftUI archive build also builds Sentry.framework as a byproduct of the dependency. We need to remove that to avoid downstream assembly tasks from tripping on these extra files. In the future we could investigate using this byproduct instead of running a separate task for Sentry.framework, or use the one already built by that other task instead of rebuilding it here.
99+
- name: Remove Sentry.framework from SentrySwiftUI build
100+
if: inputs.name == 'SentrySwiftUI'
101+
run: |
102+
find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework" -print0 | xargs -t0 rm -rf
103+
find "${{github.workspace}}/Carthage/archive" -name "Sentry.framework.dSYM" -print0 | xargs -t0 rm -rf
104+
shell: bash
105+
106+
# the upload action broke symlinks in the mac sdk slice's xcarchive
107+
- name: Zip xcarchive
108+
run: |
109+
ditto -c -k -X --rsrc --keepParent ${{github.workspace}}/Carthage/archive/${{inputs.name}}${{inputs.suffix}}/${{matrix.sdk}}.xcarchive ${{inputs.name}}${{inputs.suffix}}.xcarchive.zip
110+
shell: bash
111+
112+
- name: Upload xcarchive
113+
uses: actions/upload-artifact@v4
114+
with:
115+
name: xcframework-${{inputs.variant-id}}-slice-${{matrix.sdk}}
116+
if-no-files-found: error
117+
path: |
118+
${{inputs.name}}${{inputs.suffix}}.xcarchive.zip
119+
120+
- name: Upload build log if failed
121+
uses: actions/upload-artifact@v4
122+
if: ${{ failure() || cancelled() }}
123+
with:
124+
name: raw-build-output-build-xcframework-${{inputs.variant-id}}-${{matrix.sdk}}
125+
path: |
126+
*.log

0 commit comments

Comments
 (0)