Signing, tests, and archives
An iPhone app needs a development identity and a provisioning profile before installation. Linux builds and signs the products. A Mac with Xcode supplies Apple test execution.
Configure development signing
Prepare an Apple Development certificate and private key as a P12 file. Use OpenSSL 3 with AES encryption for the export. Legacy P12 files that use 40-bit RC2 encryption are not supported by the Linux signer.
Provide profiles for the app's bundle identifiers, entitlements, and registered iPhone. Extensions and UI test runners can require additional matching profiles.
Set the paths and enter the password in your local terminal:
export SWEETPAD_CODE_SIGN_P12="$HOME/signing/development.p12"
export SWEETPAD_PROVISIONING_PROFILES="$HOME/signing/profiles"
read -r -s -p 'P12 password: ' SWEETPAD_CODE_SIGN_P12_PASSWORD
printf '\n'
export SWEETPAD_CODE_SIGN_P12_PASSWORD
sweetpad build --project MyApp.xcodeproj --scheme MyApp \
--destination 'generic/platform=iOS' --json --non-interactive \
-- -derivedDataPath "$HOME/builds/MyApp" ARCHS=arm64
The signer selects a matching profile from the configured directory. Without a configured directory, it also checks the profile locations that Xcode uses under the user's Library.
An unsigned device build can compile successfully, but the phone cannot install it. Simulator builds require no development identity.
Build test products
Use the test action for a scheme that contains unit or UI tests:
sweetpad test build --project MyApp.xcodeproj --scheme MyApp \
--destination 'generic/platform=iOS Simulator' --json --non-interactive \
-- -derivedDataPath "$HOME/builds/MyAppTests" ARCHS=arm64 CODE_SIGNING_ALLOWED=NO
JSON output includes built and xctestrunPath.
A successful build with an unsupported manifest policy reports a null path and an explanatory xctestrunNote.
Check both the build result and the manifest path before scheduling test execution.
For an iPhone test build, select generic/platform=iOS and configure signing for every required bundle.
Unit, UI runner, and target app signatures must match the device's provisioning requirements.
Select a test plan
Linux supports version-1 test plans and their named configurations. The default plan supplies enabled test targets and manifest settings. Select another referenced plan after the passthrough separator:
sweetpad test build --project MyApp.xcodeproj --scheme MyApp \
--destination 'generic/platform=iOS Simulator' --json --non-interactive \
-- -testPlan Smoke -derivedDataPath "$HOME/builds/MyAppSmoke" \
ARCHS=arm64 CODE_SIGNING_ALLOWED=NO
Supported settings include environment, arguments, locale, selected or skipped tests, expansion target, timeouts, parallelization, and attachment lifetime. Sanitizer policies and other unsupported settings require a supplied manifest.
Run Linux-built tests
Copy the complete Products directory and its generated manifest to a Mac. Preserve its directory layout, executable permissions, and symbolic links. A tar archive preserves these properties when CI artifact storage does not:
tar -C "$HOME/builds/MyAppTests/Build" -czf MyAppTests.tar.gz Products
On the Mac, extract the archive and run the emitted manifest:
tar -xzf MyAppTests.tar.gz
sweetpad test run --project MyApp.xcodeproj --scheme MyApp \
--xctestrun /path/to/Products/prebuilt.xctestrun \
--on SIMULATOR_UDID --json --non-interactive
Use the actual manifest filename from xctestrunPath.
For signed iPhone products, select the phone's UDID instead of a simulator.
The selected runtime must support the product's platform, architecture, and deployment target.
This uses Xcode's test-without-building action. It does not compile the application or tests again. The project supplies result history and context; the manifest supplies the prebuilt products. A selection that runs zero tests fails.
The automatic manifests preserve enabled targets, environment values, quoted arguments, locale overrides, and test filters. UI test manifests also identify the built runner and target application.
Create a development archive
Configure development signing, then archive the device build:
sweetpad archive --project MyApp.xcodeproj --scheme MyApp \
--destination 'generic/platform=iOS' \
--export-method debugging --output-file ./artifacts \
--json --non-interactive
The archive includes app, extension, and embedded-framework debug symbols.
Development IPA export preserves the build's identity and profiles.
Use --no-export to retain only the archive.
Distribution export and custom export options require Xcode. The Linux export path rejects unsigned IPA export and simulator archives.
Validate on an iPhone
The Ubuntu and USB guide covers installation, launch, and bounded logs. A startup check confirms that the signed products launch. It does not validate every entitlement, extension, payment flow, or push service.
For CI, keep signing files separate from retained build artifacts. The GitHub Actions guide describes the runner and artifact layout.