fastlane-plugin-hexsign adds four fastlane actions (two single-id and two bulk-filter) that shell out to the hexsign CLI. If you already have a fastlane lane that builds, signs, and ships, this is the smallest possible change: drop two lines in front of gym (or build_app) and you're off the Apple Developer portal.
Install
Add the plugin to your project's Pluginfile:
gem "fastlane-plugin-hexsign"
bundle install
The plugin shells out to the CLI rather than re-implementing the API, so the hexsign binary must be installed and on $PATH. On a developer laptop, brew install hexsign. In CI, use the Setup HexSign CLI GitHub Action or install from a release tarball.
Authentication
The CLI auto-detects machine mode when these env vars are set, so the plugin needs no separate auth configuration:
export HEXSIGN_CLIENT_ID=… export HEXSIGN_CLIENT_SECRET=…
Provision a service credential under Settings → CLI Tokens in the HexSign dashboard. The secret is shown exactly once. Store it as a CI secret immediately.
Actions
- hexsign_certificates_download
- Downloads one signing certificate by HexSign UUID (
.p12+ a sibling.passwordfile, both0600). Required option:id. Optional:output_dir,filename,keychain. - hexsign_profiles_download
- Downloads one provisioning profile by HexSign UUID (
.mobileprovision). Required option:id. Optional:output_dir,filename,install(macOS only; also copies the profile into the directory Xcode reads). - hexsign_certificates_download_by_type
- Downloads every signing certificate of a given Apple cert type (e.g.
DISTRIBUTION) for one Apple Developer team. Required options:type,team_id. Optional:output_dir,keychain. Returns an array of{ p12:, password: }hashes. Survives cert rotation; no UUID to update when a cert is renewed. - hexsign_profiles_download_by_bundle_id
- Downloads every provisioning profile linked to a bundle identifier. Required option:
bundle_id. Optional:team_id(scopes across linked Apple accounts),output_dir,install(macOS only; also copies each profile into the directory Xcode reads). Returns an array of absolute paths.
A typical lane (by id)
lane :beta do
hexsign_certificates_download(id: ENV["HEXSIGN_CERT_ID"], output_dir: "build/sign")
hexsign_profiles_download (id: ENV["HEXSIGN_PROFILE_ID"], output_dir: "build/sign")
import_certificate(
certificate_path: "build/sign/certificate.p12",
certificate_password: File.read("build/sign/certificate.password").strip,
keychain_name: "build.keychain"
)
gym(scheme: "MyApp")
endRotation-proof lane (by type + bundle id)
lane :beta do
pairs = hexsign_certificates_download_by_type(
type: "DISTRIBUTION",
team_id: ENV["HEXSIGN_TEAM_ID"],
output_dir: "build/sign"
)
hexsign_profiles_download_by_bundle_id(
bundle_id: "com.example.app",
team_id: ENV["HEXSIGN_TEAM_ID"],
output_dir: "build/sign"
)
pairs.each do |pair|
import_certificate(
certificate_path: pair[:p12],
certificate_password: File.read(pair[:password]).strip,
keychain_name: "build.keychain"
)
end
gym(scheme: "MyApp")
endCommon gotchas
hexsign: command not found. ThehexsignCLI isn't installed on the runner. Add a step that installs it beforebundle exec fastlane.401 invalid_client. Service credentials are wrong or revoked. Re-provision in the dashboard and update the CI secret.403 insufficient scope. The credential lackshexsign-api/read. Recreate it with the right scope set; HexSign does not edit scopes on existing credentials.