Summary
We run two continuous pipelines (staging + production) via linear-release-action. Most
releases end up with zero linked issues, although the identifiers are in the commit
message — one line below where the CLI looks. Both detectors needed already exist; they
are scoped to the subject line only.
Our release process
- Feature branches are squash-merged into an integration branch. Subjects carry the
identifier, e.g. ENG-123 fix: <title> (#12).
- Periodically the integration branch is squash-merged into
main as a single release PR,
producing one commit with the subject Release (#99).
- Staging deploys from
main; the scanned HEAD is that squash commit.
- Production is cut from a GitHub release. By the time the release job runs, HEAD is an
automated bump version to <x> [skip ci] commit created by our build.
- The repo uses GitHub's defaults, including
squash_merge_commit_message: COMMIT_MESSAGES.
Where it breaks
Staging — correct range, nothing linked:
Found 2 commits between <sha> and <sha>
Synced to release <name>: pull requests [#99], links [CI]
#99 is the release PR. No issues are linked to it, so the PR reference resolves to
nothing and the dozens of squashed commits stay invisible.
Production — HEAD is the version bump:
Inspected current commit <sha>; found 1 commit
Synced to release <name>: no new issues or pull requests, links [...]
The data is already in the message
With GitHub's default squash message, the body is a list of the original subjects:
* ENG-123 fix: <title> (#12)
* ENG-124 feat: <title> (#13)
Each line carries both signals the CLI already understands: an identifier in the
ENG-123 subject form matched by COMMON_SUBJECT_PATTERNS, and a trailing (#N) matched
by the GitHub squash regex — and those PRs are linked to the issues. Both are dropped
because these detectors run against getCommitSubject(message).
We understand the reasoning behind the subject-only scoping and stripSquashBlock():
avoiding attribution of already-shipped work. Worth noting for the GitHub squash case
specifically — the body lists only commits unique to the head branch, i.e. exactly the new
work in that release.
What we had to build
Two workarounds we would happily delete:
- A script deriving the previous GitHub release tag via API and passing it as
base_ref,
so a production release scans a real range instead of a single version-bump commit.
- A shim that parses identifiers out of commit bodies and creates throwaway local branches
named after them, pointing at those commits, purely to trigger branch-ref detection.
This is a hack against an implementation detail and not something users should need.
What would make the stock action work for us
- Opt-in body scanning for squash commits, e.g.
--scan-squash-body: run
COMMON_SUBJECT_PATTERNS and (#N) extraction per body line. For us, either one alone
would resolve every missing issue. A smaller variant that would also unblock us: let
--issue-pattern target the full message, e.g. --issue-pattern-scope=subject|message.
Today it is documented as subject-only, so it cannot reach this data.
- A first-class scan base for release-event pipelines, e.g.
base_ref: previous-release-tag. base_ref already exists and works well — the gap is
that every "GitHub release publishes production" setup has to script the same lookup,
and without it the first sync degrades to HEAD only.
- Alternative to (1): resolve issues from the PRs contained in an already-detected
release PR, server-side, without any commit message parsing.
Environment
linear/linear-release-action pinned to v0.17.2, CLI v0.17.2
- GitHub Actions,
ubuntu-24.04, actions/checkout@v4 with fetch-depth: 0
- Two continuous pipelines, GitHub provider
Summary
We run two continuous pipelines (staging + production) via
linear-release-action. Mostreleases end up with zero linked issues, although the identifiers are in the commit
message — one line below where the CLI looks. Both detectors needed already exist; they
are scoped to the subject line only.
Our release process
identifier, e.g.
ENG-123 fix: <title> (#12).mainas a single release PR,producing one commit with the subject
Release (#99).main; the scanned HEAD is that squash commit.automated
bump version to <x> [skip ci]commit created by our build.squash_merge_commit_message: COMMIT_MESSAGES.Where it breaks
Staging — correct range, nothing linked:
#99is the release PR. No issues are linked to it, so the PR reference resolves tonothing and the dozens of squashed commits stay invisible.
Production — HEAD is the version bump:
The data is already in the message
With GitHub's default squash message, the body is a list of the original subjects:
Each line carries both signals the CLI already understands: an identifier in the
ENG-123 subjectform matched byCOMMON_SUBJECT_PATTERNS, and a trailing(#N)matchedby the GitHub squash regex — and those PRs are linked to the issues. Both are dropped
because these detectors run against
getCommitSubject(message).We understand the reasoning behind the subject-only scoping and
stripSquashBlock():avoiding attribution of already-shipped work. Worth noting for the GitHub squash case
specifically — the body lists only commits unique to the head branch, i.e. exactly the new
work in that release.
What we had to build
Two workarounds we would happily delete:
base_ref,so a production release scans a real range instead of a single version-bump commit.
named after them, pointing at those commits, purely to trigger branch-ref detection.
This is a hack against an implementation detail and not something users should need.
What would make the stock action work for us
--scan-squash-body: runCOMMON_SUBJECT_PATTERNSand(#N)extraction per body line. For us, either one alonewould resolve every missing issue. A smaller variant that would also unblock us: let
--issue-patterntarget the full message, e.g.--issue-pattern-scope=subject|message.Today it is documented as subject-only, so it cannot reach this data.
base_ref: previous-release-tag.base_refalready exists and works well — the gap isthat every "GitHub release publishes production" setup has to script the same lookup,
and without it the first sync degrades to HEAD only.
release PR, server-side, without any commit message parsing.
Environment
linear/linear-release-actionpinned to v0.17.2, CLI v0.17.2ubuntu-24.04,actions/checkout@v4withfetch-depth: 0