From 14ed396c23ee7f63699525eba91cf4cc0befa8b6 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Mon, 16 Mar 2026 13:38:27 -0700 Subject: [PATCH 1/2] ci: add reusable workflow to move Linear tickets to Deployed Parses SDK-XXXX ticket references from release notes and updates their status to Deployed via the Linear API. Made-with: Cursor --- .github/workflows/linear-deployed.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/linear-deployed.yml diff --git a/.github/workflows/linear-deployed.yml b/.github/workflows/linear-deployed.yml new file mode 100644 index 0000000..0af13a4 --- /dev/null +++ b/.github/workflows/linear-deployed.yml @@ -0,0 +1,67 @@ +name: Move Linear tickets to Deployed + +on: + workflow_call: + inputs: + release_body: + required: true + type: string + team_key: + required: false + type: string + default: 'SDK' + secrets: + LINEAR_API_KEY: + required: true + +jobs: + update-linear: + runs-on: ubuntu-latest + steps: + - name: Update Linear tickets to Deployed + env: + LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }} + TEAM_KEY: ${{ inputs.team_key }} + run: | + RELEASE_BODY=$(cat <<'EOF' + ${{ inputs.release_body }} + EOF + ) + + TICKETS=$(echo "$RELEASE_BODY" | grep -oE 'SDK-[0-9]+' | sort -u) + + if [ -z "$TICKETS" ]; then + echo "No SDK tickets found in release notes" + exit 0 + fi + + STATE_ID=$(curl -s -X POST https://api.linear.app/graphql \ + -H "Authorization: $LINEAR_API_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"query\": \"{ workflowStates(filter: { name: { eq: \\\"Deployed\\\" }, team: { key: { eq: \\\"$TEAM_KEY\\\" } } }) { nodes { id } } }\"}" \ + | jq -r '.data.workflowStates.nodes[0].id') + + echo "Deployed state ID: $STATE_ID" + + for TICKET in $TICKETS; do + NUM=$(echo "$TICKET" | grep -oE '[0-9]+') + echo "Processing $TICKET..." + + ISSUE_ID=$(curl -s -X POST https://api.linear.app/graphql \ + -H "Authorization: $LINEAR_API_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"query\": \"{ issueSearch(filter: { number: { eq: $NUM }, team: { key: { eq: \\\"$TEAM_KEY\\\" } } }) { nodes { id title } } }\"}" \ + | jq -r '.data.issueSearch.nodes[0].id // empty') + + if [ -z "$ISSUE_ID" ]; then + echo " ⚠️ $TICKET not found in Linear" + continue + fi + + RESULT=$(curl -s -X POST https://api.linear.app/graphql \ + -H "Authorization: $LINEAR_API_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"query\": \"mutation { issueUpdate(id: \\\"$ISSUE_ID\\\", input: { stateId: \\\"$STATE_ID\\\" }) { success issue { identifier title } } }\"}") + + echo " ✅ $TICKET → Deployed" + done From 4fbe8f3dd447cb643509cf68d4a873add5131751 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Mon, 16 Mar 2026 13:59:38 -0700 Subject: [PATCH 2/2] fix: rename secret to LINEAR_GITHUB_API_KEY Made-with: Cursor --- .github/workflows/linear-deployed.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linear-deployed.yml b/.github/workflows/linear-deployed.yml index 0af13a4..da0edf4 100644 --- a/.github/workflows/linear-deployed.yml +++ b/.github/workflows/linear-deployed.yml @@ -11,7 +11,7 @@ on: type: string default: 'SDK' secrets: - LINEAR_API_KEY: + LINEAR_GITHUB_API_KEY: required: true jobs: @@ -20,7 +20,7 @@ jobs: steps: - name: Update Linear tickets to Deployed env: - LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }} + LINEAR_GITHUB_API_KEY: ${{ secrets.LINEAR_GITHUB_API_KEY }} TEAM_KEY: ${{ inputs.team_key }} run: | RELEASE_BODY=$(cat <<'EOF' @@ -36,7 +36,7 @@ jobs: fi STATE_ID=$(curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ + -H "Authorization: $LINEAR_GITHUB_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"query\": \"{ workflowStates(filter: { name: { eq: \\\"Deployed\\\" }, team: { key: { eq: \\\"$TEAM_KEY\\\" } } }) { nodes { id } } }\"}" \ | jq -r '.data.workflowStates.nodes[0].id') @@ -48,7 +48,7 @@ jobs: echo "Processing $TICKET..." ISSUE_ID=$(curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ + -H "Authorization: $LINEAR_GITHUB_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"query\": \"{ issueSearch(filter: { number: { eq: $NUM }, team: { key: { eq: \\\"$TEAM_KEY\\\" } } }) { nodes { id title } } }\"}" \ | jq -r '.data.issueSearch.nodes[0].id // empty') @@ -59,7 +59,7 @@ jobs: fi RESULT=$(curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ + -H "Authorization: $LINEAR_GITHUB_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"query\": \"mutation { issueUpdate(id: \\\"$ISSUE_ID\\\", input: { stateId: \\\"$STATE_ID\\\" }) { success issue { identifier title } } }\"}")