Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 0910a89

Browse files
authored
Add simulator build
1 parent aef1e69 commit 0910a89

2 files changed

Lines changed: 294 additions & 0 deletions

File tree

.github/workflows/build-unsigned-ipa.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
- 'app-repo.json'
1010
- 'gallery/**'
1111
- 'website/**'
12+
- '.github/**'
1213

1314
permissions:
1415
contents: write
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
name: ProStore iOS Simulator Build
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
contents: write
8+
9+
jobs:
10+
build:
11+
runs-on: macos-15
12+
strategy:
13+
matrix:
14+
target: [device, simulator]
15+
16+
steps:
17+
- name: Checkout Repo
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
persist-credentials: true
22+
23+
- name: Show Xcode Version
24+
run: |
25+
echo "=== xcodebuild -version ==="
26+
xcodebuild -version || true
27+
echo "=== sw_vers ==="
28+
sw_vers || true
29+
30+
- name: Install Build Tools
31+
run: |
32+
# jq
33+
if ! command -v jq >/dev/null 2>&1; then
34+
echo "jq not found — attempting to install via brew"
35+
if command -v brew >/dev/null 2>&1; then
36+
brew install jq || true
37+
fi
38+
fi
39+
40+
# yq
41+
if ! command -v yq >/dev/null 2>&1; then
42+
echo "yq not found — attempting to install via brew"
43+
if command -v brew >/dev/null 2>&1; then
44+
brew install yq || true
45+
fi
46+
fi
47+
48+
# gh (GitHub CLI)
49+
if ! command -v gh >/dev/null 2>&1; then
50+
echo "gh not found — attempting to install via brew"
51+
if command -v brew >/dev/null 2>&1; then
52+
brew install gh || true
53+
fi
54+
fi
55+
56+
# xcodegen
57+
if ! command -v xcodegen >/dev/null 2>&1; then
58+
echo "xcodegen not found — attempting to install via brew"
59+
if command -v brew >/dev/null 2>&1; then
60+
brew install xcodegen || true
61+
fi
62+
fi
63+
64+
# Fallback: official gh installer script (works across platforms)
65+
if ! command -v gh >/dev/null 2>&1; then
66+
echo "gh still not found — attempting official installer script"
67+
curl -fsSL https://cli.github.com/install.sh | sh || true
68+
fi
69+
70+
echo "Tool versions (if installed):"
71+
echo "jq: $(jq --version 2>/dev/null || echo 'not installed')"
72+
echo "yq: $(yq --version 2>/dev/null || echo 'not installed')"
73+
echo "gh: $(gh --version 2>/dev/null || echo 'not installed')"
74+
echo "xcodegen: $(xcodegen --version 2>/dev/null || echo 'not installed')"
75+
shell: bash
76+
77+
- name: Check Project Files
78+
run: |
79+
echo "Workspace files:"
80+
ls -la || true
81+
echo "project.yml (first 200 lines):"
82+
sed -n '1,200p' project.yml || true
83+
84+
- name: Generate Xcode Project
85+
run: |
86+
set -e
87+
xcodegen generate --spec project.yml
88+
echo "Generated project at: $(pwd)/prostore.xcodeproj"
89+
echo "project.pbxproj header (first 60 lines):"
90+
sed -n '1,60p' prostore.xcodeproj/project.pbxproj || true
91+
92+
- name: Resolve Swift Packages
93+
run: |
94+
set -e
95+
echo "Resolving Swift package dependencies for prostore..."
96+
xcodebuild -resolvePackageDependencies -project prostore.xcodeproj -scheme prostore -configuration Release
97+
98+
# ===== DEVICE build branch (matrix.target == device) =====
99+
- name: Build Device (archive + package unsigned .ipa)
100+
if: matrix.target == 'device'
101+
id: build_device
102+
run: |
103+
set -e
104+
ARCHIVE_PATH="$PWD/build/prostore.xcarchive"
105+
mkdir -p build
106+
107+
# Try to read cached objectVersion from file
108+
CACHE_FILE=".object_version_cache"
109+
CACHED_VERSION=""
110+
candidates=(77 70 63 60 56 55)
111+
112+
if [ -f "$CACHE_FILE" ]; then
113+
CACHED_VERSION=$(cat "$CACHE_FILE" | tr -d '\n')
114+
echo "Found cached objectVersion: $CACHED_VERSION"
115+
116+
# Test the cached version first
117+
echo "----- Testing cached objectVersion = $CACHED_VERSION -----"
118+
/usr/bin/perl -0777 -pe "s/objectVersion = \\d+;/objectVersion = $CACHED_VERSION;/" -i.bak prostore.xcodeproj/project.pbxproj || true
119+
120+
set +e
121+
xcodebuild clean archive \
122+
-project prostore.xcodeproj \
123+
-scheme prostore \
124+
-archivePath "$ARCHIVE_PATH" \
125+
-sdk iphoneos \
126+
-configuration Release \
127+
CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO
128+
rc=$?
129+
set -e
130+
131+
if [ $rc -eq 0 ]; then
132+
echo "✅ Cached objectVersion $CACHED_VERSION works!"
133+
echo "object_version=$CACHED_VERSION" >> $GITHUB_OUTPUT
134+
echo "$CACHED_VERSION" > "$CACHE_FILE"
135+
else
136+
echo "❌ Cached objectVersion $CACHED_VERSION failed, trying other candidates..."
137+
fi
138+
fi
139+
140+
# If no cache or cached version failed, try all candidates
141+
if [ -z "$CACHED_VERSION" ] || [ ! -f "$ARCHIVE_PATH" ]; then
142+
build_ok=0
143+
for v in "${candidates[@]}"; do
144+
echo "----- Attempting build with objectVersion = $v -----"
145+
/usr/bin/perl -0777 -pe "s/objectVersion = \\d+;/objectVersion = $v;/" -i.bak prostore.xcodeproj/project.pbxproj || true
146+
echo "Applied objectVersion $v. Header preview:"
147+
sed -n '1,20p' prostore.xcodeproj/project.pbxproj || true
148+
echo "Running xcodebuild archive..."
149+
set +e
150+
xcodebuild clean archive \
151+
-project prostore.xcodeproj \
152+
-scheme prostore \
153+
-archivePath "$ARCHIVE_PATH" \
154+
-sdk iphoneos \
155+
-configuration Release \
156+
CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO
157+
rc=$?
158+
set -e
159+
if [ $rc -eq 0 ]; then
160+
echo "✅ xcodebuild succeeded with objectVersion = $v"
161+
echo "object_version=$v" >> $GITHUB_OUTPUT
162+
echo "$v" > "$CACHE_FILE"
163+
echo "Cached successful objectVersion: $v"
164+
build_ok=1
165+
break
166+
else
167+
echo "❌ xcodebuild failed (exit $rc). Trying next objectVersion..."
168+
fi
169+
done
170+
171+
if [ "${build_ok:-0}" -ne 1 ] && [ ! -d "$ARCHIVE_PATH" ]; then
172+
echo "ERROR: All objectVersion attempts failed. Dumping debug info:"
173+
echo "===== project.pbxproj header ====="
174+
sed -n '1,200p' prostore.xcodeproj/project.pbxproj || true
175+
echo "===== build directory listing ====="
176+
ls -la build || true
177+
exit 74
178+
fi
179+
fi
180+
181+
# Package Device .ipa (unsigned)
182+
APP_PATH="$ARCHIVE_PATH/Products/Applications/prostore.app"
183+
OUTPUT_IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
184+
echo "Device app path: $APP_PATH"
185+
if [ ! -d "$APP_PATH" ]; then
186+
echo "ERROR: App not found at expected path. Attempting fallback packaging from archive contents..."
187+
ls -la "$ARCHIVE_PATH" || true
188+
# attempt to find .app anywhere in archive
189+
FOUND_APP=$(find "$ARCHIVE_PATH" -name "*.app" -type d | head -n1 || true)
190+
if [ -n "$FOUND_APP" ]; then
191+
APP_PATH="$FOUND_APP"
192+
else
193+
echo "No .app found — failing device package step."
194+
exit 1
195+
fi
196+
fi
197+
198+
mkdir -p build/Payload
199+
rm -rf build/Payload/* || true
200+
cp -R "$APP_PATH" build/Payload/
201+
(cd build && zip -r "$(basename "$OUTPUT_IPA")" Payload) || exit 1
202+
echo "Created device ipa: $OUTPUT_IPA"
203+
ls -la "$OUTPUT_IPA" || true
204+
205+
- name: Set device artifact path output
206+
if: matrix.target == 'device'
207+
id: set_device_art
208+
run: |
209+
IPA="build/com.prostoreios.prostore-unsigned-ios.ipa"
210+
if [ -f "$IPA" ]; then
211+
echo "ipa_path=$IPA" >> $GITHUB_OUTPUT
212+
else
213+
echo "ipa_path=" >> $GITHUB_OUTPUT
214+
fi
215+
216+
- name: Upload Device IPA artifact
217+
if: matrix.target == 'device' && steps.set_device_art.outputs.ipa_path != ''
218+
uses: actions/upload-artifact@v4
219+
with:
220+
name: com.prostoreios.prostore-unsigned-ios.ipa
221+
path: ${{ steps.set_device_art.outputs.ipa_path }}
222+
223+
# ===== SIMULATOR build branch (matrix.target == simulator) =====
224+
- name: Build simulator (iphonesimulator) and package simulator .ipa (if possible)
225+
if: matrix.target == 'simulator'
226+
id: build_sim
227+
run: |
228+
set -e
229+
echo "Starting simulator build (won't fail the entire job if it fails)."
230+
SIM_DERIVED="$PWD/build/sim_derived"
231+
rm -rf "$SIM_DERIVED"
232+
set +e
233+
xcodebuild clean build \
234+
-project prostore.xcodeproj \
235+
-scheme prostore \
236+
-configuration Release \
237+
-sdk iphonesimulator \
238+
-derivedDataPath "$SIM_DERIVED" \
239+
CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY=""
240+
rc=$?
241+
set -e
242+
if [ $rc -ne 0 ]; then
243+
echo "Warning: simulator build failed (exit $rc). Will attempt to recover packaging if a simulator .app exists."
244+
fi
245+
246+
POSSIBLE_APPS=(
247+
"$SIM_DERIVED/Build/Products/Release-iphonesimulator/prostore.app"
248+
"$SIM_DERIVED/Build/Products/Debug-iphonesimulator/prostore.app"
249+
"$PWD/build/Build/Products/Release-iphonesimulator/prostore.app"
250+
"$PWD/build/Release-iphonesimulator/prostore.app"
251+
)
252+
253+
FOUND_APP=""
254+
for p in "${POSSIBLE_APPS[@]}"; do
255+
if [ -d "$p" ]; then
256+
FOUND_APP="$p"
257+
break
258+
fi
259+
done
260+
261+
if [ -z "$FOUND_APP" ]; then
262+
echo "Simulator .app not found in expected locations. Listing $SIM_DERIVED contents for debug:"
263+
ls -la "$SIM_DERIVED" || true
264+
echo "Skipping simulator .ipa packaging."
265+
exit 0
266+
fi
267+
268+
echo "Found simulator .app at: $FOUND_APP"
269+
SIM_IPA="build/com.prostoreios.prostore-unsigned-iossimulator.ipa"
270+
mkdir -p build/Payload-sim
271+
rm -rf build/Payload-sim/* || true
272+
cp -R "$FOUND_APP" build/Payload-sim/
273+
(cd build && zip -r "$(basename "$SIM_IPA")" Payload-sim) || exit 1
274+
echo "Created simulator ipa: $SIM_IPA"
275+
ls -la "$SIM_IPA" || true
276+
277+
- name: Set simulator artifact path output
278+
if: matrix.target == 'simulator'
279+
id: set_sim_art
280+
run: |
281+
IPA="build/com.prostoreios.prostore-unsigned-iossimulator.ipa"
282+
if [ -f "$IPA" ]; then
283+
echo "ipa_path=$IPA" >> $GITHUB_OUTPUT
284+
else
285+
echo "ipa_path=" >> $GITHUB_OUTPUT
286+
fi
287+
288+
- name: Upload Simulator IPA artifact
289+
if: matrix.target == 'simulator' && steps.set_sim_art.outputs.ipa_path != ''
290+
uses: actions/upload-artifact@v4
291+
with:
292+
name: com.prostoreios.prostore-unsigned-iossimulator.ipa
293+
path: ${{ steps.set_sim_art.outputs.ipa_path }}

0 commit comments

Comments
 (0)