From c5941a3c8f562d7b953f26534d96a4d57d7713ed Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Fri, 23 Aug 2024 16:34:44 -0300 Subject: [PATCH] feat(cli): allow xcodebuild to manage iOS signing and provisioning Locally this can be done by adding your account in Xcode, but there's also env vars for configuring an App Store Connect API key particularly useful for CI usage This is a more convenient alternative to the IOS_CERTIFICATE, IOS_CERTIFICATE_PASSWORD and IOS_MOBILE_PROVISION env vars option (manual signing). --- .changes/provisioning-signing-ios.md | 7 +++++ tooling/cli/Cargo.lock | 4 +-- tooling/cli/Cargo.toml | 2 +- tooling/cli/ENVIRONMENT_VARIABLES.md | 4 +-- tooling/cli/src/mobile/ios/build.rs | 39 +++++++++++++++++++++++++--- 5 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 .changes/provisioning-signing-ios.md diff --git a/.changes/provisioning-signing-ios.md b/.changes/provisioning-signing-ios.md new file mode 100644 index 000000000000..6a8d48ae268b --- /dev/null +++ b/.changes/provisioning-signing-ios.md @@ -0,0 +1,7 @@ +--- +'tauri-cli': 'patch:feat' +'@tauri-apps/cli': 'patch:feat' +--- + +Allow Xcode to manage iOS code sign and provisioning profiles by default. +On CI, the `APPLE_API_KEY`, `APPLE_API_ISSUER` and `APPLE_API_KEY_PATH` environment variables must be provided for authentication. diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index a17c239e10cb..c5e634e53da6 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -557,9 +557,9 @@ dependencies = [ [[package]] name = "cargo-mobile2" -version = "0.13.5" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bd9e694230d442d680f8e578b4f252c67adbfd74cc1dd1caa9e1f1767114dc" +checksum = "b37140c84631f1a416fff6a3f898db7bda1a2643335fdf14e3d5eb5af61bf2e3" dependencies = [ "colored", "core-foundation 0.10.0", diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml index 0d3a32b00c28..a21daafe7efe 100644 --- a/tooling/cli/Cargo.toml +++ b/tooling/cli/Cargo.toml @@ -39,7 +39,7 @@ name = "cargo-tauri" path = "src/main.rs" [dependencies] -cargo-mobile2 = { version = "0.13.5", default-features = false } +cargo-mobile2 = { version = "0.14", default-features = false } jsonrpsee = { version = "0.24", features = [ "server" ] } jsonrpsee-core = "0.24" jsonrpsee-client-transport = { version = "0.24", features = [ "ws" ] } diff --git a/tooling/cli/ENVIRONMENT_VARIABLES.md b/tooling/cli/ENVIRONMENT_VARIABLES.md index b4e5bb4f7870..5ce3089eeecb 100644 --- a/tooling/cli/ENVIRONMENT_VARIABLES.md +++ b/tooling/cli/ENVIRONMENT_VARIABLES.md @@ -26,11 +26,11 @@ These environment variables are inputs to the CLI which may have an equivalent C - `APPLE_ID` — The Apple ID used to notarize the application. If this environment variable is provided, `APPLE_PASSWORD` and `APPLE_TEAM_ID` must also be set. Alternatively, `APPLE_API_KEY` and `APPLE_API_ISSUER` can be used to authenticate. - `APPLE_PASSWORD` — The Apple password used to authenticate for application notarization. Required if `APPLE_ID` is specified. An app-specific password can be used. Alternatively to entering the password in plaintext, it may also be specified using a '@keychain:' or '@env:' prefix followed by a keychain password item name or environment variable name. - `APPLE_TEAM_ID`: Developer team ID. To find your Team ID, go to the [Account](https://developer.apple.com/account) page on the Apple Developer website, and check your membership details. -- `APPLE_API_KEY` — Alternative to `APPLE_ID` and `APPLE_PASSWORD` for notarization authentication using JWT. +- `APPLE_API_KEY` — Alternative to `APPLE_ID` and `APPLE_PASSWORD` for notarization authentication using JWT. Also an option to allow automated iOS certificate and provisioning profile management. - See [creating API keys](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api) for more information. - `API_PRIVATE_KEYS_DIR` — Specify the directory where your AuthKey file is located. See `APPLE_API_KEY`. - `APPLE_API_ISSUER` — Issuer ID. Required if `APPLE_API_KEY` is specified. -- `APPLE_API_KEY_PATH` - path to the API key `.p8` file. If not specified, the bundler searches the following directories in sequence for a private key file with the name of 'AuthKey\_.p8': './private_keys', '~/private_keys', '~/.private_keys', and '~/.appstoreconnect/private_keys'. +- `APPLE_API_KEY_PATH` - path to the API key `.p8` file. If not specified, for macOS apps the bundler searches the following directories in sequence for a private key file with the name of 'AuthKey\_.p8': './private_keys', '~/private_keys', '~/.private_keys', and '~/.appstoreconnect/private_keys'. **For iOS this variable is required**. - `APPLE_SIGNING_IDENTITY` — The identity used to code sign. Overwrites `tauri.conf.json > bundle > macOS > signingIdentity`. If neither are set, it is inferred from `APPLE_CERTIFICATE` when provided. - `APPLE_PROVIDER_SHORT_NAME` — If your Apple ID is connected to multiple teams, you have to specify the provider short name of the team you want to use to notarize your app. Overwrites `tauri.conf.json > bundle > macOS > providerShortName`. - `APPLE_DEVELOPMENT_TEAM` — The team ID used to code sign on iOS. Overwrites `tauri.conf.json > bundle > iOS > developmentTeam`. Can be found in https://developer.apple.com/account#MembershipDetailsCard. diff --git a/tooling/cli/src/mobile/ios/build.rs b/tooling/cli/src/mobile/ios/build.rs index 5da719a75704..ee1107719caf 100644 --- a/tooling/cli/src/mobile/ios/build.rs +++ b/tooling/cli/src/mobile/ios/build.rs @@ -22,13 +22,20 @@ use clap::{ArgAction, Parser, ValueEnum}; use anyhow::Context; use cargo_mobile2::{ - apple::{config::Config as AppleConfig, target::Target}, + apple::{ + config::Config as AppleConfig, + target::{ExportConfig, Target}, + }, env::Env, opts::{NoiseLevel, Profile}, target::{call_for_targets_with_fallback, TargetInvalid, TargetTrait}, }; -use std::{env::set_current_dir, fs}; +use std::{ + env::{set_current_dir, var, var_os}, + fs, + path::PathBuf, +}; #[derive(Debug, Clone, Parser)] #[clap( @@ -294,7 +301,13 @@ fn run_build( target.build(config, env, NoiseLevel::FranklyQuitePedantic, profile)?; target.archive(config, env, noise_level, profile, Some(app_version))?; - target.export(config, env, noise_level)?; + + let mut export_config = ExportConfig::new().allow_provisioning_updates(); + if let Some(credentials) = auth_credentials_from_env()? { + export_config = export_config.authentication_credentials(credentials); + } + + target.export(config, env, noise_level, export_config)?; if let Ok(ipa_path) = config.ipa_path() { let out_dir = config.export_dir().join(target.arch); @@ -313,3 +326,23 @@ fn run_build( Ok(handle) } + +fn auth_credentials_from_env() -> Result> { + match ( + var("APPLE_API_KEY"), + var("APPLE_API_ISSUER"), + var_os("APPLE_API_KEY_PATH").map(PathBuf::from), + ) { + (Ok(key_id), Ok(key_issuer_id), Some(key_path)) => { + Ok(Some(cargo_mobile2::apple::target::AuthCredentials { + key_path, + key_id, + key_issuer_id, + })) + } + (Err(_), Err(_), None) => Ok(None), + _ => anyhow::bail!( + "APPLE_API_KEY, APPLE_API_ISSUER and APPLE_API_KEY_PATH must be provided for code signing" + ), + } +}