Skip to content

Commit 136f7ad

Browse files
committed
ci(ios): Add Sentry snapshot upload workflows
Add dedicated GitHub Actions workflows for uploading SnapshotPreviews and Swift Snapshot Testing outputs to Sentry. Remove the old Sentry upload step from the Emerge snapshots workflow so each pipeline has a single responsibility.
1 parent 3166bf3 commit 136f7ad

4 files changed

Lines changed: 289 additions & 5 deletions

File tree

.github/scripts/ios/setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
# Install Ruby Bundler
44
gem install bundler
55

6-
# Install Ruby Gems
6+
# Install Ruby Gems for Fastlane and XCPretty
77
bundle install

.github/workflows/ios_emerge_upload_snapshots.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,3 @@ jobs:
8888
--client-library swift-snapshot-testing \
8989
--project-root . \
9090
--debug
91-
- name: Upload snapshots to Sentry
92-
env:
93-
SENTRY_SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_SENTRY_AUTH_TOKEN }}
94-
run: bundle exec fastlane ios upload_sentry_snapshots
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
name: Sentry Snapshots Upload
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
paths: [ios/**, .github/workflows/ios*, .github/scripts/ios/**]
9+
10+
defaults:
11+
run:
12+
working-directory: ./ios
13+
14+
env:
15+
DERIVED_DATA_PATH: ${{ github.workspace }}/DerivedData-snapshot-upload
16+
SNAPSHOT_UPLOAD_BASE_DIR: ${{ github.workspace }}/ios/snapshot-images
17+
BUILD_PRODUCTS_ARCHIVE: ${{ github.workspace }}/snapshot-build-products.tar.gz
18+
XCTESTRUN_FILENAME: HackerNewsSnapshotTests.xctestrun
19+
20+
jobs:
21+
# Build the snapshot test bundle once on a single runner, then share the
22+
# products with downstream simulator jobs via an artifact.
23+
build_for_testing:
24+
runs-on: macos-26
25+
26+
env:
27+
TEST_RUNNER_XCODE_RUNNING_FOR_PREVIEWS: 1
28+
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v6
32+
with:
33+
fetch-depth: 0
34+
35+
- name: Select Xcode 26.4
36+
run: sudo xcode-select -s /Applications/Xcode_26.4.app
37+
38+
- name: Set up Ruby env
39+
uses: ruby/setup-ruby@v1
40+
with:
41+
ruby-version: 3.3.10
42+
bundler-cache: true
43+
44+
- name: Setup gems
45+
run: exec ../.github/scripts/ios/setup.sh
46+
47+
- name: Prepare DerivedData directory
48+
run: mkdir -p "${DERIVED_DATA_PATH}"
49+
50+
- name: Cache Swift Package Manager
51+
uses: actions/cache@v4
52+
with:
53+
path: |
54+
~/Library/Caches/org.swift.swiftpm
55+
${{ env.DERIVED_DATA_PATH }}/SourcePackages
56+
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
57+
restore-keys: ${{ runner.os }}-spm-
58+
59+
- name: Build snapshot tests for distribution
60+
run: |
61+
set -o pipefail && xcodebuild build-for-testing \
62+
-scheme HackerNews \
63+
-sdk iphonesimulator \
64+
-destination 'platform=iOS Simulator,name=iPhone 17 Pro Max,arch=arm64' \
65+
-only-testing:HackerNewsTests/HackerNewsSnapshotTest \
66+
-resultBundlePath ../SnapshotBuildForTesting.xcresult \
67+
-derivedDataPath "${DERIVED_DATA_PATH}" \
68+
-skipPackagePluginValidation \
69+
ONLY_ACTIVE_ARCH=YES \
70+
TARGETED_DEVICE_FAMILY="1,2" \
71+
SUPPORTS_MACCATALYST=NO \
72+
CODE_SIGNING_ALLOWED=NO \
73+
COMPILATION_CACHING=YES \
74+
EAGER_LINKING=YES \
75+
FUSE_BUILD_SCRIPT_PHASES=YES \
76+
| xcpretty
77+
78+
- name: Normalize xctestrun path
79+
run: |
80+
XCTESTRUN_SOURCE="$(find "${DERIVED_DATA_PATH}/Build/Products" -name '*.xctestrun' -print -quit)"
81+
if [ -z "${XCTESTRUN_SOURCE}" ]; then
82+
echo "No .xctestrun file found under ${DERIVED_DATA_PATH}/Build/Products" >&2
83+
exit 1
84+
fi
85+
86+
cp "${XCTESTRUN_SOURCE}" "${DERIVED_DATA_PATH}/Build/Products/${XCTESTRUN_FILENAME}"
87+
88+
- name: Archive test products
89+
run: tar -C "${DERIVED_DATA_PATH}/Build" -czf "${BUILD_PRODUCTS_ARCHIVE}" Products
90+
91+
- name: Upload build products artifact
92+
uses: actions/upload-artifact@v7
93+
with:
94+
name: snapshot-build-products
95+
path: ${{ env.BUILD_PRODUCTS_ARCHIVE }}
96+
if-no-files-found: error
97+
98+
# One simulator per runner. Each job extracts the shared build products,
99+
# runs the snapshot tests, and uploads its PNGs as a per-sim artifact so
100+
# the final job can aggregate them.
101+
generate_snapshots:
102+
runs-on: macos-26
103+
needs: build_for_testing
104+
105+
strategy:
106+
fail-fast: false
107+
matrix:
108+
include:
109+
- simulator_name: iPhone 17 Pro Max
110+
slug: iphone-17-pro-max
111+
- simulator_name: iPhone 17e
112+
slug: iphone-17e
113+
- simulator_name: iPad Air 11-inch (M4)
114+
slug: ipad-air-11-inch-m4
115+
116+
env:
117+
TEST_RUNNER_XCODE_RUNNING_FOR_PREVIEWS: 1
118+
# Keep this base path in sync with the workflow-level SNAPSHOT_UPLOAD_BASE_DIR.
119+
TEST_RUNNER_SNAPSHOTS_EXPORT_DIR: ${{ github.workspace }}/ios/snapshot-images/${{ matrix.slug }}
120+
121+
steps:
122+
- name: Checkout
123+
uses: actions/checkout@v6
124+
with:
125+
fetch-depth: 0
126+
127+
- name: Select Xcode 26.4
128+
run: sudo xcode-select -s /Applications/Xcode_26.4.app
129+
130+
- name: Set up Ruby env
131+
uses: ruby/setup-ruby@v1
132+
with:
133+
ruby-version: 3.3.10
134+
bundler-cache: true
135+
136+
- name: Setup gems
137+
run: exec ../.github/scripts/ios/setup.sh
138+
139+
- name: Download build products artifact
140+
uses: actions/download-artifact@v5
141+
with:
142+
name: snapshot-build-products
143+
path: ${{ github.workspace }}
144+
145+
- name: Extract test products
146+
run: |
147+
mkdir -p "${DERIVED_DATA_PATH}/Build"
148+
tar -C "${DERIVED_DATA_PATH}/Build" -xzf "${BUILD_PRODUCTS_ARCHIVE}"
149+
150+
- name: Boot simulator
151+
run: xcrun simctl boot "${{ matrix.simulator_name }}" || true
152+
153+
- name: Prepare snapshot export directory
154+
run: mkdir -p "${TEST_RUNNER_SNAPSHOTS_EXPORT_DIR}"
155+
156+
- name: Generate snapshot images
157+
run: |
158+
set -o pipefail && xcodebuild test-without-building \
159+
-xctestrun "${DERIVED_DATA_PATH}/Build/Products/${XCTESTRUN_FILENAME}" \
160+
-destination 'platform=iOS Simulator,name=${{ matrix.simulator_name }},arch=arm64' \
161+
-only-testing:HackerNewsTests/HackerNewsSnapshotTest \
162+
-resultBundlePath "../SnapshotResults-${{ matrix.slug }}.xcresult" \
163+
| xcpretty
164+
165+
- name: Upload snapshots artifacts
166+
uses: actions/upload-artifact@v7
167+
with:
168+
name: snapshots-${{ matrix.slug }}
169+
path: ${{ env.TEST_RUNNER_SNAPSHOTS_EXPORT_DIR }}
170+
if-no-files-found: error
171+
172+
# Aggregate every per-sim artifact and upload the combined set to Sentry
173+
# in a single fastlane invocation.
174+
upload_snapshots:
175+
runs-on: macos-26
176+
needs: generate_snapshots
177+
178+
steps:
179+
- name: Checkout
180+
uses: actions/checkout@v6
181+
with:
182+
fetch-depth: 0
183+
184+
- name: Set up Ruby env
185+
uses: ruby/setup-ruby@v1
186+
with:
187+
ruby-version: 3.3.10
188+
bundler-cache: true
189+
190+
- name: Setup gems
191+
run: exec ../.github/scripts/ios/setup.sh
192+
193+
- name: Download generated snapshots
194+
uses: actions/download-artifact@v5
195+
with:
196+
path: ${{ env.SNAPSHOT_UPLOAD_BASE_DIR }}
197+
pattern: "snapshots-*"
198+
199+
- name: List aggregated snapshot files
200+
run: |
201+
echo "Generated snapshot files:"
202+
find "${SNAPSHOT_UPLOAD_BASE_DIR}" -type f | sort
203+
echo
204+
echo "Total PNG images: $(find "${SNAPSHOT_UPLOAD_BASE_DIR}" -type f -name '*.png' | wc -l | tr -d ' ')"
205+
206+
- name: Upload snapshots to Sentry
207+
env:
208+
SENTRY_SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_SENTRY_AUTH_TOKEN }}
209+
run: bundle exec fastlane ios upload_sentry_snapshots path:"${SNAPSHOT_UPLOAD_BASE_DIR}"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Sentry Snapshots Upload (Swift Snapshot Testing)
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
paths: [ios/**, .github/workflows/ios*, .github/scripts/ios/**]
9+
10+
jobs:
11+
upload_sentry_swift_snapshots:
12+
runs-on: macos-26
13+
14+
defaults:
15+
run:
16+
working-directory: ./ios
17+
18+
env:
19+
TEST_RUNNER_XCODE_RUNNING_FOR_PREVIEWS: 1
20+
# Enables recording mode when running Swift Snapshot Testing tests
21+
TEST_RUNNER_SNAPSHOT_TESTING_RECORD: all
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v6
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Set up Ruby env
30+
uses: ruby/setup-ruby@v1
31+
with:
32+
ruby-version: 3.3.10
33+
bundler-cache: true
34+
35+
- name: Setup gems
36+
run: exec ../.github/scripts/ios/setup.sh
37+
38+
- name: Boot iPhone simulator
39+
run: xcrun simctl boot "iPhone 17 Pro Max" || true
40+
41+
- name: Cache Swift Package Manager
42+
uses: actions/cache@v4
43+
with:
44+
path: |
45+
~/Library/Caches/org.swift.swiftpm
46+
~/Library/Developer/Xcode/DerivedData/HackerNews-*/SourcePackages
47+
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
48+
restore-keys: ${{ runner.os }}-spm-
49+
50+
- name: Generate snapshot images
51+
# continue-on-error is needed because Swift Snapshot Testing treats snapshot recording as test failures
52+
continue-on-error: true
53+
run: |
54+
set -o pipefail && xcodebuild test \
55+
-scheme HackerNews \
56+
-sdk iphonesimulator \
57+
-destination 'platform=iOS Simulator,name=iPhone 17 Pro Max,arch=arm64' \
58+
-only-testing:HackerNewsTests/SwiftSnapshotTest \
59+
-resultBundlePath ../SnapshotResults-swift-snapshots.xcresult \
60+
-skipPackagePluginValidation \
61+
ONLY_ACTIVE_ARCH=YES \
62+
TARGETED_DEVICE_FAMILY=1 \
63+
SUPPORTS_MACCATALYST=NO \
64+
CODE_SIGNING_ALLOWED=NO \
65+
COMPILATION_CACHING=YES \
66+
EAGER_LINKING=YES \
67+
FUSE_BUILD_SCRIPT_PHASES=YES \
68+
| xcpretty
69+
70+
- name: List generated images
71+
run: |
72+
echo "Generated snapshot images:"
73+
ls -1 HackerNewsTests/__Snapshots__/SwiftSnapshotTest/ || echo "No snapshots found"
74+
echo "Total: $(ls -1 HackerNewsTests/__Snapshots__/SwiftSnapshotTest/ 2>/dev/null | wc -l | tr -d ' ') images"
75+
76+
- name: Upload snapshots to Sentry
77+
env:
78+
SENTRY_SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_SENTRY_AUTH_TOKEN }}
79+
run: bundle exec fastlane ios upload_sentry_snapshots_swift_snapshot_testing

0 commit comments

Comments
 (0)