launchdarkly-flag-cleanup

launchdarkly-flag-cleanup

安全地從程式碼中移除功能開關,同時保留正式環境的行為。當使用者想要從程式碼中移除開關、刪除開關參考,或在功能推出完成後建立將獲勝變化寫死的 PR 時使用。

20星標
7分支
更新於 2026/7/25
SKILL.md
唯讀
名稱
launchdarkly-flag-cleanup
描述

安全地從程式碼中移除功能開關,同時保留正式環境的行為。當使用者想要從程式碼中移除開關、刪除開關參考,或在功能推出完成後建立將獲勝變化寫死的 PR 時使用。

LaunchDarkly Flag Cleanup

你正在使用一個技能,它會引導你安全地從程式碼中移除功能開關,同時保留正式環境的行為。你的工作是探索程式碼庫以了解開關的使用方式,查詢 LaunchDarkly 以確定正確的前向值,乾淨地移除開關程式碼,並驗證結果。

如果你尚未識別要清理的開關,請先使用開關發現技能來審視整體情況並找出候選項目。

先決條件

此技能需要在你的環境中設定遠端託管的 LaunchDarkly MCP 伺服器。

必要的 MCP 工具:

  • check-removal-readiness:詳細的安全檢查(並行協調開關設定、跨環境狀態、相依性、程式碼參考和到期目標)
  • get-flag:取得特定環境的開關設定

選用的 MCP 工具:

  • archive-flag:在程式碼移除後封存 LaunchDarkly 中的開關
  • delete-flag:永久刪除開關(不可逆,建議封存)

核心原則

  1. 安全第一:始終保留當前的正式環境行為。
  2. 以 LaunchDarkly 為真相來源:絕不猜測前向值。查詢實際設定。
  3. 遵循慣例:尊重現有的程式碼風格和結構。
  4. 最小變更:僅移除與開關相關的程式碼。不進行無關的重構。

工作流程

步驟 1:探索程式碼庫

在接觸 LaunchDarkly 或移除程式碼之前,了解此開關在程式碼庫中的使用方式。

  1. 找出所有對開關鍵的參考。 在整個程式碼庫中搜尋開關鍵字串(例如 new-checkout-flow)。檢查:

    • 直接 SDK 評估呼叫(variation()boolVariation()useFlags() 等)
    • 參考該鍵的常數/列舉
    • 抽象 SDK 的包裝器/服務模式
    • 設定檔、測試和文件
    • 請參閱 SDK 模式 以取得按語言分類的完整模式列表
  2. 了解分支邏輯。 對於每個參考,識別:

    • 當開關為 true(或變化 A)時執行哪些程式碼?
    • 當開關為 false(或變化 B)時執行哪些程式碼?
    • 是否有副作用、提前返回或巢狀條件?
  3. 注意範圍。 此開關觸及多少檔案、元件或模組?在一個 if 區塊中使用的開關比貫穿多個層級的開關更簡單。

步驟 2:執行移除就緒檢查

使用 check-removal-readiness 取得詳細的安全評估。這個單一工具呼叫會並行協調多項檢查:

  • 開關設定和目標定位狀態
  • 跨環境狀態
  • 相依開關(先決條件)
  • 到期目標
  • 程式碼參考統計

該工具會傳回移除就緒判定:

safe:沒有阻擋或警告。繼續移除。

caution:沒有硬性阻擋,但存在警告(例如其他儲存庫中的程式碼參考、已排程的到期目標、開關標記為永久)。呈現警告並讓使用者決定。

blocked:硬性阻擋阻止安全移除(例如相依開關、正在接收請求、目標定位已啟用且有活躍規則)。呈現阻擋項目:使用者必須先解決它們。

步驟 3:確定前向值

使用 get-flag 取得每個關鍵環境中的開關設定。前向值是取代程式碼中開關的變化。

情境 前向值
所有關鍵環境 ON,相同的 fallthrough,沒有規則/目標 使用 fallthrough.variation
所有關鍵環境 OFF,相同的 offVariation 使用 offVariation
關鍵環境的 ON/OFF 狀態不同 不安全:停止並通知使用者
關鍵環境提供不同的變化 不安全:停止並通知使用者

步驟 4:呈現清理計畫

在修改任何程式碼之前,向使用者呈現摘要並等待確認:

  1. 前向值 — 哪個變化將被寫死以及原因(基於開關的當前狀態)。
  2. 找到的所有程式碼參考 — 來自步驟 1 的檔案路徑和行號。
  3. 計畫的變更 — 對於每個參考,描述將移除哪些內容以及保留哪些內容。
  4. 移除就緒判定check-removal-readiness 的結果(safe、caution 或 blocked)以及任何警告。
  5. LaunchDarkly 動作 — 確認在程式碼變更完成後將封存開關。

在使用者明確確認之前,不要進行程式碼變更。

步驟 5:從程式碼中移除開關

現在使用你在步驟 1 中學到的內容執行移除。

  1. 將開關評估替換為前向值。

    • 保留與前向值匹配的程式碼分支
    • 完全移除死分支
    • 如果開關值被賦值給變數,則將變數替換為字面值或內聯化
  2. 清理死程式碼。

    • 移除僅為開關而存在的匯入、常數和型別定義
    • 移除僅為死分支而存在的函式、元件或檔案
    • 檢查孤立的匯出、鉤子、輔助函式、樣式和測試檔案
    • 如果儲存庫使用未使用匯出工具(Knip、ts-prune、lint 規則),執行它並移除任何與開關相關的孤立項目
  3. 不要過度清理。

    • 僅移除直接與開關相關的程式碼
    • 不要重構、最佳化或「改進」周圍的程式碼
    • 不要變更未觸及程式碼的格式或風格

範例轉換(布林開關,前向值 = true):

// Before
const showNewCheckout = await ldClient.variation('new-checkout-flow', user, false);
if (showNewCheckout) {
  return renderNewCheckout();
} else {
  return renderOldCheckout();
}

// After
return renderNewCheckout();

步驟 6:建立 Pull Request

使用 references/pr-template.md 中的範本建立結構化的 PR 描述。PR 應清楚傳達:

  • 移除了哪個開關以及原因
  • 前向值是什麼以及為什麼它是正確的
  • 就緒評估結果(來自 check-removal-readiness
  • 移除了哪些程式碼以及保留了哪些行為
  • 其他儲存庫是否仍參考此開關

步驟 7:驗證

在認為工作完成之前:

  1. 程式碼編譯並通過 lint。 執行專案的建置和 lint 步驟。
  2. 測試通過。 如果開關用於測試,則應更新測試以反映寫死的行為。
  3. 沒有遺留的參考。 再次搜尋程式碼庫中的開關鍵,以確保沒有遺漏任何內容。
  4. PR 完整。 描述涵蓋就緒評估、前向值理由以及任何需要的跨儲存庫協調。

邊緣情況

情況 動作
在 LaunchDarkly 中找不到開關 通知使用者,檢查鍵是否有拼寫錯誤
開關已封存 詢問是否仍需要程式碼清理(開關已從 LD 中消失,但程式碼可能仍參考它)
程式碼庫中有多種 SDK 模式 搜尋所有模式:variation()boolVariation()variationDetail()allFlags()useFlags(),以及任何包裝器
動態開關鍵(flag-${id} 警告自動化移除可能不完整:需要手動審查
程式碼與 LD 中的預設值不同 在 PR 描述中標記為不一致
移除後遺留孤立的匯出/檔案 執行未使用匯出檢查並移除死檔案

不該做的事

  • 不要變更與開關清理無關的程式碼。
  • 不要重構或最佳化超出開關移除的範圍。
  • 不要移除仍在積極推出的開關。
  • 不要猜測前向值:始終查詢 LaunchDarkly。

清理之後

一旦 PR 合併並部署:

  1. 在 LaunchDarkly 中封存開關,使用 archive-flag。封存是可逆的;刪除則不可逆。始終先封存。
  2. 通知其他團隊,如果 check-removal-readiness 報告其他儲存庫中有程式碼參考。
  3. 如果開關有待處理的目標變更,可以忽略:開關正在被移除。

參考資料

  • PR 範本:用於開關移除的結構化 PR 描述
  • SDK 模式:按語言/框架分類的開關評估模式
  • 開關發現:在使用此技能前尋找清理候選項目
  • 開關目標:如果你需要變更目標而非移除