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
-
Create a release pipeline in Linear and copy its access key. See Linear's documentation for the exact flow.
-
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: truekeeps the.gitdirectory solinear-releasecan read commit history.git/cloneperforms a shallow fetch by default, which is fine —linear-releasewill progressively deepen the clone (or rungit fetch --unshallow) if the previous release's commit isn't already in the local history.- If you are using
arm64base images, you will need to use thelinear-release-linux-arm64binary. - By installing the CLI in a separate task, the installation will be cached and reused across runs.
- RWX automatically merges
$PATHacrossusedependencies, so any task that depends onlinear-release-clican calllinear-releaseby name. See environment variables for details. - Using
afteron thelinear-releasetask means it only runs whendeploysucceeds — 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.
The following examples assume you've configured a scheduled pipeline in Linear
— passing --release-version explicitly is recommended in CI to avoid
ambiguity when releases overlap, but if you don't have overlapping releases
and don't know your release version until later, you can omit
--release-version.
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.