Track Linear Releases from RWX

Linear's linear-release CLI connects your CI/CD pipeline to Linear's release management. It scans commits for Linear issue identifiers and pull request references, then creates or updates a release in Linear and links the matching issues to it.

This guide shows how to run linear-release from an RWX run for both pipeline styles supported by Linear:

  • Continuous pipelines create a completed release on every deploy.
  • Scheduled pipelines collect changes into an in-progress release, move it through stages (e.g. code freeze, qa), and complete it when the release ships.

Prerequisites

  1. Create a release pipeline in Linear and copy its access key. See Linear's documentation for the exact flow.

  2. Store the access key as a secret in an RWX vault. For example, in the default vault:

    rwx vaults secrets set linear-access-key=lin_pipeline_...
    

    You'll reference it from a run as ${{ secrets.linear-access-key }}.

Continuous pipeline

For a continuous pipeline, run linear-release sync after a successful deploy. Each run creates a new completed release named after the short commit SHA by default.

This example runs on every push to GitHub, after a hypothetical deploy task succeeds:

on:
  github:
    push:
      init:
        commit-sha: ${{ event.git.sha }}

base:
  image: ubuntu:24.04
  config: rwx/base 1.0.2

tasks:
  - key: code
    call: git/clone 2.0.7
    with:
      repository: https://github.com/YOUR-ORG/YOUR-REPO.git
      ref: ${{ init.commit-sha }}
      github-token: ${{ github.token }}
      preserve-git-dir: true

  - key: deploy
    use: code
    run: ./bin/deploy

  - key: linear-release-cli
    run: |
      mkdir -p bin
      curl -fsSL \
        https://github.com/linear/linear-release/releases/latest/download/linear-release-linux-x64 \
        -o bin/linear-release
      chmod +x bin/linear-release
      echo "$PWD/bin" > $RWX_ENV/PATH

  - key: linear-release
    use: [code, linear-release-cli]
    after: deploy
    run: linear-release sync
    env:
      LINEAR_ACCESS_KEY: ${{ secrets.linear-access-key }}

A few things worth noting:

  • preserve-git-dir: true keeps the .git directory so linear-release can read commit history. git/clone performs a shallow fetch by default, which is fine — linear-release will progressively deepen the clone (or run git fetch --unshallow) if the previous release's commit isn't already in the local history.
  • If you are using arm64 base images, you will need to use the linear-release-linux-arm64 binary.
  • By installing the CLI in a separate task, the installation will be cached and reused across runs.
  • RWX automatically merges $PATH across use dependencies, so any task that depends on linear-release-cli can call linear-release by name. See environment variables for details.
  • Using after on the linear-release task means it only runs when deploy succeeds — you don't want to record a release that didn't actually ship.

Scheduled / staged pipelines

For a scheduled pipeline, an in-progress release accumulates issues over time, moves through one or more stages, and is eventually completed.

Sync issues into the in-progress release

Run on every merge to your default branch to add newly merged issues to the current release:

- key: linear-release
  use: [code, linear-release-cli]
  run: linear-release sync --release-version="${RELEASE_VERSION}"
  env:
    LINEAR_ACCESS_KEY: ${{ secrets.linear-access-key }}
    RELEASE_VERSION: ${{ init.release-version }}

Move the release between stages

When the release moves to a new stage — for example, when QA starts — run update:

- key: linear-release
  use: [code, linear-release-cli]
  run: linear-release update --release-version="${RELEASE_VERSION}" --stage="qa"
  env:
    LINEAR_ACCESS_KEY: ${{ secrets.linear-access-key }}
    RELEASE_VERSION: ${{ init.release-version }}

Complete the release

When the release ships, mark it complete:

- key: linear-release
  use: [code, linear-release-cli]
  run: linear-release complete --release-version="${RELEASE_VERSION}"
  env:
    LINEAR_ACCESS_KEY: ${{ secrets.linear-access-key }}
    RELEASE_VERSION: ${{ init.release-version }}

In all three cases, you'd typically wire the run up to whatever signals a stage transition in your environment — a successful deploy to staging, a manual dispatch trigger, a cron schedule for nightly cuts, and so on.

Reference