@zuke/apple
`@zuke/apple` — typed task wrappers for Apple's code-signing tools in Zuke
@zuke/apple on JSR ↗ 84 symbols
Symbols
type AltoolOperation = --upload-app | --validate-app The altool operations this wrapper runs.
type AltoolPlatform = ios | macos | appletvos | visionos The platform of the app being uploaded (--type).
class AltoolSettings extends ToolSettings Settings for xcrun altool --upload-app and --validate-app.
| Member | Signature | Doc |
|---|---|---|
file | file(path: PathLike): this | The .ipa or .pkg to upload or validate (--file); required. |
type | type(platform: AltoolPlatform): this | The app's platform (--type); required. |
apiKey | apiKey(keyId: string, issuerId: string): this | Authenticate with an App Store Connect API key: its key id and issuer id (--apiKey, --apiIssuer). altool finds AuthKey_<keyId>.p8 in ~/.appstoreconnect/private_keys and its other search directories, or in apiPrivateKeysDir. |
apiPrivateKeysDir | apiPrivateKeysDir(path: PathLike): this | The directory holding AuthKey_<keyId>.p8, passed to altool as API_PRIVATE_KEYS_DIR. |
appleId | appleId(username: string, password: string): this | Authenticate with an Apple ID and an app-specific password (--username, --password). The password is handed to altool in an environment variable it reads through @env:, so it is never on the command line, and it is registered with the run's redactor. |
const AltoolTasks: AltoolTasksApi Typed task functions for xcrun altool.
interface AltoolTasksApi The shape of AltoolTasks.
| Member | Signature | Doc |
|---|---|---|
uploadApp | uploadApp(configure: Configure<AltoolSettings>): Promise<CommandOutput> | Upload an app to App Store Connect: xcrun altool --upload-app. |
validateApp | validateApp(configure: Configure<AltoolSettings>): Promise<CommandOutput> | Validate an app without uploading it: xcrun altool --validate-app. |
const APP_STORE_CONNECT_API_URL: https://api.appstoreconnect.apple.com The App Store Connect API's base URL.
class AppStoreConnectError extends Error Raised when the App Store Connect API answers with an error status. The message names the request and every error the API listed; it never carries the API key or the token signed with it.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
interface AppStoreConnectErrorDetail One entry of an App Store Connect API error response's errors list.
| Member | Signature | Doc |
|---|---|---|
code | code: string | The machine-readable code, e.g. ENTITY_ERROR.ATTRIBUTE.INVALID. |
title | title: string | The short title. |
detail? | detail?: string | The explanation, when the API gave one. |
class AppStoreConnectSettings Settings for a task that calls the App Store Connect API with an API key (*Users and Access → Integrations* in App Store Connect): the issuer id, the key id, and the AuthKey_<keyId>.p8 private key.
The private key and every token signed with it stay out of progress lines and errors. Declare them in the build as parameter(...).secret() so Zuke masks them in its own output too.
| Member | Signature | Doc |
|---|---|---|
issuerId | issuerId(id: string): this | The API key's issuer id, a UUID. |
keyId | keyId(id: string): this | The API key's id, e.g. ABC123. |
privateKey | privateKey(pem: string): this | The private key, as the PEM text of AuthKey_<keyId>.p8. |
privateKeyFile | privateKeyFile(path: PathLike): this | Read the private key from AuthKey_<keyId>.p8. |
apiUrl | apiUrl(url: string): this | The API's base URL, https://api.appstoreconnect.apple.com by default. It carries the token, so it must be https: unless it is loopback or ZUKE_ALLOW_INSECURE_URL is set. |
fetch | fetch(fetcher: fetch): this | Send with this fetch instead of the global one — the seam tests use. |
readEnv | readEnv(reader: unknown): this | Read environment variables through reader instead of Deno.env. |
sleep | sleep(sleeper: unknown): this | Wait through sleeper instead of a timer — the seam tests use. |
now | now(clock: unknown): this | Read the time from clock (epoch ms) instead of Date.now. |
log | log(sink: unknown): this | Send progress lines to sink instead of console.log. |
issuerId_? | issuerId_?: string | The API key's issuer id (set by issuerId). |
keyId_? | keyId_?: string | The API key's id (set by keyId). |
privateKey_? | privateKey_?: string | The private key, PEM (set by privateKey). |
privateKeyFile_? | privateKeyFile_?: string | The private key's file (set by privateKeyFile). |
apiUrl_ | apiUrl_: string | The API's base URL (set by apiUrl). |
fetch_ | fetch_: fetch | The fetch to use (set by fetch). |
readEnv_ | readEnv_: unknown | The environment reader (set by readEnv). |
sleep_ | sleep_: unknown | How the task waits between polls (set by sleep). |
now_ | now_: unknown | The clock, in epoch ms (set by now). |
log_ | log_: unknown | Where progress lines go (set by log). |
interface CodesignDisplay A code signature as codesign --display describes it.
| Member | Signature | Doc |
|---|---|---|
identifier? | identifier?: string | The signed code's identifier (Identifier=), when printed. |
teamIdentifier? | teamIdentifier?: string | The team identifier (TeamIdentifier=), when printed. codesign prints not set for an ad-hoc signature, and that text is kept as it is. |
authorities | authorities: string[] | The certificate chain (Authority= lines), leaf first. |
text | text: string | The whole description: stderr, then any stdout, trimmed. |
output | output: CommandOutput | The command output the description was read from. |
class CodesignDisplaySettings extends CodesignSettings Settings for codesign --display.
class CodesignSettings extends ToolSettings The shared shape of every codesign operation: the files it acts on and how verbose it is. Each operation subclass names its mode flag and its own options.
| Member | Signature | Doc |
|---|---|---|
file | file(...paths: PathLike[]): this | The code to act on (positional) — an app bundle, framework, binary or disk image; repeatable. A relative path starting with - is passed as ./-… so codesign cannot read it as an option. |
verbose | verbose(level?: number): this | More output (--verbose, or --verbose=<level> with a level). display shows more of the signature at each level; 4 lists everything. |
class CodesignSignSettings extends CodesignSettings Settings for codesign --sign.
| Member | Signature | Doc |
|---|---|---|
identity | identity(value: string): this | The signing identity (--sign <identity>): a certificate's common name, a substring of it, or its SHA-1 hash. - signs ad hoc. Required. |
force | force(): this | Replace an existing signature (--force). |
deep | deep(): this | Sign nested code as well (--deep). Apple discourages it for signing. |
options | options(...flags: string[]): this | Signature option flags (--options, comma-joined); repeatable. runtime enables the hardened runtime notarization requires. |
timestamp | timestamp(url?: string): this | Request a secure timestamp (--timestamp), from url when given (--timestamp=<url>). Notarization requires one. |
entitlements | entitlements(path: PathLike): this | The entitlements plist to embed (--entitlements). |
keychain | keychain(path: PathLike): this | Look the identity up in this keychain only (--keychain). |
identifier | identifier(value: string): this | The code's identifier (--identifier), overriding the bundle id. |
const CodesignTasks: CodesignTasksApi Typed task functions for Apple's codesign.
interface CodesignTasksApi The shape of CodesignTasks.
| Member | Signature | Doc |
|---|---|---|
sign | sign(configure: Configure<CodesignSignSettings>): Promise<CommandOutput> | Sign code with codesign --sign. |
verify | verify(configure: Configure<CodesignVerifySettings>): Promise<CommandOutput> | Check a signature with codesign --verify; a bad one fails the run. |
display | display(configure: Configure<CodesignDisplaySettings>): Promise<CodesignDisplay> | Describe a signature with codesign --display. codesign prints the description on stderr, so it is returned parsed, with the raw text and the command output alongside. |
class CodesignVerifySettings extends CodesignSettings Settings for codesign --verify.
| Member | Signature | Doc |
|---|---|---|
strict | strict(): this | Apply the strict validation rules notarization uses (--strict). |
deep | deep(): this | Verify nested code as well (--deep). |
class DittoSettings extends ToolSettings Settings for a ditto run.
| Member | Signature | Doc |
|---|---|---|
create | create(): this | Create an archive rather than copy (-c). |
extract | extract(): this | Extract an archive rather than copy (-x). |
pkzip | pkzip(): this | Use the PKZip format for the archive (-k) instead of CPIO. |
sequesterRsrc | sequesterRsrc(): this | Keep resource forks and HFS metadata in a __MACOSX directory inside the archive (--sequesterRsrc), the way the Finder's own compress does. |
keepParent | keepParent(): this | Put the source directory itself in the archive, not only its contents (--keepParent) — what makes a zipped MyApp.app unzip as MyApp.app. |
source | source(path: PathLike): this | What to copy or archive (positional). Required. |
destination | destination(path: PathLike): this | Where to write it (positional). Required. |
const DittoTasks: DittoTasksApi Typed task functions for macOS ditto.
interface DittoTasksApi The shape of DittoTasks.
| Member | Signature | Doc |
|---|---|---|
copy | copy(configure: Configure<DittoSettings>): Promise<CommandOutput> | Copy a file or directory tree with ditto, metadata intact. |
archive | archive(configure: Configure<DittoSettings>): Promise<CommandOutput> | Write a zip archive: ditto -c -k, then the lambda's settings. |
extract | extract(configure: Configure<DittoSettings>): Promise<CommandOutput> | Unpack a zip archive: ditto -x -k, then the lambda's settings. |
type ExportDestination = export | upload Whether to write the export locally or upload it to App Store Connect (destination).
type ExportMethod = app-store-connect | release-testing | enterprise | debugging | developer-id | mac-application | validation | app-store | ad-hoc | development How an archive is exported (method). Xcode 15.3 renamed three methods: app-store-connect, release-testing and debugging were app-store, ad-hoc and development, which older Xcode versions still require.
class ExportOptionsSettings Settings for an ExportOptions.plist.
| Member | Signature | Doc |
|---|---|---|
method | method(method: ExportMethod): this | How the archive is exported (method); required. |
teamId | teamId(id: string): this | The developer team id (teamID). |
signingStyle | signingStyle(style: ExportSigningStyle): this | Automatic or manual signing (signingStyle). |
signingCertificate | signingCertificate(name: string): this | The certificate to sign with, e.g. Apple Distribution (signingCertificate). |
provisioningProfile | provisioningProfile(bundleId: string, profile: string): this | The provisioning profile, by name or UUID, for one bundle identifier (provisioningProfiles); repeatable, once per app and extension. |
destination | destination(destination: ExportDestination): this | Export to a directory, or upload to App Store Connect (destination). |
uploadSymbols | uploadSymbols(enabled: boolean): this | Include symbols for crash reports (uploadSymbols). |
manageAppVersionAndBuildNumber | manageAppVersionAndBuildNumber(enabled: boolean): this | Let App Store Connect manage the version and build number (manageAppVersionAndBuildNumber). |
stripSwiftSymbols | stripSwiftSymbols(enabled: boolean): this | Strip Swift symbols from the binary (stripSwiftSymbols). |
testFlightInternalTestingOnly | testFlightInternalTestingOnly(enabled: boolean): this | Limit a TestFlight upload to internal testers (testFlightInternalTestingOnly). |
render | render(): string | The property list, as xcodebuild -exportArchive -exportOptionsPlist reads it. Pure: no I/O. |
options_ | options_: Map<string, ExportOptionValue> | The options set so far, in the order each key was first set; setting a key again replaces its value in place. |
type ExportOptionValue = string | boolean | Record<string, string> One value in an ExportOptions.plist: a string, a boolean, or a string dictionary.
type ExportSigningStyle = automatic | manual Whether Xcode or the export options pick the signing assets (signingStyle).
interface InstalledProvisioningProfile An installed provisioning profile.
| Member | Signature | Doc |
|---|---|---|
profile | profile: ProvisioningProfile | What the profile says about itself. |
paths | paths: unknown | Every file it was installed as. |
class KeychainCleanupError extends Error Raised by SecurityTasks.temporaryKeychain when tearing the keychain down failed — restoring the search list, deleting the keychain, or removing its directory. Every step is attempted regardless; failures holds each one that threw. When the callback had already failed, that error is the Error.cause, so neither is lost.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
interface KeychainCleanupFailure One cleanup step of a temporary keychain that threw.
| Member | Signature | Doc |
|---|---|---|
step | step: string | What the step was doing, e.g. delete the keychain. |
message | message: string | The step's error message. |
class KeychainError extends Error Raised by SecurityTasks.temporaryKeychain when the keychain cannot be set up for signing: no certificate given, a certificate that is not base64, or an imported certificate holding no codesigning identity, or several that the identity filter cannot tell apart. Never carries a password.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
interface KeychainHost What SecurityTasks.temporaryKeychain asks of the machine it runs on.
| Member | Signature | Doc |
|---|---|---|
security | security(settings: SecuritySettings): Promise<CommandOutput> | Run one configured security command and return its output. |
makeTempDir | makeTempDir(): Promise<string> | Create a fresh private directory and return its absolute, canonical path — symlinks resolved, so it is spelled the way security list-keychains prints it (on macOS the temp dir is under the /var → /private/var link). |
writePrivateFile | writePrivateFile(path: string, data: Uint8Array): Promise<void> | Write data to a new file at path readable by the owner only (mode 0600), refusing to overwrite or follow anything already there. |
remove | remove(path: string): Promise<void> | Remove path and anything under it; a path that is already gone is fine. |
randomHex | randomHex(bytes: number): string | bytes cryptographically random bytes, as lower-case hex. |
class NotarizationError extends Error Raised by NotarytoolTasks.submit when .wait() was set and Apple finished the submission with any status other than Accepted. The message names the status and lists the issues from the submission's notarization log, which the task fetched with the same credentials.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
class NotarytoolHistorySettings extends NotarytoolSettings Settings for xcrun notarytool history.
class NotarytoolInfoSettings extends NotarytoolSettings Settings for xcrun notarytool info <id>.
| Member | Signature | Doc |
|---|---|---|
submissionId | submissionId(id: string): this | The submission to describe (positional). Required. |
interface NotarytoolIssue One problem a notarization log reports.
| Member | Signature | Doc |
|---|---|---|
severity? | severity?: string | error or warning. |
message? | message?: string | What is wrong, e.g. The binary is not signed. |
path? | path?: string | The path inside the archive the issue is about. |
architecture? | architecture?: string | The CPU architecture of the offending slice. |
docUrl? | docUrl?: string | Apple's documentation link for the issue. |
interface NotarytoolLog A submission's notarization log, from notarytool log.
| Member | Signature | Doc |
|---|---|---|
jobId? | jobId?: string | The submission id the log belongs to. |
status? | status?: string | The final status, e.g. Invalid. |
statusSummary? | statusSummary?: string | A one-line summary, e.g. Archive contains critical validation errors. |
issues | issues: NotarytoolIssue[] | Every issue the log lists; empty for a clean submission. |
text | text: string | The log as notarytool printed it. |
class NotarytoolLogSettings extends NotarytoolSettings Settings for xcrun notarytool log <id>.
| Member | Signature | Doc |
|---|---|---|
submissionId | submissionId(id: string): this | The submission whose log to fetch (positional). Required. |
class NotarytoolOutputError extends Error Raised when notarytool did not print the JSON result a task asked for — an older Xcode, a crash, or output that is not a notarytool result at all. The raw output is kept on the error rather than in its message.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
class NotarytoolSettings extends ToolSettings The shared settings of every xcrun notarytool subcommand: the credentials, and the masking of the app-specific password. A subclass names its subcommand and builds its own arguments.
| Member | Signature | Doc |
|---|---|---|
key | key(path: PathLike): this | The App Store Connect API private key file, AuthKey_<id>.p8 (--key). |
keyId | keyId(id: string): this | The API key's id (--key-id). |
issuer | issuer(uuid: string): this | The API key's issuer UUID (--issuer); omit it for an individual key. |
keychainProfile | keychainProfile(name: string): this | Authenticate with credentials saved by notarytool store-credentials (--keychain-profile). |
keychain | keychain(path: PathLike): this | The keychain to read the keychainProfile from (--keychain). |
appleId | appleId(email: string): this | The Apple ID to authenticate as (--apple-id). |
password | password(value: string): this | The Apple ID's app-specific password (--password). Registered with the run's redactor and masked out of any error this run raises. |
teamId | teamId(id: string): this | The developer team id the Apple ID signs for (--team-id). |
toolPath | toolPath(path: PathLike): this | Override the binary, remembered so a follow-up command uses it too. |
env | env(record: Record<string, string>): this | Merge environment variables, remembered for a follow-up command too. |
cwd | cwd(path: PathLike): this | Set the working directory, remembered for a follow-up command too. |
run | run(): Promise<CommandOutput> | Run the command, with the app-specific password masked out of any CommandError or timeout it raises — inside a run and outside one. |
interface NotarytoolSubmission A notarization submission as notarytool reports it.
| Member | Signature | Doc |
|---|---|---|
id | id: string | The submission id, used by info, log and wait. |
status? | status?: string | The status — Accepted, Invalid, Rejected or In Progress. Absent from a submit run without --wait, which only reports the upload. |
message? | message?: string | notarytool's message, e.g. Processing complete. |
name? | name?: string | The uploaded file's name (info, history). |
createdDate? | createdDate?: string | When the submission was created, ISO 8601 (info, history). |
class NotarytoolSubmitSettings extends NotarytoolSettings Settings for xcrun notarytool submit.
| Member | Signature | Doc |
|---|---|---|
file | file(path: PathLike): this | The archive to notarize — a .zip, .pkg or .dmg (positional). Required. |
wait | wait(): this | Wait for Apple to finish processing (--wait). With it the result carries the final status, and NotarytoolTasks.submit throws a NotarizationError for anything but Accepted. |
timeout | timeout(duration: string): this | How long --wait waits, e.g. 30m or 1h (--timeout). Needs wait. |
waits | waits(): boolean | Whether wait was set. |
logFor | logFor(id: string): NotarytoolLogSettings | Settings for notarytool log <id> that reuse this submission's credentials, binary, environment and working directory. |
submit_ | submit_(): Promise<NotarytoolSubmission> | Run the submission and read its JSON result — what NotarytoolTasks.submit calls before judging the status. The exit code is judged after the JSON is read: notarytool can exit non-zero for a waited submission Apple did not accept, and that result — which NotarytoolTasks.submit turns into a NotarizationError with the log — is the most useful thing to report. Any other non-zero exit raises the CommandError, even when it printed a result with an id (an upload that failed after the id was issued, say); .noThrow() returns the result instead. A failed run with no readable result raises it even under .noThrow(), since there is then nothing to return. |
const NotarytoolTasks: NotarytoolTasksApi Typed task functions for xcrun notarytool.
interface NotarytoolTasksApi The shape of NotarytoolTasks.
| Member | Signature | Doc |
|---|---|---|
submit | submit(configure: Configure<NotarytoolSubmitSettings>): Promise<NotarytoolSubmission> | Upload an archive with notarytool submit and return the parsed result. With .wait(), a final status other than Accepted fetches the submission's log and throws a NotarizationError listing its issues — unless .noThrow() was set, when the result is returned for the caller to inspect. |
info | info(configure: Configure<NotarytoolInfoSettings>): Promise<NotarytoolSubmission> | Read a submission's status with notarytool info. |
log | log(configure: Configure<NotarytoolLogSettings>): Promise<NotarytoolLog> | Fetch and parse a submission's notarization log with notarytool log. |
history | history(configure: Configure<NotarytoolHistorySettings>): Promise<NotarytoolSubmission[]> | List the team's past submissions with notarytool history. |
interface ProvisioningHost The operations installing a provisioning profile needs.
| Member | Signature | Doc |
|---|---|---|
readFile | readFile(path: string): Promise<Uint8Array> | Read a file's bytes. |
makeDirectory | makeDirectory(path: string): Promise<void> | Create a directory and its parents, if missing. |
writeFile | writeFile(path: string, data: Uint8Array): Promise<void> | Write a file, replacing one that exists. |
remove | remove(path: string): Promise<void> | Remove a file. |
exists | exists(path: string): Promise<boolean> | Whether a file exists. |
home | home(): string | The user's home directory. |
interface ProvisioningProfile A provisioning profile's identity, as read from the profile itself.
| Member | Signature | Doc |
|---|---|---|
uuid | uuid: string | The profile's UUID — Xcode installs it as <uuid>.mobileprovision. |
name | name: string | The profile's name, as ExportOptions.plist can refer to it. |
teamIds | teamIds: unknown | The team ids it belongs to. |
teamName | teamName: string | The team's name. |
appIdName | appIdName: string | The App ID's name. |
bundleId | bundleId: string | The bundle identifier it signs, e.g. com.example.app, or a wildcard such as com.example.* — the application-identifier entitlement without its team prefix. |
platforms | platforms: unknown | The platforms it is for, e.g. ["iOS"]. |
kind | kind: ProvisioningProfileKind | How it distributes the app. |
creationDate | creationDate: Date | When it was created. |
expirationDate | expirationDate: Date | When it expires. |
xcodeManaged | xcodeManaged: boolean | Whether Xcode created and manages it (automatic signing). |
class ProvisioningProfileError extends Error Raised by ProvisioningProfileTasks when a profile cannot be read, is expired, or could not be removed after temporary. When the callback had already failed before the removal did, that error is the Error.cause.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
type ProvisioningProfileKind = development | ad-hoc | enterprise | app-store How a profile distributes the app, as Xcode's Organizer names it: development (devices listed, debugging allowed), ad-hoc (devices listed), enterprise (all devices) or app-store (no devices — App Store and TestFlight).
class ProvisioningProfileSettings Settings for ProvisioningProfileTasks.
| Member | Signature | Doc |
|---|---|---|
file | file(path: PathLike): this | Read the profile from a .mobileprovision file. |
base64 | base64(text: string): this | Take the profile as base64 — how a CI secret usually holds it (base64 -i profile.mobileprovision). |
directory | directory(path: PathLike): this | Install into this directory instead of Xcode's two defaults; repeatable. |
allowExpired | allowExpired(): this | Install the profile even if it has expired. |
host | host(host: ProvisioningHost): this | Work through host instead of the real file system — the test seam. |
now | now(clock: unknown): this | Read the time from clock (epoch ms) instead of Date.now. |
file_? | file_?: string | The profile file (set by file). |
base64_? | base64_?: string | The profile as base64 (set by base64). |
directories_ | directories_: string[] | Directories to install into (set by directory). |
allowExpired_ | allowExpired_: boolean | Whether an expired profile may be installed (set by allowExpired). |
host_ | host_: ProvisioningHost | The file-system seam (set by host). |
now_ | now_: unknown | The clock, in epoch ms (set by now). |
const ProvisioningProfileTasks: ProvisioningProfileTasksApi Read and install provisioning profiles.
interface ProvisioningProfileTasksApi The shape of ProvisioningProfileTasks.
| Member | Signature | Doc |
|---|---|---|
inspect | inspect(configure: Configure<ProvisioningProfileSettings>): Promise<ProvisioningProfile> | Read what a profile says about itself, without installing it. |
install | install(configure: Configure<ProvisioningProfileSettings>): Promise<InstalledProvisioningProfile> | Install a profile where Xcode looks for it, named by its UUID. Refuses an expired profile unless .allowExpired(). |
temporary | temporary(configure: Configure<ProvisioningProfileSettings>, fn: unknown): Promise<T> | Install a profile, run fn, then remove every file the install created — even when fn throws. A copy that was already installed under the same UUID is left in place. Returns what fn returns. |
class SecurityCreateKeychainSettings extends SecuritySettings Settings for security create-keychain.
| Member | Signature | Doc |
|---|---|---|
password | password(value: string): this | The new keychain's password (-p). A secret: masked in every rendering of the command. Without it security prompts for one. |
keychain | keychain(...paths: PathLike[]): this | The keychain(s) to create (positional); repeatable. Required. |
class SecurityDeleteKeychainSettings extends SecuritySettings Settings for security delete-keychain.
| Member | Signature | Doc |
|---|---|---|
keychain | keychain(...paths: PathLike[]): this | The keychain(s) to delete (positional); repeatable. Required. |
type SecurityDomain = user | system | common | dynamic A preference domain security list-keychains reads or sets (-d).
class SecurityFindIdentitySettings extends SecuritySettings Settings for security find-identity.
| Member | Signature | Doc |
|---|---|---|
policy | policy(name: string): this | Only identities usable under this policy (-p), e.g. codesigning. |
search | search(value: string): this | Only identities whose name contains this string (-s). |
valid | valid(): this | Only valid identities (-v) — not expired, revoked or untrusted. |
keychain | keychain(...paths: PathLike[]): this | The keychain(s) to search (positional); the search list when omitted. |
interface SecurityIdentity A signing identity as security find-identity lists it.
| Member | Signature | Doc |
|---|---|---|
hash | hash: string | The certificate's SHA-1 hash, 40 upper-case hex digits. |
name | name: string | The certificate's common name, e.g. Developer ID Application: … (TEAMID). |
type SecurityImportFormat = openssl | openssh1 | openssh2 | bsafe | raw | pkcs7 | pkcs8 | pkcs12 | netscape | x509 | pemseq A file format security import accepts (-f).
class SecurityImportSettings extends SecuritySettings Settings for security import.
| Member | Signature | Doc |
|---|---|---|
file | file(path: PathLike): this | The file to import, e.g. a .p12 (positional). Required. |
keychain | keychain(path: PathLike): this | The keychain to import into (-k); the default keychain when omitted. |
passphrase | passphrase(value: string): this | The file's passphrase (-P), e.g. a .p12's export password. A secret: masked in every rendering of the command. |
application | application(...paths: PathLike[]): this | An application allowed to use the imported key without a prompt (-T), e.g. /usr/bin/codesign; repeatable. |
type | type(value: SecurityItemType): this | The type of item in the file (-t). |
format | format(value: SecurityImportFormat): this | The file's format (-f), e.g. pkcs12. |
nonExtractable | nonExtractable(): this | Make the imported private key non-extractable (-x). |
type SecurityItemType = pub | priv | session | cert | agg An item type security import accepts (-t).
class SecurityListKeychainsSettings extends SecuritySettings Settings for security list-keychains.
| Member | Signature | Doc |
|---|---|---|
domain | domain(value: SecurityDomain): this | The preference domain to read or set (-d). |
set | set(...keychains: PathLike[]): this | Replace the search list with these keychains (-s), in order. Called with none, it empties the list. Repeat calls append. |
class SecuritySetKeychainSettings extends SecuritySettings Settings for security set-keychain-settings. With no flags, the keychain never locks on its own — no timeout, and no lock on sleep — which is what a CI keychain wants for the length of a build.
| Member | Signature | Doc |
|---|---|---|
lockOnSleep | lockOnSleep(): this | Lock the keychain when the machine sleeps (-l). |
lockAfterTimeout | lockAfterTimeout(): this | Lock the keychain after timeout seconds of inactivity (-u). |
timeout | timeout(seconds: number): this | The inactivity timeout, in seconds (-t). |
keychain | keychain(path: PathLike): this | The keychain to configure (positional); the default keychain when omitted. |
class SecuritySetKeyPartitionListSettings extends SecuritySettings Settings for security set-key-partition-list, which lets Apple's signing tools use a key without the "allow access" prompt that hangs a headless build.
| Member | Signature | Doc |
|---|---|---|
partitionList | partitionList(...ids: string[]): this | Partition ids to allow (-S, comma-joined); repeatable. apple-tool: and apple: cover codesign and the other Apple tools. |
privateKeys | privateKeys(): this | Match private keys only (-s). |
password | password(value: string): this | The keychain's password (-k). A secret: masked in every rendering of the command. Without it security prompts for one. |
keychain | keychain(path: PathLike): this | The keychain to modify (positional); the default keychain when omitted. |
class SecuritySettings extends ToolSettings The shared settings of every security subcommand: the binary, and the secret handling for the passwords a subcommand takes. A subclass names its subcommand and builds its own arguments.
| Member | Signature | Doc |
|---|---|---|
run | run(): Promise<CommandOutput> | Run the command, with every password masked out of any CommandError or timeout it raises — inside a run and outside one. |
const SecurityTasks: SecurityTasksApi Typed task functions for macOS security.
interface SecurityTasksApi The shape of SecurityTasks.
| Member | Signature | Doc |
|---|---|---|
createKeychain | createKeychain(configure: Configure<SecurityCreateKeychainSettings>): Promise<CommandOutput> | Create a keychain with security create-keychain. |
deleteKeychain | deleteKeychain(configure: Configure<SecurityDeleteKeychainSettings>): Promise<CommandOutput> | Delete a keychain with security delete-keychain. |
unlockKeychain | unlockKeychain(configure: Configure<SecurityUnlockKeychainSettings>): Promise<CommandOutput> | Unlock a keychain with security unlock-keychain. |
setKeychainSettings | setKeychainSettings(configure: Configure<SecuritySetKeychainSettings>): Promise<CommandOutput> | Change a keychain's lock settings with security set-keychain-settings. |
import | import(configure: Configure<SecurityImportSettings>): Promise<CommandOutput> | Import a certificate or key with security import. |
setKeyPartitionList | setKeyPartitionList(configure: Configure<SecuritySetKeyPartitionListSettings>): Promise<CommandOutput> | Set which tools may use a key with security set-key-partition-list. |
listKeychains | listKeychains(configure?: Configure<SecurityListKeychainsSettings>): Promise<string[]> | Read — or, with .set(...), replace — the keychain search list with security list-keychains. Returns the listed paths; empty after a set, which prints nothing. |
findIdentity | findIdentity(configure?: Configure<SecurityFindIdentitySettings>): Promise<SecurityIdentity[]> | List signing identities with security find-identity, parsed. |
temporaryKeychain | temporaryKeychain(configure: Configure<TemporaryKeychainSettings>, use: unknown): Promise<T> | Import a base64 .p12 into a fresh keychain, run use with the keychain and its codesigning identity, and always tear the keychain down after. See TemporaryKeychainSettings. |
class SecurityUnlockKeychainSettings extends SecuritySettings Settings for security unlock-keychain.
| Member | Signature | Doc |
|---|---|---|
password | password(value: string): this | The keychain's password (-p). A secret: masked in every rendering of the command. Without it security prompts for one. |
keychain | keychain(path: PathLike): this | The keychain to unlock (positional); the default keychain when omitted. |
interface TemporaryKeychain What the callback of SecurityTasks.temporaryKeychain is handed.
| Member | Signature | Doc |
|---|---|---|
keychain | keychain: string | The keychain's absolute path — pass it to codesign --keychain. |
identity | identity: SecurityIdentity | The codesigning identity imported into it. |
class TemporaryKeychainSettings Settings for SecurityTasks.temporaryKeychain.
| Member | Signature | Doc |
|---|---|---|
certificate | certificate(base64P12: string): this | The signing certificate and its private key, as a base64-encoded .p12 — the form CI secrets hold it in. Whitespace is ignored. Required. It is decoded only into a 0600 file that is deleted straight after import, and never appears in a command line or an error message. |
certificatePassword | certificatePassword(value: string): this | The .p12's export password, handed to security import -P. A secret: masked in every rendering of that command. Defaults to empty, for a .p12 exported without one — security would otherwise prompt. |
identity | identity(filter: string): this | Pick the identity whose name contains filter, or whose SHA-1 hash it is. Needed only when the .p12 holds more than one codesigning identity. |
application | application(...paths: PathLike[]): this | An application allowed to use the imported key (security import -T); repeatable. Defaults to /usr/bin/codesign when none is named. |
toolPath | toolPath(path: PathLike): this | Run this security binary instead of the one on PATH. |
host | host(value: KeychainHost): this | Replace the machine the keychain is set up on — the seam a test uses to record the steps without macOS. Production code leaves the default. |
open_ | open_(use: unknown): Promise<T> | Set the keychain up, run use with it, and tear it down — what SecurityTasks.temporaryKeychain calls. Returns what use returns. |
interface TestFlightBuild A build in App Store Connect, once processed.
| Member | Signature | Doc |
|---|---|---|
id | id: string | The build's App Store Connect id. |
appId | appId: string | The app's App Store Connect id. |
buildNumber | buildNumber: string | The build number, CFBundleVersion. |
processingState | processingState: string | The processing state: VALID once distribute returns. |
class TestFlightError extends Error Raised by TestFlightTasks.distribute when the release cannot go ahead: no app has the bundle id, a beta group does not exist, the build finished processing as INVALID or FAILED, or it had not finished by the timeout.
| Member | Signature | Doc |
|---|---|---|
name | name: string | The error name. |
type TestFlightPlatform = IOS | MAC_OS | TV_OS | VISION_OS The platform of a build, as App Store Connect names it.
class TestFlightSettings extends AppStoreConnectSettings Settings for TestFlightTasks.distribute.
| Member | Signature | Doc |
|---|---|---|
bundleId | bundleId(id: string): this | The app's bundle id, e.g. com.example.app; required. |
buildNumber | buildNumber(number: string | number): this | The uploaded build's number, CFBundleVersion; required. |
version | version(version: string): this | The uploaded build's version, CFBundleShortVersionString — needed when the same build number exists under several versions. |
platform | platform(platform: TestFlightPlatform): this | The build's platform — needed when the app ships on several. |
timeout | timeout(duration: string | number): this | The longest wait for the build to finish processing ("45m", or ms); default 30 minutes. |
pollInterval | pollInterval(duration: string | number): this | The time between two looks at the build ("1m", or ms); default 30 seconds. |
usesNonExemptEncryption | usesNonExemptEncryption(uses: boolean): this | Answer the export-compliance question: whether the app uses encryption beyond the exempt kinds. Until it is answered — here, or by ITSAppUsesNonExemptEncryption in Info.plist — the build sits at *Missing Compliance* and no tester can install it. |
whatToTest | whatToTest(text: string, locale?: string): this | The "What to Test" notes testers see, per locale; default locale en-US. |
group | group(name: string): this | Add the build to this beta group, by name; repeatable. |
submitForBetaReview | submitForBetaReview(): this | Submit the build for beta review, which external testing needs. |
bundleId_? | bundleId_?: string | The app's bundle id (set by bundleId). |
buildNumber_? | buildNumber_?: string | The build number (set by buildNumber). |
version_? | version_?: string | The version (set by version). |
platform_? | platform_?: TestFlightPlatform | The platform (set by platform). |
timeout_ | timeout_: number | The longest wait for processing, in ms (set by timeout). |
pollInterval_ | pollInterval_: number | The time between two polls, in ms (set by pollInterval). |
usesNonExemptEncryption_? | usesNonExemptEncryption_?: boolean | Export compliance (set by usesNonExemptEncryption). |
whatToTest_ | whatToTest_: Map<string, string> | "What to Test" notes by locale (set by whatToTest). |
groups_ | groups_: string[] | Beta groups to add the build to (set by group). |
submitForBetaReview_ | submitForBetaReview_: boolean | Whether to submit for beta review (set by submitForBetaReview). |
const TestFlightTasks: TestFlightTasksApi Distribute builds in TestFlight through the App Store Connect API.
interface TestFlightTasksApi The shape of TestFlightTasks.
| Member | Signature | Doc |
|---|---|---|
distribute | distribute(configure: Configure<TestFlightSettings>): Promise<TestFlightBuild> | Wait for an uploaded build to be processed, then distribute it in TestFlight as configured. |
class XcodebuildActionSettings extends XcodebuildProjectSettings Settings for xcodebuild build, clean, analyze, build-for-testing and -resolvePackageDependencies.
type XcodebuildActionTask = unknown A task that runs a flag-free xcodebuild action.
class XcodebuildArchiveSettings extends XcodebuildProjectSettings Settings for xcodebuild archive.
| Member | Signature | Doc |
|---|---|---|
archivePath | archivePath(path: PathLike): this | Where to write the .xcarchive (-archivePath); required. |
class XcodebuildExportArchiveSettings extends XcodebuildSettings Settings for xcodebuild -exportArchive.
| Member | Signature | Doc |
|---|---|---|
archivePath | archivePath(path: PathLike): this | The .xcarchive to export (-archivePath); required. |
exportPath | exportPath(path: PathLike): this | The directory to write the export to (-exportPath); required. |
exportOptionsPlist | exportOptionsPlist(path: PathLike): this | The export options (-exportOptionsPlist); required. Write one with XcodebuildTasks.writeExportOptions. |
type XcodebuildPlainAction = analyze | build | build-for-testing | clean | -resolvePackageDependencies An xcodebuild action that takes no flags of its own.
class XcodebuildProjectSettings extends XcodebuildSettings The project flags every build action takes. Each action names itself and its own flags; the project flags come first, then the action, then the build settings.
| Member | Signature | Doc |
|---|---|---|
workspace | workspace(path: PathLike): this | The workspace to build, e.g. App.xcworkspace (-workspace). |
project | project(path: PathLike): this | The project to build, e.g. App.xcodeproj (-project). |
scheme | scheme(name: string): this | The scheme to build (-scheme); required with a workspace. A later call replaces it. |
configuration | configuration(name: string): this | The build configuration, e.g. Release (-configuration). A later call replaces it. |
sdk | sdk(name: string): this | The SDK, e.g. iphoneos or iphonesimulator (-sdk). A later call replaces it. |
destination | destination(specifier: string): this | A destination, e.g. generic/platform=iOS or platform=iOS Simulator,name=iPhone 16 (-destination); repeatable. |
derivedDataPath | derivedDataPath(path: PathLike): this | Where intermediate build files go (-derivedDataPath). |
clonedSourcePackagesDirPath | clonedSourcePackagesDirPath(path: PathLike): this | Where Swift packages are checked out (-clonedSourcePackagesDirPath). |
resultBundlePath | resultBundlePath(path: PathLike): this | Write an .xcresult bundle with the logs and results (-resultBundlePath). |
xcconfig | xcconfig(path: PathLike): this | Apply an .xcconfig file's settings over every target (-xcconfig). |
buildSetting | buildSetting(name: string, value: string): this | Override a build setting for every target, e.g. ("DEVELOPMENT_TEAM", "ABCDE12345") → DEVELOPMENT_TEAM=ABCDE12345; repeatable. A condition goes in the name: CODE_SIGN_IDENTITY[sdk=iphoneos*]. |
class XcodebuildSettings extends ToolSettings Base for all xcodebuild settings: the binary is xcodebuild, on PATH.
| Member | Signature | Doc |
|---|---|---|
quietOutput | quietOutput(): this | Print only warnings and errors (-quiet). |
allowProvisioningUpdates | allowProvisioningUpdates(): this | Let Xcode create and update provisioning profiles and certificates (-allowProvisioningUpdates); on CI, pair it with authenticationKey. |
authenticationKey | authenticationKey(path: PathLike, keyId: string, issuerId: string): this | Sign in to the developer account with an App Store Connect API key instead of an Xcode account: the AuthKey_<id>.p8 file, its key id and its issuer id (-authenticationKeyPath, -authenticationKeyID, -authenticationKeyIssuerID). |
class XcodebuildShowBuildSettings extends XcodebuildProjectSettings Settings for xcodebuild -showBuildSettings.
| Member | Signature | Doc |
|---|---|---|
json | json(): this | Print the settings as JSON (-json). |
const XcodebuildTasks: XcodebuildTasksApi Typed task functions for xcodebuild.
interface XcodebuildTasksApi The shape of XcodebuildTasks.
| Member | Signature | Doc |
|---|---|---|
archive | archive(configure: Configure<XcodebuildArchiveSettings>): Promise<CommandOutput> | Build an .xcarchive: xcodebuild archive. |
exportArchive | exportArchive(configure: Configure<XcodebuildExportArchiveSettings>): Promise<CommandOutput> | Export an archive to an .ipa, or upload it: xcodebuild -exportArchive. |
showBuildSettings | showBuildSettings(configure?: Configure<XcodebuildShowBuildSettings>): Promise<CommandOutput> | Print the resolved build settings: xcodebuild -showBuildSettings. |
writeExportOptions | writeExportOptions(path: PathLike, configure: Configure<ExportOptionsSettings>): Promise<void> | Write an ExportOptions.plist for exportArchive to path. Runs no subprocess. |
build | build: XcodebuildActionTask | Build a scheme: xcodebuild build. |
clean | clean: XcodebuildActionTask | Remove build products: xcodebuild clean. |
analyze | analyze: XcodebuildActionTask | Run the static analyzer: xcodebuild analyze. |
buildForTesting | buildForTesting: XcodebuildActionTask | Build for a later test run: xcodebuild build-for-testing. |
resolvePackageDependencies | resolvePackageDependencies: XcodebuildActionTask | Resolve Swift package dependencies: xcodebuild -resolvePackageDependencies. |
test | test: XcodebuildTestTask | Build and run the tests: xcodebuild test. |
testWithoutBuilding | testWithoutBuilding: XcodebuildTestTask | Run tests already built: xcodebuild test-without-building. |
type XcodebuildTestAction = test | test-without-building An xcodebuild action that runs tests.
class XcodebuildTestSettings extends XcodebuildProjectSettings Settings for xcodebuild test and test-without-building.
| Member | Signature | Doc |
|---|---|---|
xctestrun | xctestrun(path: PathLike): this | Run the tests a build-for-testing run described, from its .xctestrun file (-xctestrun), instead of a scheme — the usual way to run test-without-building. |
testPlan | testPlan(name: string): this | The test plan to run (-testPlan). |
onlyTesting | onlyTesting(identifier: string): this | Run only this test target, class or method, e.g. AppTests/LoginTests (-only-testing); repeatable. |
skipTesting | skipTesting(identifier: string): this | Skip this test target, class or method (-skip-testing); repeatable. |
enableCodeCoverage | enableCodeCoverage(enabled?: boolean): this | Turn code coverage on or off (-enableCodeCoverage YES|NO). |
parallelTestingEnabled | parallelTestingEnabled(enabled?: boolean): this | Turn parallel testing on or off (-parallel-testing-enabled YES|NO). |
retryTestsOnFailure | retryTestsOnFailure(): this | Re-run a failed test until it passes, up to the iteration limit (-retry-tests-on-failure). |
testIterations | testIterations(count: number): this | How many times to run each test (-test-iterations). |
type XcodebuildTestTask = unknown A task that runs an xcodebuild test action.