Tokens and CI
Configure identity, targets and build tools to automate the release you already verified locally.
Updated 2026-09-14
On this page
Verify a local release first
CI automates the first-release workflow. Verify the same baseline, bundle command and targets locally before adding automation so build and authentication issues are not mixed.
Create a publishing token
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
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.
[
{ "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
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:
- 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-interactiveThe 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
Explicitly provide
--targets, a native--packageId, or--packageVersioninstead of selection prompts.--dryRundoes not upload, create channels or publish; it is not a successful release.Retain the returned update-package
packageIdand alldeploymentIds. If a failure supplies retryable deployment IDs, resume those exact targets:
pakta publish --deploymentIds DEPLOYMENT_ID_1,DEPLOYMENT_ID_2 --platform android --no-interactiveReplace 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
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.
Token maintenance
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.
