Skip to content

ci: report router releases to a Linear release pipeline#3066

Draft
endigma wants to merge 2 commits into
mainfrom
jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0
Draft

ci: report router releases to a Linear release pipeline#3066
endigma wants to merge 2 commits into
mainfrom
jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0

Conversation

@endigma

@endigma endigma commented Jul 9, 2026

Copy link
Copy Markdown
Member

Sets up Linear release reporting for the router component to start, following the continuous-deployment pattern in the Linear docs.

The setup is per-component by design: more components are added by copying the router job and adjusting the tag prefix, include_paths, and access-key secret — each reporting to its own Linear pipeline.

Required setup before this takes effect

  1. Create a continuous release pipeline in Linear (Settings → Releases) for router, with a path filter matching router/.
  2. Add its pipeline access key as the repo secret LINEAR_ACCESS_KEY_ROUTER.

The router job only runs for its own release tag, so additional components can be rolled out independently later.

Summary by CodeRabbit

  • New Features
    • Added an automated GitHub Actions workflow that reports newly published router releases to Linear.
    • Limits commit scanning to the matching component directory, via a reusable reporting workflow and a component-specific Linear access key.
  • Bug Fixes
    • Draft and prerelease releases are no longer reported (reporting runs only for non-prereleases).

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

Walkthrough

A new release workflow routes published component tags to a reusable Linear reporting workflow. The reusable workflow receives scoped paths and a secret key, checks out full history, and submits the release metadata to Linear.

Changes

Linear release reporting workflows

Layer / File(s) Summary
Workflow trigger and metadata
.github/workflows/linear-release.yaml
Defines the release-published workflow metadata, run name, and read-only contents permission.
Component release routing jobs
.github/workflows/linear-release.yaml
Adds conditional jobs for router, aws-lambda-router, wgc, controlplane, studio, graphqlmetrics, keycloak, otelcollector, and cdn release tags, each mapping a tag prefix to component-specific include paths and Linear secrets.
Reusable Linear report workflow
.github/workflows/linear-release-report.yaml
Defines the reusable workflow inputs and secret, checks out the repository with full history, and invokes linear/linear-release-action@v0 with the release tag metadata and scoped paths.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main CI change, though it narrows the scope to router while the PR adds reporting for multiple component releases.

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

@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from 226810d to 7b9e34c Compare July 9, 2026 16:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/linear-release.yaml (1)

88-96: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Missing-secret case isn't actually skipped.

The PR description states unmatched tags or missing secrets are skipped, and the mapping-resolution step only guards on matched == 'true'. If the corresponding LINEAR_RELEASE_KEY_<SLUG> secret isn't configured, secrets[format(...)] resolves to an empty string, and this step still runs with an empty access_key, likely surfacing an opaque failure from linear/linear-release-action instead of a graceful skip.

💡 Proposed fix: add an explicit secret-presence check
+      - name: Check Linear access key secret
+        id: secret_check
+        if: steps.component.outputs.matched == 'true'
+        env:
+          ACCESS_KEY: ${{ secrets[format('LINEAR_RELEASE_KEY_{0}', steps.component.outputs.slug)] }}
+        run: |
+          if [[ -z "$ACCESS_KEY" ]]; then
+            echo "No LINEAR_RELEASE_KEY_${{ steps.component.outputs.slug }} secret configured; skipping."
+            echo "has_key=false" >> "$GITHUB_OUTPUT"
+          else
+            echo "has_key=true" >> "$GITHUB_OUTPUT"
+          fi
+
       - name: Checkout repository
-        if: steps.component.outputs.matched == 'true'
+        if: steps.component.outputs.matched == 'true' && steps.secret_check.outputs.has_key == 'true'
         uses: actions/checkout@v4
         with:
           fetch-depth: 0

       - name: Report release to Linear
-        if: steps.component.outputs.matched == 'true'
+        if: steps.component.outputs.matched == 'true' && steps.secret_check.outputs.has_key == 'true'
         uses: linear/linear-release-action@v0
🤖 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.yaml around lines 88 - 96, The release
reporting step in the workflow only checks steps.component.outputs.matched, so
it still runs when the LINEAR_RELEASE_KEY_<SLUG> secret is missing and passes an
empty access_key to linear/linear-release-action. Update the condition on the
Report release to Linear step to also verify the resolved secret is present
before running, using the same steps.component.outputs.slug and
secrets[format(...)] lookup, so missing-secret cases are skipped cleanly instead
of failing in the action.
🧹 Nitpick comments (1)
.github/workflows/linear-release.yaml (1)

92-92: 🔒 Security & Privacy | 🔵 Trivial | ⚖️ Poor tradeoff

Dynamic secret lookup necessarily exposes the whole secrets context.

zizmor's overprovisioned-secrets warning is an inherent consequence of selecting the secret name dynamically (secrets[format('LINEAR_RELEASE_KEY_{0}', slug)]) to support per-component keys. There's no low-cost fix without restructuring to a static per-component step/matrix, which would add significant duplication for marginal benefit here.

🤖 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.yaml at line 92, The `access_key`
assignment in `linear-release.yaml` uses a dynamic `secrets[format(...)]`
lookup, which triggers the overprovisioned-secrets warning. To fix it, replace
the dynamic secret access with statically referenced secrets by restructuring
the release job around explicit per-component steps or a matrix in the
`linear-release` workflow. If you keep the dynamic lookup, add an explicit
suppression/justification in the workflow near this secret reference so the
intended per-component key selection is documented.

Source: Linters/SAST tools

🤖 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.yaml:
- Around line 80-86: The Checkout repository step in the linear-release workflow
currently leaves Git credentials persisted for the rest of the job even though
nothing pushes afterward. Update the actions/checkout@v4 configuration in that
step to set persist-credentials to false, keeping the existing full-history
fetch-depth behavior intact.

---

Outside diff comments:
In @.github/workflows/linear-release.yaml:
- Around line 88-96: The release reporting step in the workflow only checks
steps.component.outputs.matched, so it still runs when the
LINEAR_RELEASE_KEY_<SLUG> secret is missing and passes an empty access_key to
linear/linear-release-action. Update the condition on the Report release to
Linear step to also verify the resolved secret is present before running, using
the same steps.component.outputs.slug and secrets[format(...)] lookup, so
missing-secret cases are skipped cleanly instead of failing in the action.

---

Nitpick comments:
In @.github/workflows/linear-release.yaml:
- Line 92: The `access_key` assignment in `linear-release.yaml` uses a dynamic
`secrets[format(...)]` lookup, which triggers the overprovisioned-secrets
warning. To fix it, replace the dynamic secret access with statically referenced
secrets by restructuring the release job around explicit per-component steps or
a matrix in the `linear-release` workflow. If you keep the dynamic lookup, add
an explicit suppression/justification in the workflow near this secret reference
so the intended per-component key selection is documented.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c644eee7-2e95-47d8-8981-ed0f1b91847e

📥 Commits

Reviewing files that changed from the base of the PR and between 6c2dc0f and 226810d.

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

Comment thread .github/workflows/linear-release.yaml Outdated
Comment on lines +80 to +86
- name: Checkout repository
if: steps.component.outputs.matched == 'true'
uses: actions/checkout@v4
with:
# Full history is required so the action can scan commits since the
# pipeline's previous release for issue references.
fetch-depth: 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Set persist-credentials: false on checkout.

No push happens afterward, so persisting the checkout credentials for the remainder of the job is unnecessary exposure.

🔒️ Proposed fix
       - name: Checkout repository
         if: steps.component.outputs.matched == 'true'
         uses: actions/checkout@v4
         with:
+          persist-credentials: false
           # Full history is required so the action can scan commits since the
           # pipeline's previous release for issue references.
           fetch-depth: 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout repository
if: steps.component.outputs.matched == 'true'
uses: actions/checkout@v4
with:
# Full history is required so the action can scan commits since the
# pipeline's previous release for issue references.
fetch-depth: 0
- name: Checkout repository
if: steps.component.outputs.matched == 'true'
uses: actions/checkout@v4
with:
persist-credentials: false
# Full history is required so the action can scan commits since the
# pipeline's previous release for issue references.
fetch-depth: 0
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 80-86: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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.yaml around lines 80 - 86, The Checkout
repository step in the linear-release workflow currently leaves Git credentials
persisted for the rest of the job even though nothing pushes afterward. Update
the actions/checkout@v4 configuration in that step to set persist-credentials to
false, keeping the existing full-history fetch-depth behavior intact.

Source: Linters/SAST tools

@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from 7b9e34c to 5f6d9e1 Compare July 9, 2026 16:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/linear-release.yaml (1)

71-71: 🔒 Security & Privacy | 🔵 Trivial | ⚖️ Poor tradeoff

Dynamic secret lookup exposes the entire secrets context to the runner.

Using secrets[steps.component.outputs.secret_name] is valid GitHub Actions syntax for dynamic secret selection, but because the key isn't statically known, GitHub injects the full secrets context into the runner for this job (flagged by zizmor as overprovisioned-secrets). This means every repo secret, not just the intended per-component key, is available to the runner process during this job. Given the job also checks out untrusted-by-default release metadata and calls a third-party action, this widens the blast radius if either is compromised.

If this is an accepted tradeoff for the incremental-rollout design, no action is needed; otherwise, consider a per-component job matrix with statically-referenced secrets (or per-component GitHub Environments) to scope secret access.

Also applies to: 92-92

🤖 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.yaml at line 71, The release workflow is
using a dynamic secret lookup in the job, which causes the full secrets context
to be injected. Update the `linear-release` workflow to avoid
`secrets[steps.component.outputs.secret_name]` in the `ACCESS_KEY` assignment,
and instead scope secret access per component using a job matrix with statically
referenced secrets or separate GitHub Environments so only the intended key is
available.

Source: Linters/SAST tools

🤖 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.yaml:
- Around line 68-79: The guard step in the workflow is interpolating
steps.component.outputs.secret_name and steps.component.outputs.component
directly into the shell body, which creates a template-injection risk. Update
the “Check pipeline is configured” step to pass those outputs through env
variables alongside ACCESS_KEY, and have the run script reference shell
variables only. Keep the logic in the guard step the same, but remove direct ${{
... }} expansion from the script body so the shell never sees raw template text.

---

Nitpick comments:
In @.github/workflows/linear-release.yaml:
- Line 71: The release workflow is using a dynamic secret lookup in the job,
which causes the full secrets context to be injected. Update the
`linear-release` workflow to avoid
`secrets[steps.component.outputs.secret_name]` in the `ACCESS_KEY` assignment,
and instead scope secret access per component using a job matrix with statically
referenced secrets or separate GitHub Environments so only the intended key is
available.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ff3b2f4-4560-438c-a8cf-528ee2b86146

📥 Commits

Reviewing files that changed from the base of the PR and between 226810d and 7b9e34c.

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

Comment thread .github/workflows/linear-release.yaml Outdated
@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from 5f6d9e1 to eeb1124 Compare July 9, 2026 16:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/linear-release.yaml (1)

52-66: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Malformed tag silently falls back to bogus component/version.

If TAG doesn't contain @, both ${TAG%@*} and ${TAG##*@} leave component/version equal to the full tag string rather than failing. The guard step's secret lookup coincidentally prevents a bad run in practice (no matching secret → skipped), but an explicit check would make the failure mode clearer and avoid depending on that side-effect.

           component="${TAG%@*}"
           version="${TAG##*@}"
+          if [ "$component" = "$TAG" ] || [ "$version" = "$TAG" ]; then
+            echo "Tag '$TAG' does not match <component>@<semver>; skipping." >&2
+            exit 1
+          fi
🤖 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.yaml around lines 52 - 66, The tag parsing
in the release workflow currently assumes TAG always contains “@”, so malformed
tags can produce bogus component/version values instead of failing fast. Update
the shell logic in the release step that derives component, version, and
secret_name to explicitly validate TAG contains a separator before using
${TAG%@*} and ${TAG##*@}, and exit with a clear error if it does not. Keep the
existing output keys and slug derivation in place, but make the validation part
of the same release-tag parsing block so the failure is immediate and obvious.
🤖 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.

Nitpick comments:
In @.github/workflows/linear-release.yaml:
- Around line 52-66: The tag parsing in the release workflow currently assumes
TAG always contains “@”, so malformed tags can produce bogus component/version
values instead of failing fast. Update the shell logic in the release step that
derives component, version, and secret_name to explicitly validate TAG contains
a separator before using ${TAG%@*} and ${TAG##*@}, and exit with a clear error
if it does not. Keep the existing output keys and slug derivation in place, but
make the validation part of the same release-tag parsing block so the failure is
immediate and obvious.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c1678f4-b30e-4da4-9139-a7d1472f1360

📥 Commits

Reviewing files that changed from the base of the PR and between 7b9e34c and 5f6d9e1.

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

@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from eeb1124 to 59a3c99 Compare July 9, 2026 16:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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-report.yaml:
- Around line 32-35: The checkout in the release report workflow leaves
persisted Git credentials enabled by default, which is unnecessary for a
history-only job. Update the existing actions/checkout step in the
linear-release-report workflow to disable persisted credentials while keeping
the full-history fetch behavior, so later steps and nested actions do not
inherit the repo token.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83ca8f46-6992-45ba-a0e3-2a477ed64c12

📥 Commits

Reviewing files that changed from the base of the PR and between 5f6d9e1 and eeb1124.

📒 Files selected for processing (2)
  • .github/workflows/linear-release-report.yaml
  • .github/workflows/linear-release.yaml

Comment thread .github/workflows/linear-release-report.yaml Outdated
@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from 59a3c99 to a5b56d8 Compare July 9, 2026 16:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/linear-release-report.yaml (1)

37-42: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Consider pinning linear/linear-release-action to a commit SHA.

Pinning to @v0 trusts the tag not being force-moved; a SHA pin is safer against supply-chain tampering, per GitHub's own guidance that using the commit SHA is safest for stability and security.

🤖 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-report.yaml around lines 37 - 42, The
workflow uses linear/linear-release-action@v0, which should be pinned to a
specific commit SHA for supply-chain safety. Update the action reference in the
release job to use an immutable SHA instead of the moving `@v0` tag, keeping the
existing with inputs unchanged.
🤖 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.

Nitpick comments:
In @.github/workflows/linear-release-report.yaml:
- Around line 37-42: The workflow uses linear/linear-release-action@v0, which
should be pinned to a specific commit SHA for supply-chain safety. Update the
action reference in the release job to use an immutable SHA instead of the
moving `@v0` tag, keeping the existing with inputs unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 666d00be-05aa-4a4a-beb1-eaf2c83b57da

📥 Commits

Reviewing files that changed from the base of the PR and between eeb1124 and a5b56d8.

📒 Files selected for processing (2)
  • .github/workflows/linear-release-report.yaml
  • .github/workflows/linear-release.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/linear-release.yaml

@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch 3 times, most recently from 9076b1a to 923ad05 Compare July 9, 2026 17:14
@endigma endigma changed the title ci: report component releases to Linear release pipelines ci: report router releases to a Linear release pipeline Jul 9, 2026
@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from 923ad05 to f04f223 Compare July 9, 2026 17:15
Add Linear release reporting for the router component, following the
continuous-deployment pattern in the Linear docs. lerna publishes one GitHub
release per component (tagged '<component>@<semver>'); linear-release.yaml has
a router job that runs on the 'released' event for the 'router@' tag prefix and
hands off to the reusable linear-release-report workflow with the router path
filter and its pipeline access key (LINEAR_ACCESS_KEY_ROUTER). More components
can be added by copying the job.

Generated with [Linear](https://linear.app/wundergraph/issue/COSMO-52/set-up-linear-releases-for-cosmo-monorepo-components#agent-session-f5d3e845)

Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
@endigma endigma force-pushed the jesse/cosmo-52-set-up-linear-releases-for-cosmo-monorepo-components-a1d0 branch from f04f223 to 283ed03 Compare July 9, 2026 17:18
The report job only reads git history, so persist-credentials: false avoids
leaving the repo token in git config for later steps.

Generated with [Linear](https://linear.app/wundergraph/issue/COSMO-52/set-up-linear-releases-for-cosmo-monorepo-components#agent-session-f5d3e845)

Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
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