アップデートトップに戻る

破壊的変更のポリシー

要約: line-harness の DB スキーマ変更はadditive-only (足すだけ)。 破壊的変更が必要な場合は3 リリースに分けて段階的に適用します。 これは、古いバージョンを動かしているユーザーがいる間に DB を壊さないための バージョン間互換ルールです。

許可される変更 (リリース単位)

1 つのリリース内で許可されるのは、既存データを壊さない変更だけです。 具体的には以下のとおりです。

  • CREATE TABLE — 新しいテーブルの作成
  • ALTER TABLE ... ADD COLUMN — 既存テーブルへのカラム追加 (NULL 許容 or DEFAULT 値ありに限る)
  • CREATE INDEX — インデックス追加
  • INSERT INTO ... — seed データの追加

同一リリース内で禁止される変更

以下の変更は、古いバージョンの Worker が動いている可能性があるため、同一リリースで実行することは禁止されています。 段階的アプローチ (後述) を使ってください。

  • DROP TABLE — テーブル削除
  • DROP COLUMN — カラム削除
  • ALTER COLUMN TYPE — カラム型変更
  • RENAME TABLE / RENAME COLUMN — 名前変更
  • NOT NULL 制約の追加 (DEFAULT なし)
  • UNIQUE 制約の追加

破壊的変更を行うときの手順 (3 リリース)

どうしても DROP / RENAME / 型変更が必要な場合は、 以下のように3 リリース挟んで段階的に移行します。 例として「users.email カラムを削除する」ケースで説明します。

リリース N: 新スキーマを additive に追加

  • 新しいカラム / テーブルを additive に追加 (旧スキーマはそのまま残す)
  • 新コードは新旧両方を読めるようにする
  • 書き込みは引き続き旧スキーマ (or 新旧両方)
-- migrations/0042_add_email_address.sql
ALTER TABLE users ADD COLUMN email_address TEXT;

リリース N+1: 旧スキーマを deprecate

  • 新コードは新スキーマのみに書き込む (旧スキーマには書かない)
  • 読み込みは互換性のため引き続き新旧両方
  • 既存データのバックフィル migration を実行
-- migrations/0050_backfill_email_address.sql
UPDATE users SET email_address = email WHERE email_address IS NULL;

リリース N+2: 旧スキーマを drop

  • 新コードは新スキーマのみ参照
  • 旧カラム / テーブルを DROP
  • この時点で N-1 以前を動かしている Worker は壊れるが、 十分な告知期間を取ったあとなので OK
-- migrations/0058_drop_legacy_email.sql
ALTER TABLE users DROP COLUMN email;
なぜ 3 リリース? ユーザーが古いバージョンの Worker をしばらく動かし続ける可能性があるからです。 1 リリースで DROP すると、まだ更新していないユーザーの Worker が DB エラーで動かなくなります。

急ぐ場合: major version bump

段階的な移行が現実的でないほど大規模な変更が必要な場合は、major version をインクリメントして破壊的変更を入れる選択肢があります。

  • 例: v1.x.xv2.0.0
  • リリースノートで明示的に「破壊的変更を含む」と告知
  • 移行ガイドを wiki に用意
  • ユーザーが手動でアップデート決定 (自動アップデートは major bump で停止)

ただし major bump はユーザー体験を悪化させるので、 できる限り 3 リリース移行を選んでください。

CI で違反 migration を block

scripts/check-migrations.ts という CI スクリプトが、 リリース時に各 migration ファイルを構文チェックします。DROP / RENAME / ALTER COLUMN TYPE などの破壊的キーワードが含まれていると、release.yml ワークフローでリリースが blockされます。

# 違反例 (CI で reject される)
ALTER TABLE users DROP COLUMN email;
ALTER TABLE users RENAME COLUMN name TO display_name;
ALTER TABLE users ALTER COLUMN age TYPE BIGINT;

意図的に破壊的変更を入れたい場合は、 コミットメッセージに BREAKING CHANGE: を含めて PR タイトルにも明記してください。レビュー時に手動で承認します。

なぜこのルールが必要か

line-harness は OSS で、ユーザーが各自のサーバーで動かしています。 中央集権的にバージョンを揃えられないので、古いバージョンの Worker が新しい DB スキーマと共存する期間 が必ず発生します。

additive-only ルールにより、新スキーマは古いコードからも安全に 無視できます (古いコードは新カラムを知らないだけで、エラーにならない)。 逆に DROP / RENAME を即時適用すると、未更新の Worker が 「カラムがない」エラーで全停止する事故が起きます。

このポリシーは、line-harness が長期メンテナンスされる OSS であるための 基本契約だと考えてください。

関連ページ