ci(ios): bundle the verified generic developer image

This commit is contained in:
zeuzmakessoftware 2026-09-20 22:56:31 -07:00
parent a4722251f2
commit e145bbe932
2 changed files with 63 additions and 0 deletions

View file

@ -29,6 +29,15 @@ jobs:
with:
xcode-version: '26.6'
- name: Test Cryptex image validation
run: swift test
- name: Prepare checksum-pinned idevice with Cryptex support
run: python3 scripts/prepare_idevice.py
- name: Prepare verified generic developer image
run: python3 scripts/prepare_cryptex_ddi.py --output build/BundledCryptexDDI
- name: 3. Compile Project Archive
run: |
xcodebuild clean archive \
@ -48,6 +57,7 @@ jobs:
- name: 4. Package .app into .ipa
run: |
cp -R build/StikDebug.xcarchive/Products/Applications/StikDebug.app .
cp -R build/BundledCryptexDDI StikDebug.app/BundledCryptexDDI
mkdir -p Payload
cp -R StikDebug.app Payload/
zip -r StikDebug.ipa Payload

View file

@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Bundle the verified generic DDI used in the iPhone19,2 mounting test."""
import argparse
import hashlib
import plistlib
import shutil
import tempfile
import urllib.request
from pathlib import Path
REVISION = "59a90f1e3f1e7190b9a429c768568b83c321582e"
BASE = f"https://raw.githubusercontent.com/doronz88/DeveloperDiskImage/{REVISION}/PersonalizedImages/Xcode_iOS_DDI_Cryptex"
PAYLOADS = {
"Cryptex1,GenericDmg": "Image.dmg",
"Cryptex1,GenericTrustCache": "Image.dmg.trustcache",
"Cryptex1,CryptexInfoPlist": "Image.dmg.cryptex_info",
"Cryptex1,GenericVolume": "Image.dmg.root_hash",
}
def prepare(output: Path):
if output.exists():
raise ValueError(f"Output already exists: {output}")
output.parent.mkdir(parents=True, exist_ok=True)
staging = Path(tempfile.mkdtemp(prefix="cryptex-", dir=output.parent))
try:
def download(name):
with urllib.request.urlopen(f"{BASE}/{name}", timeout=120) as response:
data = response.read()
(staging / name).write_bytes(data)
return data
manifest = plistlib.loads(download("BuildManifest.plist"))
identity = next(i for i in manifest["BuildIdentities"]
if i.get("Info", {}).get("Variant", "").endswith("Developer Disk Image Cryptex"))
for key, name in PAYLOADS.items():
entry = identity["Manifest"][key]
if entry["Info"]["Path"] != name:
raise ValueError(f"Unexpected Cryptex path for {key}")
data = download(name)
if not data or hashlib.sha384(data).digest() != entry["Digest"]:
raise ValueError(f"Cryptex payload failed verification: {name}")
staging.rename(output)
print(f"Verified Cryptex DDI {manifest['ProductBuildVersion']} from {REVISION}")
finally:
if staging.exists():
shutil.rmtree(staging)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--output", type=Path, required=True)
prepare(parser.parse_args().output)