Elizon Docs
Guides & Walkthroughs

CI/CD

Validate and build Packages on every change, and sign releases, in GitHub Actions or any CI.

Every command is scriptable: --json gives one JSON document on stdout, exit codes separate "fix the Package" (1) from "the tool broke" (2), and nothing prompts when there's no terminal.

Validate and build on every pull request

These need no secrets and no network beyond fetching the CLI.

.github/workflows/package.yml
name: Package
on:
  pull_request:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
      - name: Read the pinned CLI version
        id: cli
        run: echo "version=$(sed -n 's/^cliVersion: *//p' .elizon/config.yaml)" >> "$GITHUB_OUTPUT"
      - name: Validate
        run: npx --yes @elizon/cli@${{ steps.cli.outputs.version }} validate --json > validate.json
      - name: Build
        run: npx --yes @elizon/cli@${{ steps.cli.outputs.version }} build --out=package.pkg --json > build.json
      - uses: actions/upload-artifact@v4
        with:
          name: unsigned-package
          path: package.pkg
  • Always run the pinned version from .elizon/config.yaml; build refuses any other.
  • npx --yes skips npm's install confirmation in non-interactive environments.
  • On failure, validate.json holds every error with its path, code and hint. Print it, or post it as a review comment.
  • Builds are reproducible: the same commit and CLI version produce the same bytes, so a later signing job signs exactly what CI built.

Signing in CI

Signing needs a connected device, which is created by a person approving it in a browser. For CI:

  1. On a trusted machine, outside any Package project, connect a device as a dedicated user whose role allows signing (Owner, Admin or Editor). ELIZON_CONFIG_HOME puts its credential in a separate folder:

    ELIZON_CONFIG_HOME="$HOME/elizon-ci" npx @elizon/cli@<version> target add <your-elizon-address> --name=release --default
  2. Store the resulting $HOME/elizon-ci/targets.json as an encrypted CI secret, then delete the local copy.

  3. In the release job, restore it outside the checkout and point ELIZON_CONFIG_HOME at it:

    - name: Restore signing device
      run: |
        mkdir -p "$RUNNER_TEMP/elizon-home"
        echo "$ELIZON_TARGETS" > "$RUNNER_TEMP/elizon-home/targets.json"
        chmod 600 "$RUNNER_TEMP/elizon-home/targets.json"
      env:
        ELIZON_TARGETS: ${{ secrets.ELIZON_TARGETS_JSON }}
    - name: Sign
      run: npx --yes @elizon/cli@${{ steps.cli.outputs.version }} sign package.pkg --target=release --yes --json
      env:
        ELIZON_CONFIG_HOME: ${{ runner.temp }}/elizon-home
  • The credential store must be outside the project directory; the CLI refuses otherwise (CLI_TARGET_STORE_UNSAFE).
  • Device tokens last 30 days. Plan to reconnect the device, and revoke it in Settings → CLI Devices when it's no longer needed.
  • CLI_TARGET_TOKEN_REJECTED means reconnect; CLI_TARGET_FORBIDDEN means the CI user's role doesn't allow signing.

A device token acts with its user's full role in that Organization. Use a dedicated user with no more access than signing needs, and treat the stored file like any other deployment credential.

Installing from CI

install --non-interactive fails with every missing item in one message rather than prompting. Supply each Slot with --slot.<id>=… (credentials as {{secret.KEY}} references to Secrets that already exist in the target Organization). See install.

Add --activate to make the Package live in the same run. A job can't prompt, so a Package with an evaluation suite also needs --acknowledge-evaluation, which records that the results the job prints were accepted. Treat that flag as a decision someone made about this Package, not a default, and keep the job's output. See Activating.