Skip to content

v0.10.0 sync silently skips release creation when latest tracked commit is on a diverged release branch #75

@alex-quilt

Description

@alex-quilt

Summary

In a workflow that uses both main (for minor cuts) and long-lived release branches (for patch cuts), linear-release sync (CLI v0.10.0) silently skips release creation on the next main cut, leaving the release entry absent. A subsequent update --stage=... call then fails with No release found with version "X.Y.Z" for pipeline "<uuid>".

The root cause is that the auto-detected base commit, after a release-branch patch sync, is no longer an ancestor of main HEAD. The ancestor walk appears to only consider the top 2 most-recent releases, so once enough patches have been synced from a release branch, the older main-line release falls out of the candidate window. sync then falls back to the "first-sync scan boundary," diffs HEAD..HEAD, finds 0 commits, and returns {"release":null} without creating the release.

There's no CLI flag (--from-commit, --base-commit, --previous-version, etc.) to override this.

Repro

Single Linear pipeline tracking a monorepo. Standard main + long-lived release branches workflow with patch-version increments — no pre-release / rc tags involved.

  1. On main at commit A, run sync --release-version=1.52.0. Linear creates release 1.52.0 with tracked commit A.
  2. Branch release/1.52 from A.
  3. Land a hotfix on release/1.52 at commit B (lives only on release/1.52; B is not an ancestor of future main). Run sync --release-version=1.52.1 from release/1.52. Linear creates release 1.52.1 with tracked commit B.
  4. (Optionally a 2nd hotfix at commit B2, synced as 1.52.2, etc.)
  5. Continue work on main. Weeks later, on main at commit C, run sync --release-version=1.53.0. A is an ancestor of C; B (and B2, ...) is not.

Expected: release 1.53.0 is created with commits between A (most recent main-ancestor release) and C.

Actual output:

=> Using custom release version: 1.53.0
=> No recent release is an ancestor of <C> (2 candidates considered); falling back to the first-sync scan boundary
=> Found 0 commits between <C> and <C>
=> No commits found matching [<include-paths>]. Skipping release creation.
{"release":null}

A follow-up update --release-version=1.53.0 --stage="<some stage>" then fails:

Error: Failed to update release: Not found - No release found with version "1.53.0" for pipeline "<uuid>".

This worked on CLI v0.7.0 (no ancestor check; it just created the release using whatever range it had).

Why this matters

The "main for minor cuts, branch for patches" pattern is common in long-lived monorepos (and is the only sane way to land a hotfix without dragging in everything that landed on main since the cut). Under v0.10.0, once one or two patch syncs from a release branch push the main-line release out of the 2-candidate ancestor window, the next minor sync from main fails open — and the next update call fails closed.

Requests

Any of these would fix it cleanly:

  1. Add a --from-commit / --base-commit / --previous-version flag so the caller can say "diff from <sha>" or "diff from release 1.52.0's commit." Lets the workflow be explicit and avoids the ancestor-check gamble.
  2. Walk further back when no recent release is an ancestor of HEAD — page through older releases until one matches, instead of stopping at 2.
  3. At minimum, don't silently skip release creation: if no candidate matches as an ancestor and the auto-detected range is empty, exit non-zero so the workflow surfaces the misconfiguration rather than failing on the next update step.

Happy to provide more context if useful.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions