From 62fe714ff8e6b643c91e26d053f6e3a07e25f44e Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 20:27:54 +0000 Subject: [PATCH 1/2] ci: sync published production releases to Linear scheduled pipeline Adds a workflow that runs linear/linear-release-action whenever a production release is published on this repo. The action scans commit history between the previous release tag and the new one, extracts Linear issue identifiers from commit and PR titles, and creates or updates a release in the configured Scheduled pipeline. Pre-release tags (e.g. v0.7.4-staging.2) are skipped so Linear issues aren't marked as shipped to production before they actually are. Co-Authored-By: ashlee@vellum.ai --- .github/workflows/linear-release-sync.yml | 87 +++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 .github/workflows/linear-release-sync.yml diff --git a/.github/workflows/linear-release-sync.yml b/.github/workflows/linear-release-sync.yml new file mode 100644 index 00000000000..c76a37a53c1 --- /dev/null +++ b/.github/workflows/linear-release-sync.yml @@ -0,0 +1,87 @@ +# Linear Release sync — connects published production releases of this repo +# to Linear's release tracking so issues referenced in commit/PR titles between +# the previous tagged release and the current one are automatically grouped +# under the new release. +# +# This repo follows a tagged-release model (semver tags like `v0.5.3`), so the +# Linear pipeline configured to consume this sync should be of type +# **Scheduled** — not Continuous. The companion repo +# `vellum-ai/vellum-assistant-platform` is continuously deployed and uses a +# separate Continuous pipeline (see that repo's `linear-release-sync.yml`). +# +# The action scans commit history between the previous Linear release and the +# tagged commit, extracts Linear issue identifiers (e.g. `LUM-1234`, +# `JARVIS-123`), and creates or updates a Scheduled release identified by the +# git tag. +# +# Filtering: only true production releases (clean semver tags such as +# `v0.5.3`) advance the pipeline. The repo's release workflow also publishes +# `-staging.N` pre-release tags (`v0.7.4-staging.2`) via `gh release create`; +# those are skipped so Linear issues don't get marked as shipped to production +# before they actually are. +# +# Setup prerequisites (one-time, in Linear and GitHub UIs): +# 1. Create a Scheduled release pipeline in Linear: +# Settings → Releases → New pipeline → Type: Scheduled. +# 2. Copy the pipeline access key from its settings page. +# 3. Add the access key as a GitHub Actions secret on this repo named +# `LINEAR_ACCESS_KEY` (Settings → Secrets and variables → Actions). +# +# References: +# - Linear — Releases: https://linear.app/docs/releases +# - linear/linear-release-action: https://github.com/linear/linear-release-action +# - Linear Release CLI (pipeline semantics): https://github.com/linear/linear-release +# - GitHub — `release` event: +# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#release +name: Linear Release Sync + +on: + release: + types: [published] + +permissions: + contents: read + +concurrency: + # Serialize so two releases published back-to-back can't race the action + # into creating overlapping releases for the same commit window. + group: linear-release-sync + cancel-in-progress: false + +jobs: + sync: + name: Sync Linear release + runs-on: ubuntu-latest + # Skip on forks (the secret isn't available there) and on pre-release tags + # such as `v0.7.4-staging.2`. The repo's release workflow publishes + # staging tags through the same `gh release create` path as production but + # encodes the channel in the tag suffix; matching on `-staging.` keeps + # Scheduled-pipeline releases aligned with actual production launches. + if: >- + github.repository == 'vellum-ai/vellum-assistant' && + !contains(github.event.release.tag_name, '-staging.') + steps: + - name: Checkout release tag + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + # The published release's tag — checkout this exact ref so the + # action scans the commit history that actually shipped, not + # whatever HEAD happens to be on the default branch when the event + # fires. + ref: ${{ github.event.release.tag_name }} + # Full commit history required so the action can walk back from the + # release tag to the previous Linear release and find every issue + # mentioned in commit titles, merge commits, and PR titles in + # between. + fetch-depth: 0 + + - name: Sync to Linear scheduled pipeline + uses: linear/linear-release-action@755d50b5adb7dd42b976ee9334952745d62ceb2d # v0.6.0 + with: + access_key: ${{ secrets.LINEAR_ACCESS_KEY }} + # For scheduled pipelines, the Linear Release CLI recommends always + # passing `version` in CI so the sync targets the exact Linear + # release matching this git tag instead of inferring from + # started/planned state. See "Command targeting" in the action's + # README. + version: ${{ github.event.release.tag_name }} From 60798a75ff9c14abb7d911558456475e140e05ea Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 20:31:42 +0000 Subject: [PATCH 2/2] ci(linear-release-sync): pin cli_version and skip all pre-release tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two defensive hardening changes: 1. Pin the underlying Linear Release CLI to v0.10.0. The action's cli_version input defaults to 'latest', which would let every production run pull a newer CLI build with potentially-changed behavior or flags. Pinning keeps the sync reproducible. 2. Tighten the production-tag filter from a literal '-staging.' match to any tag containing '-'. The current release workflow only emits clean semver and '-staging.N' tags, but if a future workflow ever publishes '-rc.N', '-beta.N', or '-alpha.N' tags those would have leaked through and marked Linear issues as shipped to production prematurely. The 'gh release create' calls don't pass --prerelease, so we can't rely on github.event.release.prerelease — match on the hyphen in the tag instead. Co-Authored-By: ashlee@vellum.ai --- .github/workflows/linear-release-sync.yml | 30 +++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/linear-release-sync.yml b/.github/workflows/linear-release-sync.yml index c76a37a53c1..b701014947b 100644 --- a/.github/workflows/linear-release-sync.yml +++ b/.github/workflows/linear-release-sync.yml @@ -16,9 +16,12 @@ # # Filtering: only true production releases (clean semver tags such as # `v0.5.3`) advance the pipeline. The repo's release workflow also publishes -# `-staging.N` pre-release tags (`v0.7.4-staging.2`) via `gh release create`; -# those are skipped so Linear issues don't get marked as shipped to production -# before they actually are. +# `-staging.N` pre-release tags (`v0.7.4-staging.2`) via `gh release create`, +# and future workflows could plausibly publish other pre-release variants +# (`-rc.N`, `-beta.N`, `-alpha.N`). All such tags share the property that the +# semver-string contains a hyphen, so any tag with `-` in the suffix is +# skipped. This keeps Linear issues from being marked as shipped to +# production before they actually are. # # Setup prerequisites (one-time, in Linear and GitHub UIs): # 1. Create a Scheduled release pipeline in Linear: @@ -52,14 +55,18 @@ jobs: sync: name: Sync Linear release runs-on: ubuntu-latest - # Skip on forks (the secret isn't available there) and on pre-release tags - # such as `v0.7.4-staging.2`. The repo's release workflow publishes - # staging tags through the same `gh release create` path as production but - # encodes the channel in the tag suffix; matching on `-staging.` keeps + # Skip on forks (the secret isn't available there) and on any pre-release + # tag (`vX.Y.Z-staging.N`, `vX.Y.Z-rc.N`, `vX.Y.Z-beta.N`, …). The repo's + # current release workflow publishes staging tags through the same + # `gh release create` path as production but encodes the channel in the + # tag suffix; the `prerelease` flag on the GitHub Release object is *not* + # set (no `--prerelease`), so we can't rely on + # `github.event.release.prerelease`. Filtering on a hyphen in the tag + # catches every pre-release shape semver allows and keeps # Scheduled-pipeline releases aligned with actual production launches. if: >- github.repository == 'vellum-ai/vellum-assistant' && - !contains(github.event.release.tag_name, '-staging.') + !contains(github.event.release.tag_name, '-') steps: - name: Checkout release tag uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -85,3 +92,10 @@ jobs: # started/planned state. See "Command targeting" in the action's # README. version: ${{ github.event.release.tag_name }} + # Pin the underlying Linear Release CLI version. The action's input + # defaults to `latest`, which would let every production run pull a + # newer CLI build with potentially-changed behavior or flags. To + # upgrade: look up the new CLI tag at + # https://github.com/linear/linear-release/releases and bump the + # value below in the same PR as the action SHA bump. + cli_version: v0.10.0