CI automation with GitHub Actions
This workflow builds your app, uploads a new bundle with the CLI, and can release it to a channel when you set one variable.
1) Add repository secrets and variables
GitHub repository secrets (required):
OTAKIT_SECRET_KEY=otakit_sk_... OTAKIT_APP_ID=app_... OTAKIT_SERVER_URL=https://your-otakit.example.com # optional, only for self-hosted
GitHub repository variables (optional):
OTAKIT_BUILD_DIR=out # only if not in capacitor.config.ts webDir OTAKIT_RELEASE_CHANNEL=staging # if empty/unset: upload only (no release)
2) Copy this workflow
Create file .github/workflows/otakit.yml:
name: OTA upload
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
upload:
runs-on: ubuntu-latest
env:
OTAKIT_SECRET_KEY: ${{ secrets.OTAKIT_SECRET_KEY }}
OTAKIT_APP_ID: ${{ secrets.OTAKIT_APP_ID }}
OTAKIT_SERVER_URL: ${{ secrets.OTAKIT_SERVER_URL }}
OTAKIT_BUILD_DIR: ${{ vars.OTAKIT_BUILD_DIR }}
OTAKIT_RELEASE_CHANNEL: ${{ vars.OTAKIT_RELEASE_CHANNEL }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- name: Upload bundle (and optionally release)
run: |
BASE_VERSION="$(node -p "require('./package.json').version")"
OTA_VERSION="${BASE_VERSION}+${GITHUB_RUN_NUMBER}.${GITHUB_SHA::7}"
if [ -n "$OTAKIT_RELEASE_CHANNEL" ]; then
npx --yes @otakit/cli@latest upload --version "$OTA_VERSION" --channel "$OTAKIT_RELEASE_CHANNEL"
else
npx --yes @otakit/cli@latest upload --version "$OTA_VERSION"
fiBest practices
- Pin CLI version after first successful run (replace
@latestwith a fixed version). - Use
stagingfor auto-release and promote to production after validation. - Keep
OTAKIT_RELEASE_CHANNELunset if you want upload-only CI and release manually later. - Use branch protection so OTA uploads only run from trusted branches.
Related docs: CLI reference and channels and update mode.