Files
apple-code-sign-action/README.md
Solomon 21e6f8327e Add parallel processing of inputs
Support processing multiple inputs in parallel to reduce CI time
2026-01-06 14:41:27 +00:00

172 lines
5.4 KiB
Markdown

# Apple Code Signing and Notarization Action
This action signs, notarizes, and/or staples Apple applications using the open source `rcodesign` tool from https://github.com/indygreg/apple-platform-rs/tree/main/apple-codesign.
This action can be run from Linux, Windows, and macOS Actions Runners.
This action is a thin veneer over downloading and invoking `rcodesign`.
Advanced customers may want to forego this action and invoke `rcodesign`
directly.
## Usage
You will likely want an Apple issued code signing certificate. See
https://gregoryszorc.com/docs/apple-codesign/stable/apple_codesign_certificate_management.html
for instructions on how to obtain one.
For notarizing, you will need an App Store Connect API Key. See
https://gregoryszorc.com/docs/apple-codesign/stable/apple_codesign_getting_started.html#obtaining-an-app-store-connect-api-key
for instructions on how to obtain one.
It is up to the caller to materialize a file/directory for
signing/notarizing/stapling.
It is up to the caller to do something with the file/directory operated on.
## Inputs and Outputs
See [action.yml](action.yml) for the set of inputs. The file should be
self-documenting.
The outputs are:
- `output_path`: filesystem path of the signed/notarized/stapled entity (or the
first path when multiple `input_path` values are provided).
- `output_paths`: newline-separated list of output paths when multiple
`input_path` values are provided.
## Examples
Ad-hoc signing.
```yaml
steps:
# Add a step here to materialize a Mach-O binary, bundle, DMG, etc
# that you want to sign.
- name: Sign an Application Bundle
uses: indygreg/apple-code-sign-action@v1
with:
input_path: MyApp.app
output_path: dist/MyApp.app
# MyApp.app should be signed, but without a code signing certificate.
```
Sign using a code signing certificate in a .p12/.pfx file.
```yaml
steps:
# Add a step here to materialize a Mach-O binary, bundle, DMG, etc
# that you want to sign.
- name: Sign a Mach-O binary
uses: indygreg/apple-code-sign-action@v1
with:
input_path: my-exe
p12_file: cert.p12
p12_password: ${{ secrets.certificate_password }}
```
Sign using a PEM encoded code signing certificate stored in a secret.
```yaml
steps:
- name: Write PEM encoded private key data to a file
env:
# The secret has content:
#
# ```
# -----BEGIN PRIVATE KEY-----
# MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkdCzwAgHcNbpH
# ...
# -----END PRIVATE KEY-----
# ```
#
# Because of the way GitHub Actions secrets are stored, the newlines likely
# get mangled to a single line. So we pipe to `tr` to translate whitespace
# to newlines to restore the original format.
SIGNING_KEY_PEM: ${{ secrets.SIGNING_KEY_PEM }}
run: |
echo $SIGNING_KEY_PEM | tr ' ' '\n' > key.pem
# We assume the `-----BEGIN PUBLIC CERTIFICATE------` exists in a file named
# `cert.pem`.
#
# The public certificate data is not a secret: the public certificate will be
# embedded in code signatures. So you can safely check this data into version
# control. You can also store it as a GitHub Secret: it doesn't really much
# matter how you do it as long as code signing sees both the private key and
# public certificate data.
- name: Sign a Mach-O binary
uses: indygreg/apple-code-sign-action@v1
with:
input_path: my-exe
pem_file: |
key.pem
cert.pem
```
Sign on a remote machine (requires running `rcodesign remote-sign` on another machine when this action is running).
```yaml
steps:
# Add a step here to materialize a Mach-O binary, bundle, DMG, etc
# that you want to sign.
- name: Sign a DMG
uses: indygreg/apple-code-sign-action@v1
with:
input_path: MyApp.dmg
remote_sign_public_key: |
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6GIrYnjZ3mbcAJjmmEm/
5jEp66vjs81MSt7AwVw381lteMoX9nzXVFuI4hwu7o41ZPuSqp+YvG90mMSVoTjy
m6O1tVoD7m8X0fLdfBegZN7sePlgS34s9Sj0fEvNVjrwFimfWQ1RNR+JNogufeKZ
IaePfb/hXBSbPxJrMVsCno6lUVuoFu2bJPMJUWxAsDhJLTyllJ5wzVc3MhzSL4OC
3B4SCgv/QKi8R7cYIZlJHXZAyghRAO2jpa7PHOfCmCb1tT1Cs50OQlpk9XBv2xGV
3r/2kqiG3Ay7cozX8V+oKZtzQHJQrqDVZNNXENcaPo7meoSCIdJhjd+leUI3iTLK
hwIDAQAB
```
Sign, notarize, and staple an app bundle.
```yaml
steps:
- name: Install App Store Connect API Key
run: |
mkdir -p private_keys/
echo '${{ secrets.app_store_connect_key }}' > private_keys/AuthKey_DEADBEEF.p12
- name: Sign and Notarize
uses: indygreg/apple-code-sign-action@v1
with:
input_path: MyApp.app
notarize: true
staple: true
p12_file: cert.p12
p12_password: ${{ secrets.certificate_password }}
# Find the issuer and key ID at https://appstoreconnect.apple.com/access/api.
# The `AuthKey_XXXXXX.12` file created above must have the same `api_key` value listed here.
app_store_connect_api_issuer: 'abcdef-42-2411312...'
app_store_connect_api_key: 'DEADBEEF'
```
Notarize multiple signed assets in parallel.
```yaml
steps:
# Add steps here to materialize signed assets (.app/.zip/.dmg/etc).
- name: Notarize (parallel)
uses: BloopAI/apple-code-sign-action@v1
with:
input_path: |
MyApp.zip
MyOtherApp.zip
sign: false
notarize: true
notarize_concurrency: 2
app_store_connect_api_key_json_file: app_store_key.json
```