GitHub Actions
This guide releases to Aether from GitHub Actions using the aetherpush-deploy-action. The action installs a pinned CLI, logs in, and runs the release for you.
Before you start, create a deploy-scoped API key as described in Prerequisites.
Store the API key
Section titled “Store the API key”Add the key as an encrypted secret:
- Open your repository’s Settings → Secrets and variables → Actions.
- Add a secret named
AETHER_ACCESS_KEYwith the value of an API key created in the dashboard.
For the production gate below, you can instead scope the secret to a GitHub Environment (Settings → Environments). A job that names that environment reads the environment’s secret. Repository secrets are simpler to set up; environment secrets let you require approval and restrict which branches can deploy.
Pin the action version
Section titled “Pin the action version”Reference the action by an exact tag, not a branch:
- uses: Monoradioactivo/aetherpush-deploy-action@v0.4.1While the action is on a 0.x release, input and output names can change between versions, so pin the exact tag. Pinning the tag also pins the CLI: v0.4.1 installs a fixed @aetherpush/cli version, so you do not pin the CLI separately in the workflow.
Staging on merge, production behind a gate
Section titled “Staging on merge, production behind a gate”This workflow releases to Staging on every merge to main, then waits for approval before releasing to Production.
name: OTA releaseon: push: branches: [main]
jobs: staging: runs-on: ubuntu-latest environment: staging steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - uses: Monoradioactivo/aetherpush-deploy-action@v0.4.1 with: access-key: ${{ secrets.AETHER_ACCESS_KEY }} app-name: my-react-native-app command: release-react platform: android deployment-name: Staging rollout: 100%
production: needs: staging runs-on: ubuntu-latest environment: production steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - uses: Monoradioactivo/aetherpush-deploy-action@v0.4.1 with: access-key: ${{ secrets.AETHER_ACCESS_KEY }} app-name: my-react-native-app command: release-react platform: android deployment-name: Production rollout: 25%Replace app-name and platform with your app’s values. For release-react, the action reads the target binary version from your native project; pass target-binary-version to set it explicitly.
Wire up the manual gate
Section titled “Wire up the manual gate”The production job names environment: production. That is what turns it into a gate:
- Open Settings → Environments and create an environment named
production. - Enable Required reviewers and add the people who approve releases.
GitHub then pauses the run after staging succeeds and before production starts, until a reviewer approves. Because production declares needs: staging, a failed staging release also blocks production.
Choosing the server
Section titled “Choosing the server”Leave api-url unset to release against Aether’s production server. Set it only to target another server, for example api-url: https://api-staging.aetherpush.com for Aether staging. This is separate from the Staging deployment channel, which is a channel on the same production server.
Step outputs
Section titled “Step outputs”The action maps the CLI --json object to step outputs that carry release metadata. The bundle’s signed download URL is not one of them. That URL stays valid for seven days and no single link can be revoked, while a step output reaches the job log whenever step debug logging is on and travels into every job that reads it.
status is success when the CLI printed a release object, and also when no-duplicate-release-error is true and the CLI printed no JSON. That second case is a swallowed 409: identical package, or an unfinished rollout. The other metadata outputs stay empty then. Put id: release on the action step and gate later steps with if: steps.release.outputs.label != ''. A job that uses needs: must pass label through that job’s outputs map; steps is not visible across jobs. The CLI warning in the log names the 409.
The action writes release.json in the job workspace to do the mapping, then deletes the signed URL fields from the file. A later step in the same job reads release metadata rather than download links. The action does not upload that file. Do not add actions/upload-artifact for it either. On a swallowed 409 the file may be empty or a non-JSON last line; do not parse it unless label is set.
Keep this guide in sync
Section titled “Keep this guide in sync”The action is maintained in the aetherpush-deploy-action repository (action.yml and its README). When its inputs or pinned CLI change, update this guide to match. The action repository is the source of truth.