# Tokens and CI

Configure identity, targets and build tools to automate the release you already verified locally.

## Verify a local release first {#before}

CI automates [the first-release workflow](/docs/publish). Verify the same baseline, bundle command and targets locally before adding automation so build and authentication issues are not mixed.

## Create a publishing token {#what-is-api-key}

Open **API Key** in the console sidebar (`/settings/tokens`). Select the required permissions, application scope and expiration. The full value appears once; save it directly to CI Secrets.

A token is constrained by its selected permissions and application scope, not equivalent to an unrestricted account session. The CLI reads `PAKTA_API_TOKEN` and sends `x-api-token`; interactive login uses a session token. The SDK uses only the public appKey.

## Prepare release configuration {#configuration}

Commit the app's `package.json`, lockfile, `update.json` containing public identifiers only, and `targets.json`. Generate update.json locally with `selectApp`; do not rely on selection prompts in CI.

```json title="targets.json · replace with verified production targets"
[
  { "channel": "default", "packageVersion": "1.0.0", "rollout": 10 }
]
```

Match the local Node, Metro/Hermes and platform dependencies. Choose a runner capable of the same commands for iOS, HarmonyOS or custom Android builds; a generic Linux image is not always enough.

## GitHub Actions example {#ci}

This is a **steps fragment for an existing job**, not a complete workflow. It assumes checkout, Node and the required toolchain are configured, the working directory is the app root, and the CLI is installed at the same version used locally:

```yaml title="Steps in your existing workflow"
- name: Install locked dependencies
  run: |
    npm ci
    npm install -g rn-update-cli@1.1.0

- name: Verify identity and targets
  env:
    PAKTA_API_TOKEN: ${{ secrets.PAKTA_API_TOKEN }}
    NO_INTERACTIVE: 'true'
  run: |
    pakta me
    pakta publish .pakta/output/android.ppk --platform android --name "$GITHUB_RUN_ID" --targets targets.json --dryRun --no-interactive

- name: Bundle and publish
  env:
    PAKTA_API_TOKEN: ${{ secrets.PAKTA_API_TOKEN }}
    NO_INTERACTIVE: 'true'
  run: |
    pakta bundle --platform android --output .pakta/output/android.ppk --no-interactive
    pakta publish .pakta/output/android.ppk --platform android --name "$GITHUB_RUN_ID" --targets targets.json --sourcemap .pakta/intermedia/android/index.bundlejs.map --no-interactive
```

The run blocks use Bash. Add `--expo` to bundling for Expo; keep custom sourcemap paths consistent. For self-hosting, add your `RNU_SERVICE_URL` to both steps' environment.

## Non-interactive release and recovery {#non-interactive}

- Explicitly provide `--targets`, a native `--packageId`, or `--packageVersion` instead of selection prompts.
- `--dryRun` does not upload, create channels or publish; it is not a successful release.
- Retain the returned update-package `packageId` and all `deploymentIds`. If a failure supplies retryable deployment IDs, resume those exact targets:

```bash
pakta publish --deploymentIds DEPLOYMENT_ID_1,DEPLOYMENT_ID_2 --platform android --no-interactive
```

Replace the placeholder IDs; do not guess unrelated drafts. Serialize deployments by application and target so parallel jobs do not replace each other. Archive the package, map, commit and publishing output from the same build.

## Completion check {#verify}

The pipeline exits successfully, the console shows the expected active targets, and a matching device activates and confirms health. Upload completion alone is insufficient; verify in [analytics](/docs/analytics).

## Token maintenance {#security}

Issue a separate token per pipeline; revoke unused tokens and rotate before expiration. Inject through CI Secrets, never update.json, the app or logs. On authentication failure, check expiration, revocation, scope and permissions, then verify identity with `me`.

## Related reading {#related}

[CLI](/docs/cli) · [Channel publishing](/docs/channels) · [Production checklist](/docs/bestpractice).
