> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sparkles.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Release and deploy the CLI

> Maintain signed CLI release channels, recover failed publication, and deploy Mintlify documentation.

This page is for Sparkles maintainers shipping the CLI and its documentation.

## Current v1.3.0 channels

| Channel              | Status                                                                  |
| -------------------- | ----------------------------------------------------------------------- |
| GitHub release       | Published with signed and notarized macOS archives                      |
| Standalone installer | Published through `https://sparkles.dev/install`                        |
| Homebrew             | Published through `sparklesdotdev/tap/sparkles`                         |
| npm                  | v1.3.0 published; its immutable macOS platform package predates signing |

The signed build identifies commit `ead2e9b06711a50b0920cc379f69f8133bb0bc67`. The release assets are available from [GitHub release v1.3.0](https://github.com/sparklesdotdev/cli/releases/tag/v1.3.0).

## Automated release sequence

1. Merge Conventional Commits into the CLI repository's `main` branch.
2. Merge the Release Please pull request to create the version tag and GitHub release.
3. Build all platform archives.
4. Sign and notarize both macOS architectures before creating the immutable release bundle.
5. Publish the exact bundle to GitHub Releases and versioned Cloudflare R2 paths.
6. Publish the npm platform packages and shim under a staging tag.
7. Update Homebrew.
8. Move npm `latest` and the stable installer pointer only after every channel succeeds.

Never publish the npm shim before its platform packages. npm versions are immutable, so an unsigned or incomplete package must be replaced by a new version rather than overwritten.

## GitHub release environment

The CLI repository uses the GitHub environment named `release`.

### Secrets

* `AWS_ACCESS_KEY_ID`
* `AWS_SECRET_ACCESS_KEY`
* `MACOS_SIGN_P12`
* `MACOS_SIGN_PASSWORD`
* `MACOS_NOTARY_KEY`
* `MACOS_NOTARY_KEY_ID`
* `MACOS_NOTARY_ISSUER_ID`
* `NPM_TOKEN`
* `HOMEBREW_TAP_TOKEN`

### Variables

* `AWS_ENDPOINT_URL`
* `R2_BUCKET`

Create the R2 S3 credentials in Cloudflare under **R2 object storage → Manage API Tokens**. Grant Object Read & Write access only to the release bucket, then copy the one-time Access Key ID and Secret Access Key into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` secrets. Cloudflare shows an account-specific S3 endpoint alongside those credentials; copy it into the `AWS_ENDPOINT_URL` variable, and set `R2_BUCKET` to the release bucket name. See [Cloudflare's S3 credential guide](https://developers.cloudflare.com/r2/get-started/s3/).

## Recover a failed release

Use GitHub's failed-job retry while the original workflow still has its artifacts. If a full rerun loses the artifact, dispatch the Release workflow with the existing `v*` tag so it can recover from the immutable signed bundle attached to the release.

If signing and notarization pass but publication fails:

1. Download the release bundle artifact.
2. Verify every archive against `checksums.txt`.
3. Extract both macOS archives and verify each extracted binary by path, such as `codesign --verify --deep --strict ./sparkles`. `codesign` requires an explicit target and fails when it is omitted.
4. Publish the same bytes to the GitHub release and versioned R2 path.
5. Download the public objects and compare them with the bundle before moving the stable pointer.

A local Wrangler login can recover an individual release, but it does not replace `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in GitHub Actions. Add the S3 credentials so the next release completes automatically.

## Protect and rotate Apple credentials

Never send `.p12` certificates, `.p8` keys, or export passwords through chat, tickets, source control, or documentation. Put them directly into the GitHub `release` environment.

If an App Store Connect API key is exposed, revoke it and create a replacement. Apple recommends revoking lost or compromised keys immediately. See [Revoking API keys](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys).

Treat a possible Developer ID key compromise as an incident rather than a rotation. If a private key or an exported `.p12` may have reached anyone outside the release owners, remove its CI access immediately by deleting `MACOS_SIGN_P12` and `MACOS_SIGN_PASSWORD` from the `release` environment, and contact Apple Product Security right away: whoever holds that identity can distribute software as Sparkles until it is revoked. Revocation blocks installation and launch of every build already signed with that certificate, so tell users which versions stop working and create, sign, and ship the replacement release in parallel instead of waiting for it before acting.

For routine rotation of a certificate that is not compromised, do not revoke it before a replacement-signed release is live. Apple states that software signed with a revoked Developer ID certificate can no longer be installed or launched. Create a replacement certificate, update the GitHub signing secrets, ship a new release, and then contact Apple about revoking the old certificate. See [Revoking Developer ID privileges](https://developer.apple.com/help/account/reference/revoking-privileges).

## Deploy the Mintlify docs

The Mintlify project root is `docs/api`. Validate changes from the application repository root:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
bun run docs:validate
bun run docs:links
```

The Mintlify GitHub integration watches `/docs/api` and deploys changes after they merge into `main`. A docs-only change does not require `bun run deploy`, a Cloudflare Worker deployment, or a CLI release.
