Skip to content

fix: Harden WebGUI Linear release workflow#2647

Merged
elibosley merged 5 commits into
masterfrom
codex/webgui-linear-release-sync-review-fixes
May 22, 2026
Merged

fix: Harden WebGUI Linear release workflow#2647
elibosley merged 5 commits into
masterfrom
codex/webgui-linear-release-sync-review-fixes

Conversation

@elibosley
Copy link
Copy Markdown
Member

@elibosley elibosley commented May 22, 2026

Summary

  • Pins actions/checkout to the immutable commit currently referenced by v6.0.2.
  • Bounds the no-previous-tag path to TAG^..TAG when possible so the workflow does not scan full tag ancestry.
  • Restricts PR number extraction to explicit merge commit messages like Merge pull request #123, avoiding accidental issue references like (#123).
  • Adds Linear-side GitHub PR link resolution: discovered PR URLs are passed to the sync script, which resolves Linear attachments for those URLs and attaches the linked issues to the release.
  • Fixes manual workflow_dispatch testing against historical tags by checking out the workflow branch while still resolving the requested tag_name.
  • Carries active QA work across OS prereleases: internal tag sync now attaches active issues to the exact prerelease, the stable companion release, and the next planned prerelease. It removes next-prerelease membership only after the issue reaches an internal/completed state.
  • Sweeps existing issues already attached to the exact prerelease through the same policy, so tickets are carried forward even when they were not mentioned by the latest WebGUI tag diff.

Review Notes

  • Valid: mutable checkout tag. Fixed by pinning to de0fac2e4500dabe0009e67214ff5f5447ce83dd.
  • Valid: empty PREVIOUS_TAG range walked too much history. Fixed with parent-bounded range and a parentless fallback.
  • Valid: broad parenthetical PR extraction could treat issue references as PR numbers. Fixed by restricting extraction to Merge pull request #[0-9]+ while preserving numeric extraction, sort -u, and || true behavior.
  • Follow-up support: if the GitHub PR only links to Linear from the Linear side, attachmentsForURL now resolves the issue from the PR URL.
  • Manual test finding: checking out tag_name during workflow_dispatch failed for historical tags because the tag did not contain the new script. Fixed by checking out github.ref for manual runs.
  • Skipped: none. All reported findings applied to the current code.

Validation

  • git diff --check
  • node --check .github/scripts/sync-linear-release.mjs
  • ruby -e 'require "yaml"; YAML.load_file(".github/workflows/linear-release.yml"); puts "yaml ok"'
  • Shell probe confirmed PR extraction returns 2645 from Merge pull request #2645 ... and ignores parenthetical (#2646) / (#123) references.
  • Shell probe confirmed the first-tag fallback uses a single-commit style range such as 6.2.2^..6.2.2 when a parent exists.
  • Live Linear validation: attachmentsForURL(https://github.com/unraid/webgui/pull/2645) resolved OS-239, and the sync script attached OS-239 to 7.3.1-rc.0.3 without changing its QA Ready state.
  • Manual workflow test passed: https://github.com/unraid/webgui/actions/runs/26299583415 for tag_name=7.3.1-rc.0.3; it synced the existing Linear Release and attached OS-239 idempotently.
  • Local Linear validation after carry-forward change: OS-239 is QA Ready and attached to 7.3.1-rc.0.3, 7.3.1-rc.0.4, and Unraid OS 7.3.1 Stable.

Summary by CodeRabbit

Chores

  • Improved release automation and synchronization between GitHub PRs and Linear issues, ensuring PR links are properly captured and tracked throughout the release cycle
  • Strengthened issue state management across multiple release versions, providing better visibility into which changes are included in each release
  • Enhanced overall reliability of the release workflow

Review Change Stack

Purpose of the change:
- Address review feedback on the WebGUI Linear release workflow while keeping the patch minimal.

Previous behavior:
- The workflow used the mutable actions/checkout@v6 tag.
- Tags without a previous semver tag used RANGE_SPEC equal to the tag name, causing git log to walk full ancestry.
- PR metadata collection only recognized merge commits shaped as Merge pull request #123.

Why that was a problem:
- Mutable action tags can be retargeted upstream.
- A first-tag release could scan unrelated historical commits and attach unrelated Linear metadata.
- Squash-merged PRs with commit messages like Fix thing (#123) would not have their PR body scanned for Linear or FeatureOS links.

What this changes:
- Pins actions/checkout to the current v6.0.2 commit SHA.
- Uses TAG^..TAG for first-tag ranges when a parent exists, with the old tag fallback only for parentless commits.
- Extends PR number extraction to include squash-merge (#123) patterns while preserving numeric extraction, sorting, and dedupe.

How it works:
- The existing PR lookup loop remains unchanged; it receives a broader but still numeric-only PR number list.
- The git range emitted by Resolve tag remains bounded before the later git log call uses it.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c46f456c-5430-4c1f-8059-c507fef4e4ae

📥 Commits

Reviewing files that changed from the base of the PR and between b869eb7 and 019e57b.

📒 Files selected for processing (1)
  • .github/scripts/sync-linear-release.mjs

Walkthrough

The release workflow pins checkout, adds a tag-range fallback, records GitHub PR URLs and passes their path/count to the Node sync script; the script loads those PR URLs and attaches any linked Linear issues using generalized URL-to-issue helpers and related-release linking.

Changes

Release Workflow Improvements

Layer / File(s) Summary
Workflow: checkout pin, tag range, PR capture and wiring
.github/workflows/linear-release.yml
actions/checkout pinned to v6.0.2; tag-range fallback added to use ${TAG_NAME}^..${TAG_NAME} when no PREVIOUS_TAG but parent commit exists; GITHUB_PR_URLS_PATH file created and populated with .../pull/${PR_NUMBER} entries; exported github_pr_urls_path and github_pr_url_count and passed into the node sync step; final summary reports GitHub PR link count.

Sync script: related releases and attachment-based issue sync

Layer / File(s) Summary
Sync orchestration and env
.github/scripts/sync-linear-release.mjs
Script reads GITHUB_PR_URLS_PATH into githubPrUrls, computes relatedReleases for internal runs, and passes relatedReleases plus featureOsUrls and githubPrUrls into syncIssuesToRelease.
Upsert/related-release resolution
.github/scripts/sync-linear-release.mjs
upsertRelease expanded to accept custom name/version/description and resolveRelatedReleases added to create/update stable and planned next-prerelease releases.
Attachment lookup and GitHub PR ingestion
.github/scripts/sync-linear-release.mjs
Feature-OS URL resolver generalized to findIssuesForAttachmentUrl using candidateAttachmentUrls; new loop reads githubPrUrls, resolves linked Linear issues (including issue state), skips archived issues, and hands each to syncIssueToReleases for release-link updates.
Issue queries and carry logic
.github/scripts/sync-linear-release.mjs
findIssue now fetches issue state; findIssuesForRelease(releaseId) added to list non-archived attached issues; shouldCarryIssueToNextPrerelease(issue) introduced to decide next-prerelease linking; candidate URL helper reintroduced as candidateAttachmentUrls.

Sequence Diagram(s)

sequenceDiagram
  participant Workflow
  participant NodeScript
  participant LinearAPI
  Workflow->>Workflow: checkout pinned to v6.0.2
  Workflow->>Workflow: compute RANGE_SPEC (use ${TAG_NAME}^..${TAG_NAME} fallback)
  Workflow->>Workflow: extract PR numbers and write GITHUB_PR_URLS_PATH
  Workflow->>NodeScript: set env GITHUB_PR_URLS_PATH / github_pr_url_count
  NodeScript->>LinearAPI: findIssuesForAttachmentUrl(url) for each githubPrUrl
  LinearAPI->>NodeScript: return linked Linear issue IDs (skip archived/unlinked)
  NodeScript->>LinearAPI: attach/de-duplicate issues on release
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • unraid/webgui#2646: Modifies sync-linear-release.mjs with adjacent URL-to-issue resolution changes.
  • unraid/webgui#2644: Updates linear-release.yml and related sync behavior for release automation.

Poem

🐰 I hopped through tags and pinned the flow,
I gathered PR links in a neat row,
Passed them to Node with a gentle shove,
Found Linear issues and linked with love,
Now releases and issues dance in a glow 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: Harden WebGUI Linear release workflow' directly relates to the primary objective of the PR: strengthening the Linear release workflow with hardened processes (pinning checkout SHA, bounding git ranges, refining PR extraction, and passing GitHub PR URLs to sync).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/webgui-linear-release-sync-review-fixes

Comment @coderabbitai help to get the list of available commands and usage tips.

@elibosley elibosley marked this pull request as ready for review May 22, 2026 16:16
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/linear-release.yml:
- Around line 123-125: The current grep pipeline is too broad because it picks
up parenthetical issue references like "(`#123`)"; restrict the extraction to
actual merge PR lines by changing the first grep to only match explicit merge
commit messages (e.g. grep -Eo "Merge pull request #[0-9]+") instead of also
matching "\(#[0-9]+\)"; update the pipeline that uses LOG_PATH (the two grep |
sort -u || true sequence) so it extracts only numbers from "Merge pull request
#[0-9]+" matches, ensuring curl calls to /pulls/{id} won’t receive issue IDs and
fail the job.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 536767ec-43ac-425c-b933-13e124f0fd6c

📥 Commits

Reviewing files that changed from the base of the PR and between 460bdb7 and 1797b25.

📒 Files selected for processing (1)
  • .github/workflows/linear-release.yml

Comment thread .github/workflows/linear-release.yml Outdated
Purpose of the change:
- Support WebGUI release sync when the only issue relationship is stored in Linear as a GitHub PR attachment.

Previous behavior:
- The workflow scanned commit and PR text for Linear issue IDs and FeatureOS URLs only.
- If a PR was linked from Linear but did not mention the Linear ticket in GitHub, release sync could miss the issue.

Why that was a problem:
- WebGUI release membership would be incomplete for issues where the canonical link lives in Linear's GitHub integration attachments.

What this changes:
- Records the GitHub PR URL for each PR discovered from the release tag range.
- Passes those PR URLs into the Linear sync script.
- Resolves matching Linear attachments with attachmentsForURL and attaches the linked issues to the release.
- Treats missing PR attachments as normal and avoids noisy skipped entries.

How it works:
- The existing PR number parsing and PR metadata fetch stay in place.
- The script uses the same attachment lookup path for FeatureOS URLs and GitHub PR URLs, then dedupes issues before applying addedReleaseIds.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
.github/workflows/linear-release.yml (1)

124-137: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Constrain inline (#N) extraction to commit subjects to avoid false PR lookups.

Line 125 currently scans full commit bodies for (#N), which can capture non-PR references and make Line 136 fail with curl -fsSL against /pulls/{id}.

Suggested patch
           git log --format='%B%n' "$RANGE_SPEC" > "$LOG_PATH"
+          SUBJECTS_PATH="${RUNNER_TEMP}/linear-release-subjects.txt"
+          git log --format='%s' "$RANGE_SPEC" > "$SUBJECTS_PATH"

           PR_NUMBERS="$(
-            grep -Eo 'Merge pull request #[0-9]+|\(#[0-9]+\)' "$LOG_PATH" \
+            grep -Eo 'Merge pull request #[0-9]+|\(#[0-9]+\)$' "$SUBJECTS_PATH" \
               | grep -Eo '[0-9]+' \
               | sort -u || true
           )"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/linear-release.yml around lines 124 - 137, The current
PR_NUMBERS extraction greps the entire "$LOG_PATH" which captures `(`#N`)`
anywhere (including commit bodies) and leads to invalid PR lookups; change the
pipeline so the grep runs only against commit subjects instead of the full log
file — for example, replace reading "$LOG_PATH" with a command that emits only
commit subjects (e.g. git log --pretty=format:%s ...) or filter "$LOG_PATH" to
only subject lines before applying grep -Eo 'Merge pull request
#[0-9]+|\(#[0-9]+\)'; keep the rest of the pipeline (sort -u, loop over
PR_NUMBERS, writing to GITHUB_PR_URLS_PATH and the curl call) intact. Ensure you
update the PR_NUMBERS assignment (the variable and the grep invocation) so only
subject-line matches produce PR IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In @.github/workflows/linear-release.yml:
- Around line 124-137: The current PR_NUMBERS extraction greps the entire
"$LOG_PATH" which captures `(`#N`)` anywhere (including commit bodies) and leads
to invalid PR lookups; change the pipeline so the grep runs only against commit
subjects instead of the full log file — for example, replace reading "$LOG_PATH"
with a command that emits only commit subjects (e.g. git log --pretty=format:%s
...) or filter "$LOG_PATH" to only subject lines before applying grep -Eo 'Merge
pull request #[0-9]+|\(#[0-9]+\)'; keep the rest of the pipeline (sort -u, loop
over PR_NUMBERS, writing to GITHUB_PR_URLS_PATH and the curl call) intact.
Ensure you update the PR_NUMBERS assignment (the variable and the grep
invocation) so only subject-line matches produce PR IDs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a7d6488-1ea4-4088-9041-52477b446664

📥 Commits

Reviewing files that changed from the base of the PR and between 1797b25 and 52cb2f0.

📒 Files selected for processing (2)
  • .github/scripts/sync-linear-release.mjs
  • .github/workflows/linear-release.yml

elibosley added 3 commits May 22, 2026 12:23
Purpose of the change:
- Address review feedback on the WebGUI Linear release workflow PR parsing.

Previous behavior:
- PR number extraction matched both explicit merge commits and any parenthetical number shaped like (#123).

Why that was a problem:
- Ordinary issue references in commit messages could be treated as PR numbers and sent to the GitHub pulls API, causing the workflow to fail.

What this changes:
- Restricts PR number extraction to explicit Merge pull request #123 commit messages.
- Keeps the existing numeric extraction, sort -u dedupe, and || true fallback behavior.

How it works:
- The first grep now emits only Merge pull request #[0-9]+ matches before the second grep extracts digits for the existing curl loop.
Purpose of the change:
- Make workflow_dispatch testing work for historical WebGUI release tags.

Previous behavior:
- Manual runs checked out the requested tag directly.
- Historical tags do not contain the new sync script, so the workflow failed with MODULE_NOT_FOUND.

Why that was a problem:
- The workflow could not be tested against previous tags from the PR branch even though the tag metadata was fetched successfully.

What this changes:
- Manual workflow_dispatch runs now check out the workflow ref/branch while still resolving and operating on the requested tag_name.
- Tag push runs continue to check out the pushed tag.

How it works:
- The checkout ref uses github.ref for workflow_dispatch and github.ref_name for tag pushes.
Purpose of the change:
- Keep active QA work attached to the next prerelease and stable companion release from WebGUI tag sync.

Previous behavior:
- WebGUI release sync attached discovered Linear issues only to the exact tag release.
- Existing QA Ready issues already on a prerelease were not swept into the next planned prerelease.
- WebGUI-linked prerelease issues could miss the stable companion release.

Why that was a problem:
- QA Ready work could fall out of the next release bucket even though it still needed validation.
- Stable release planning would not reliably track all work that passed through the prerelease series.

What this changes:
- Internal/prerelease tag sync now resolves the exact prerelease, stable companion, and next planned prerelease releases.
- Active issues are attached to all applicable release buckets.
- Completed/internal-released issues are removed from the next planned prerelease while preserving exact prerelease and stable companion memberships.
- Existing issues already attached to the exact prerelease are swept through the same policy, even if they were not discovered from the current tag diff.

How it works:
- The sync script creates or updates the stable companion as Planned and the next prerelease as Planned.
- Issue state is loaded from Linear and used to decide whether to carry or remove next-prerelease membership.
- Linear issue updates use addedReleaseIds and removedReleaseIds without changing workflow state.
@elibosley elibosley merged commit 7b789bb into master May 22, 2026
6 checks passed
@elibosley elibosley deleted the codex/webgui-linear-release-sync-review-fixes branch May 22, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant