技能 编程开发 线性SDK安全版本迁移指南

线性SDK安全版本迁移指南

v20260423
linear-upgrade-migration
本指南提供了升级Linear SDK重大版本的完整流程。它指导用户如何安全地处理SDK的兼容性问题,包括检查API变化、处理字段重命名和类型变化,使用兼容层代码进行过渡,并制定了完整的测试和回滚策略,确保零停机部署。
获取技能
354 次下载
概览

Linear Upgrade Migration

Overview

Safely upgrade @linear/sdk versions with zero downtime. The SDK is auto-generated from Linear's GraphQL schema -- major versions can rename fields, change return types, add required parameters, or remove deprecated methods. This skill covers version checking, upgrade procedure, compatibility layers, and rollback.

Prerequisites

  • Existing Linear integration with version control (Git)
  • Test suite covering Linear SDK operations
  • Understanding of semantic versioning

Instructions

Step 1: Check Current vs Latest Version

set -euo pipefail
# Current installed version
npm list @linear/sdk 2>/dev/null || echo "Not installed"

# Latest available
npm view @linear/sdk version

# All recent versions
npm view @linear/sdk versions --json | jq '.[-10:]'

Step 2: Review Changelog for Breaking Changes

set -euo pipefail
# View SDK changelog on GitHub
npm view @linear/sdk repository.url
# Then check: https://github.com/linear/linear/blob/master/packages/sdk/CHANGELOG.md

# Also review Linear's API changelog:
# https://linear.app/changelog (filter for API/developer updates)

Common breaking changes between major versions:

  • Renamed fields: e.g., issue.state property vs lazy relation
  • Changed return types: direct value to paginated connection
  • New required parameters: mutations gaining mandatory fields
  • Removed methods: deprecated methods dropped
  • ESM/CJS: module system changes

Step 3: Create Upgrade Branch and Install

set -euo pipefail
git checkout -b upgrade/linear-sdk-$(npm view @linear/sdk version)
npm install @linear/sdk@latest

# Immediately check for type errors
npx tsc --noEmit 2>&1 | head -50

Step 4: Fix Type Errors with Compatibility Layer

// src/linear-compat.ts
// Bridge pattern for gradual migration across SDK versions

import { LinearClient } from "@linear/sdk";

/**
 * Normalize issue state access across SDK versions.
 * SDK v2: issue.state was a direct string property
 * SDK v3+: issue.state is a lazy-loaded WorkflowState relation
 */
export async function getIssueStateName(issue: any): Promise<string> {
  if (typeof issue.state === "string") return issue.state;
  const state = await issue.state;
  return state?.name ?? "unknown";
}

export async function getIssueStateType(issue: any): Promise<string> {
  if (typeof issue.stateType === "string") return issue.stateType;
  const state = await issue.state;
  return state?.type ?? "unknown";
}

/**
 * Normalize team access — some versions changed from direct to paginated.
 */
export async function getTeamByKey(client: LinearClient, key: string) {
  const teams = await client.teams({ filter: { key: { eq: key } } });
  return teams.nodes[0];
}

/**
 * Normalize issue creation return — handle both success shapes.
 */
export async function createIssue(
  client: LinearClient,
  input: { teamId: string; title: string; [key: string]: any }
) {
  const result = await client.createIssue(input);
  // Some versions return { success, issue } others return directly
  if ("success" in result) {
    return { success: result.success, issue: await result.issue };
  }
  return { success: true, issue: result };
}

Step 5: Run Tests and Fix Failures

set -euo pipefail
# Type-check
npx tsc --noEmit

# Run unit tests
npm test

# Run integration tests (if API key available)
npm run test:integration 2>&1 || true

# Lint
npm run lint 2>&1 || true

Common fixes:

// Fix: Property 'x' does not exist
// Old: issue.statusName
// New: (await issue.state)?.name

// Fix: Type 'X' is not assignable to type 'Y'
// Old: const states: string[] = team.states
// New: const states = await team.states()

// Fix: Expected 2 arguments but got 1
// Check if mutation added required parameter
// Old: client.updateIssue(id, { title: "new" })
// New: client.updateIssue(id, { title: "new" })  // usually same

Step 6: Test in Staging Before Production

set -euo pipefail
# Deploy to staging
npm run build
npm run deploy:staging

# Run integration tests against staging
LINEAR_API_KEY=$STAGING_LINEAR_API_KEY npm run test:integration

# Check health endpoint
curl -s https://staging.yourapp.com/health/linear | jq .

Step 7: Deploy with Rollback Plan

set -euo pipefail
# Commit upgrade
git add package.json package-lock.json src/linear-compat.ts
git commit -m "chore: upgrade @linear/sdk to $(npm list @linear/sdk --json | jq -r '.dependencies["@linear/sdk"].version')"
git push origin upgrade/linear-sdk-*

# If something breaks in production:
git revert HEAD
npm install  # Restores previous version
npm run deploy

Version Compatibility

SDK RangeNode.jsTypeScriptNotable Changes
1.x14+4.5+Initial release, callback-style
2.x-16.x16+4.7+ESM support, typed models
17.x-28.x18+5.0+Strict types, new entity models
Latest18+5.0+Refresh tokens, initiatives, agents

Error Handling

ErrorCauseSolution
Property does not existRenamed fieldCheck changelog, update field name
Type is not assignableChanged return typeUpdate type annotations
Module not foundESM/CJS mismatchUpdate import syntax or tsconfig
Cannot find nameRemoved exportReplace with new API equivalent
Tests pass, prod failsSDK version mismatch in lockfileDelete node_modules, npm ci

Examples

Pre-Upgrade Audit Script

// scripts/audit-linear-usage.ts
// Run before upgrading to find all SDK touchpoints

import { readFileSync } from "fs";
import { globSync } from "glob";

const files = globSync("src/**/*.ts");
const patterns = [
  /LinearClient/g,
  /client\.issues/g,
  /client\.createIssue/g,
  /client\.updateIssue/g,
  /\.state\b/g,
  /\.assignee\b/g,
  /rawRequest/g,
];

for (const file of files) {
  const content = readFileSync(file, "utf-8");
  for (const pattern of patterns) {
    const matches = content.match(pattern);
    if (matches) {
      console.log(`${file}: ${pattern.source} (${matches.length} occurrences)`);
    }
  }
}

Resources

信息
分类 编程开发
名称 linear-upgrade-migration
版本 v20260423
大小 4.3KB
更新时间 2026-04-28
语言