Axonpack

CI

Publish every pull request as a preview with GitHub Actions, and remove it when the pull request closes.

The repository has a sample GitHub Actions workflow for each package manager. Copy the one that matches your app's lockfile into your app's .github/workflows/. They are not part of the npm package, so take them from GitHub:

LockfileFile to copy
bun.lockpreview.bun.yml
package-lock.jsonpreview.npm.yml
pnpm-lock.yamlpreview.pnpm.yml
yarn.lockpreview.yarn.yml

All four have the same jobs and triggers. Only the setup, install and run steps differ:

Package managerSetupInstallRun
bunoven-sh/setup-bunbun install --frozen-lockfilebunx preview
npmactions/setup-nodenpm cinpx preview
pnpmpnpm/action-setup, actions/setup-nodepnpm install --frozen-lockfilepnpm exec preview
yarnactions/setup-node, corepack enableyarn install --immutableyarn preview

The yarn file is for Yarn 2 and later. For Yarn 1, change the install to yarn install --frozen-lockfile. pnpm and yarn take their version from packageManager in your package.json.

What it does

The workflow runs on pull_request: opened, synchronize, reopened and closed. It can also be run by hand (see Run by hand).

publish runs on every event but closed:

  1. Checks out the pull request's own commit (not the merge commit), with the full history so the changelog can count commits from the base branch.

  2. Sets up the package manager and, for --environment, eas-cli with EXPO_TOKEN.

  3. Installs, then runs:

    preview publish --id "$PREVIEW_ID" --base "origin/$BASE_BRANCH" --platform "$PLATFORM" \
      ${EAS_ENVIRONMENT:+--environment "$EAS_ENVIRONMENT"}

    with the branch name as the id, the pull request's base branch for the changelog, all platforms, and --environment preview. The branch names go through env, not straight into the script, so a branch name can never run as shell code.

Pushing to the pull request publishes it again under the same id, so QA sees Update available.

unpublish runs on closed, merged or not, and runs preview unpublish "$PREVIEW_ID".

Run by hand

Each workflow also has a workflow_dispatch trigger, for publishing any branch, or removing a preview, without a pull request. Run it from your repository's Actions tab, as in GitHub's guide to running a workflow manually.

InputValuesMeaning
actionpublish (default), unpublishWhich job runs
idAny, optionalThe preview id. Empty means the branch the run was started on
platformall (default), android, iosWhich platforms to publish. Publish only
environmentpreview (default), or any EAS environment: development, production or a custom onePassed as --environment. Empty means no --environment

A dispatched publish checks out the branch the run was started on and counts the changelog from the repository's default branch. A pull request run always uses --environment preview. The inputs reach the script through env, like the branch names.

Secrets

Add these under your repository's Settings, Secrets and variables, Actions:

SecretNeeded
PREVIEW_S3_URLYes
PREVIEW_S3_ACCESS_KEY_IDYes, the write key
PREVIEW_S3_SECRET_ACCESS_KEYYes
PREVIEW_S3_REGIONNo. Default us-east-1
EXPO_TOKENOnly with --environment: an Expo access token, from your account settings on expo.dev

If your app keeps no variables on EAS, remove the expo/expo-github-action step, EXPO_TOKEN and EAS_ENVIRONMENT. Then give the job any EXPO_PUBLIC_* values the bundle needs as env, since a preview is built with what the CI job has. See A preview's own env values.

Pull requests from forks

GitHub gives no secrets to a workflow run from a fork's pull request, so it can't publish. The workflow works for branches in your own repository.

Unpublish on close (optional)

The unpublish job is optional. To keep previews after a pull request closes, do one of these in your copy of the workflow:

  • remove closed from the trigger's types (a dispatch can still unpublish)
  • delete the unpublish job
  • change the job's condition to if: false

The last two also turn off unpublishing by dispatch.

Then remove previews by hand with preview unpublish <id>, and delete the files no preview uses any more with preview prune.

Other CI systems

Nothing in the CLI is specific to GitHub. Any CI that can check out the branch with its history, install your dependencies and set the PREVIEW_S3_* variables can run the same two commands. On a detached HEAD there is no branch name, so pass --id yourself.

Next: Compatibility

On this page