Skip to content

feat: split unsigned IPA into runner and screen streamer#28

Merged
gmegidish merged 3 commits into
mainfrom
feat-split-ipa
Apr 15, 2026
Merged

feat: split unsigned IPA into runner and screen streamer#28
gmegidish merged 3 commits into
mainfrom
feat-split-ipa

Conversation

@gmegidish

Copy link
Copy Markdown
Member

No description provided.

Produce two separate IPAs instead of one combined archive:
- devicekit-ios-runner.ipa (XCUITest runner for device automation)
- devicekit-ios-screenstreamer.ipa (Screen Stream app)

iOS can only install one bundle per IPA, so they must be separate.
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 73c1fb73-1fba-400a-972c-69a28db393cc

📥 Commits

Reviewing files that changed from the base of the PR and between 975e73c and fcb808c.

📒 Files selected for processing (1)
  • Makefile
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile

Walkthrough

CI workflow artifact handling was changed: artifact name devicekit-ios-unsigned-ipadevicekit-ios-ipa; upload/download globs widened from *-unsigned.ipa*.ipa; release job step name updated; provenance attestation and GitHub Release upload subject/file globs changed to *.ipa (simulator *-Sim-*.zip patterns unchanged). Makefile ipa-unsigned target now packages only $(SCHEME)UITests-Runner.app (host $(SCHEME).app removed), invokes scripts/patch-runner.sh with the iPhoneOS build products path only, clears/creates $(EXPORT_PATH)/Payload, removes prior $(SCHEME)-runner.ipa, and outputs $(SCHEME)-runner.ipa with updated log text.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the rationale for splitting the unsigned IPA and how the runner and screen streamer IPAs differ.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: splitting the unsigned IPA artifact handling to distinguish between runner and screen streamer components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-split-ipa

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Makefile`:
- Around line 45-53: Before packaging, remove any stale artifacts: delete
$(EXPORT_PATH)/Payload and existing archive files for the scheme (e.g.
$(EXPORT_PATH)/$(SCHEME)-runner.ipa and
$(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa) to ensure deterministic output,
then recreate Payload with mkdir -p; replace the current sequence around the
Payload/zip steps so you run rm -rf "$(EXPORT_PATH)/Payload" && rm -f
"$(EXPORT_PATH)/$(SCHEME)-runner.ipa" && rm -f
"$(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa" before creating Payload and
copying the .app bundles, and ensure you also remove the temporary Payload after
each zip to avoid leaks between the two packaging steps.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 93b178b4-788d-4ca6-bb2e-fd9d8b6e037c

📥 Commits

Reviewing files that changed from the base of the PR and between 4ebdd76 and 918b38e.

📒 Files selected for processing (2)
  • .github/workflows/build.yml
  • Makefile

Comment thread Makefile Outdated
Comment on lines +45 to +53
@mkdir -p $(EXPORT_PATH)/Payload
@cp -r $(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME).app $(EXPORT_PATH)/Payload/
@cp -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" $(EXPORT_PATH)/Payload/
@scripts/patch-runner.sh "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos" "$(EXPORT_PATH)/Payload"
@cd $(EXPORT_PATH) && zip -r $(SCHEME)-unsigned.ipa Payload
@cd $(EXPORT_PATH) && zip -r $(SCHEME)-runner.ipa Payload
@rm -rf $(EXPORT_PATH)/Payload
@echo "Runner IPA created at: $(EXPORT_PATH)/$(SCHEME)-runner.ipa"
@echo "Packaging screen streamer IPA..."
@mkdir -p $(EXPORT_PATH)/Payload
@cp -r $(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME).app $(EXPORT_PATH)/Payload/
@cd $(EXPORT_PATH) && zip -r $(SCHEME)-screenstreamer.ipa Payload

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Clean Payload and old archives before repackaging.

Line 45 only creates Payload, and Lines 47/53 write into whatever $(SCHEME)-*.ipa already exists. If make ipa-unsigned is rerun after a partial/interrupted build, stale app bundles/files can leak into the new artifacts, so the output is no longer deterministic.

Proposed hardening
 	`@echo` "Packaging runner IPA..."
-	`@mkdir` -p $(EXPORT_PATH)/Payload
-	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" $(EXPORT_PATH)/Payload/
-	`@cd` $(EXPORT_PATH) && zip -r $(SCHEME)-runner.ipa Payload
+	`@rm` -rf "$(EXPORT_PATH)/Payload" "$(EXPORT_PATH)/$(SCHEME)-runner.ipa"
+	`@mkdir` -p "$(EXPORT_PATH)/Payload"
+	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" "$(EXPORT_PATH)/Payload/"
+	`@cd` "$(EXPORT_PATH)" && zip -r "$(SCHEME)-runner.ipa" Payload
 	`@rm` -rf $(EXPORT_PATH)/Payload
 	`@echo` "Runner IPA created at: $(EXPORT_PATH)/$(SCHEME)-runner.ipa"
 	`@echo` "Packaging screen streamer IPA..."
-	`@mkdir` -p $(EXPORT_PATH)/Payload
-	`@cp` -r $(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME).app $(EXPORT_PATH)/Payload/
-	`@cd` $(EXPORT_PATH) && zip -r $(SCHEME)-screenstreamer.ipa Payload
+	`@rm` -rf "$(EXPORT_PATH)/Payload" "$(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa"
+	`@mkdir` -p "$(EXPORT_PATH)/Payload"
+	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME).app" "$(EXPORT_PATH)/Payload/"
+	`@cd` "$(EXPORT_PATH)" && zip -r "$(SCHEME)-screenstreamer.ipa" Payload
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 45 - 53, Before packaging, remove any stale artifacts:
delete $(EXPORT_PATH)/Payload and existing archive files for the scheme (e.g.
$(EXPORT_PATH)/$(SCHEME)-runner.ipa and
$(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa) to ensure deterministic output,
then recreate Payload with mkdir -p; replace the current sequence around the
Payload/zip steps so you run rm -rf "$(EXPORT_PATH)/Payload" && rm -f
"$(EXPORT_PATH)/$(SCHEME)-runner.ipa" && rm -f
"$(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa" before creating Payload and
copying the .app bundles, and ensure you also remove the temporary Payload after
each zip to avoid leaks between the two packaging steps.

Remove screen streamer app from build artifacts. The broadcast
extension will be refactored to a separate repo.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
Makefile (2)

45-48: ⚠️ Potential issue | 🟠 Major

Recreate the IPA instead of updating it in place.

Line 47 writes into any existing $(SCHEME)-runner.ipa. zip -r updates matching entries, but it does not remove files that disappeared from Payload, so rerunning make ipa-unsigned can leak stale bundle contents into the new artifact.

Proposed change
 	`@echo` "Packaging runner IPA..."
-	`@mkdir` -p $(EXPORT_PATH)/Payload
-	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" $(EXPORT_PATH)/Payload/
-	`@cd` $(EXPORT_PATH) && zip -r $(SCHEME)-runner.ipa Payload
-	`@rm` -rf $(EXPORT_PATH)/Payload
+	`@rm` -rf "$(EXPORT_PATH)/Payload" "$(EXPORT_PATH)/$(SCHEME)-runner.ipa"
+	`@mkdir` -p "$(EXPORT_PATH)/Payload"
+	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" "$(EXPORT_PATH)/Payload/"
+	`@cd` "$(EXPORT_PATH)" && zip -r "$(SCHEME)-runner.ipa" Payload
+	`@rm` -rf "$(EXPORT_PATH)/Payload"

Run this to verify the zip -r behavior in isolation:

#!/bin/bash
set -euo pipefail

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

mkdir -p "$tmp/Payload/App.app"
printf 'old\n' > "$tmp/Payload/App.app/old.txt"

(
  cd "$tmp"
  zip -qr test.ipa Payload
)

rm "$tmp/Payload/App.app/old.txt"
printf 'new\n' > "$tmp/Payload/App.app/new.txt"

(
  cd "$tmp"
  zip -qr test.ipa Payload
)

python - "$tmp/test.ipa" <<'PY'
import sys, zipfile
zf = zipfile.ZipFile(sys.argv[1])
names = sorted(zf.namelist())
print("\n".join(names))
print("\nstale_old_present =", "Payload/App.app/old.txt" in names)
PY
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 45 - 48, The Makefile's zip step currently updates an
existing $(SCHEME)-runner.ipa which can leave stale files; before running zip
-r, delete any existing archive at $(EXPORT_PATH)/$(SCHEME)-runner.ipa (or use
zip --filesync/ -FS) so the new archive is created cleanly from
$(EXPORT_PATH)/Payload; update the snippet around the cp/cd/zip steps to remove
the old $(SCHEME)-runner.ipa (rm -f $(EXPORT_PATH)/$(SCHEME)-runner.ipa) or
replace zip -r with zip -r -FS to ensure removed files do not persist.

44-49: ⚠️ Potential issue | 🟠 Major

Emit the screen streamer IPA from ipa-unsigned too.

This target now stops after creating $(SCHEME)-runner.ipa. Nothing in ipa-unsigned repackages $(SCHEME).app into a second IPA anymore, so the runner/screen-streamer split is only half implemented.

Proposed change
 	`@echo` "Packaging runner IPA..."
 	`@mkdir` -p $(EXPORT_PATH)/Payload
 	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app" $(EXPORT_PATH)/Payload/
 	`@cd` $(EXPORT_PATH) && zip -r $(SCHEME)-runner.ipa Payload
 	`@rm` -rf $(EXPORT_PATH)/Payload
 	`@echo` "Runner IPA created at: $(EXPORT_PATH)/$(SCHEME)-runner.ipa"
+	`@echo` "Packaging screen streamer IPA..."
+	`@mkdir` -p $(EXPORT_PATH)/Payload
+	`@cp` -r "$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME).app" $(EXPORT_PATH)/Payload/
+	`@cd` $(EXPORT_PATH) && zip -r $(SCHEME)-screenstreamer.ipa Payload
+	`@rm` -rf $(EXPORT_PATH)/Payload
+	`@echo` "Screen streamer IPA created at: $(EXPORT_PATH)/$(SCHEME)-screenstreamer.ipa"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 44 - 49, The current Makefile block that packages the
runner IPA (uses EXPORT_PATH, BUILD_DIR, CONFIGURATION, SCHEME) stops after
creating $(SCHEME)-runner.ipa and no longer repackages the app in the
ipa-unsigned export; update this packaging step to also create the
screen-streamer IPA from the ipa-unsigned output. Concretely: after the existing
runner packaging (the block that cp's
"$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app"
into $(EXPORT_PATH)/Payload and zips it), add analogous commands that copy the
$(SCHEME).app produced by the ipa-unsigned path into a fresh Payload, zip it as
the screen-streamer IPA (use a clear name like $(SCHEME)-screen-streamer.ipa or
match existing naming conventions), and clean up the temporary Payload;
reference the same variables (EXPORT_PATH, SCHEME, BUILD_DIR/ipa-unsigned
output) so both runner and screen-streamer IPAs are produced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@Makefile`:
- Around line 45-48: The Makefile's zip step currently updates an existing
$(SCHEME)-runner.ipa which can leave stale files; before running zip -r, delete
any existing archive at $(EXPORT_PATH)/$(SCHEME)-runner.ipa (or use zip
--filesync/ -FS) so the new archive is created cleanly from
$(EXPORT_PATH)/Payload; update the snippet around the cp/cd/zip steps to remove
the old $(SCHEME)-runner.ipa (rm -f $(EXPORT_PATH)/$(SCHEME)-runner.ipa) or
replace zip -r with zip -r -FS to ensure removed files do not persist.
- Around line 44-49: The current Makefile block that packages the runner IPA
(uses EXPORT_PATH, BUILD_DIR, CONFIGURATION, SCHEME) stops after creating
$(SCHEME)-runner.ipa and no longer repackages the app in the ipa-unsigned
export; update this packaging step to also create the screen-streamer IPA from
the ipa-unsigned output. Concretely: after the existing runner packaging (the
block that cp's
"$(BUILD_DIR)/Build/Products/$(CONFIGURATION)-iphoneos/$(SCHEME)UITests-Runner.app"
into $(EXPORT_PATH)/Payload and zips it), add analogous commands that copy the
$(SCHEME).app produced by the ipa-unsigned path into a fresh Payload, zip it as
the screen-streamer IPA (use a clear name like $(SCHEME)-screen-streamer.ipa or
match existing naming conventions), and clean up the temporary Payload;
reference the same variables (EXPORT_PATH, SCHEME, BUILD_DIR/ipa-unsigned
output) so both runner and screen-streamer IPAs are produced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f25a5df1-c4a6-4760-a592-d4d723bdd47f

📥 Commits

Reviewing files that changed from the base of the PR and between 918b38e and 975e73c.

📒 Files selected for processing (1)
  • Makefile

@gmegidish
gmegidish merged commit 432cff2 into main Apr 15, 2026
5 of 6 checks passed
@gmegidish
gmegidish deleted the feat-split-ipa branch April 15, 2026 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant