

Amazon CodeCatalyst 不再向新客戶開放。現有客戶可以繼續正常使用該服務。如需詳細資訊，請參閱[如何從 CodeCatalyst 遷移](migration.md)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 以藍圖作者身分使用生命週期管理
<a name="lifecycle-management-dev"></a>

生命週期管理可讓您從單一常用最佳實務來源保持大量專案同步。這會擴展修正的傳播，並在整個軟體開發生命週期中維護任意數量的專案。生命週期管理可簡化內部行銷活動、安全性修正、稽核、執行時間升級、最佳實務的變更，以及其他維護實務，因為這些標準是在一處定義，並在發佈新標準時自動集中保持在最新狀態。

發佈藍圖的新版本時，系統會提示包含該藍圖的所有專案更新至最新版本。身為藍圖作者，您也可以查看每個專案為了合規目的而包含的特定藍圖版本。當現有來源儲存庫發生衝突時，生命週期管理會建立提取請求。對於開發環境等所有其他資源，所有生命週期管理更新都會嚴格建立新的資源。使用者可以自由合併或不合併這些提取請求。合併待定提取請求時，專案中使用的藍圖版本，包括選項都會更新。若要了解如何以藍圖使用者身分使用生命週期管理，請參閱 [在現有專案上使用生命週期管理](lifecycle-management-user.md#using-lm-existing-projects)和 [在專案中的多個藍圖上使用生命週期管理](lifecycle-management-user.md#using-lm-multiple-bp)。

**Topics**
+ [測試套件輸出和合併衝突的生命週期管理](test-lm.md)
+ [使用合併策略來產生套件和指定檔案](merge-strategies-lm.md)
+ [存取專案詳細資訊的內容物件](context-objects-lm.md)

# 測試套件輸出和合併衝突的生命週期管理
<a name="test-lm"></a>

您可以在本機測試藍圖的生命週期管理和合併衝突解決。會產生 `synth/`目錄下的一系列套件，代表生命週期更新的各個階段。若要測試生命週期管理，您可以在藍圖上執行下列 yarn 命令：`yarn blueprint: resynth`若要進一步了解重新合成和套件，請參閱 [重新合成](custom-bp-concepts.md#resynthesis-concept)和 [使用重新合成產生檔案](merge-strategies-lm.md#three-way-merge-lm)。

# 使用合併策略來產生套件和指定檔案
<a name="merge-strategies-lm"></a>

您可以使用合併策略來產生具有重新合成的套件，並指定用於自訂藍圖生命週期管理更新的檔案。透過利用重新合成和合併策略，您可以管理更新，並控制在部署期間更新哪些檔案。您也可以撰寫自己的策略，以控制變更如何合併至現有的 CodeCatalyst 專案。

**Topics**
+ [使用重新合成產生檔案](#three-way-merge-lm)
+ [使用合併策略](#vended-merge-strategies-lm)
+ [指定生命週期管理更新的檔案](#specify-files-lm-updates)
+ [撰寫合併策略](#write-merge-strategies-lm)

## 使用重新合成產生檔案
<a name="three-way-merge-lm"></a>

重新合成可以將藍圖產生的原始程式碼與先前由相同藍圖產生的原始程式碼合併，允許將藍圖的變更傳播到現有專案。合併是從 `resynth()`函數跨藍圖輸出套件執行。重新合成會先產生三個套件，代表藍圖和專案狀態的不同層面。它可以使用 `yarn blueprint:resynth`命令在本機手動執行，如果套件不存在，則會建立套件。手動使用套件可讓您在本機模擬和測試重新合成行為。根據預設，藍圖只會跨 下的儲存庫執行重新合成，`src/*`因為只有該部分的套件通常受來源控制。如需詳細資訊，請參閱[重新合成](custom-bp-concepts.md#resynthesis-concept)。
+ `existing-bundle` - 此套件是現有專案狀態的表示。這是由合成運算人工建構的，以提供藍圖內容，說明其要部署到的專案中的內容 （如果有的話）。如果在本機執行重新合成時，此位置已存在任何內容，則會將其重設並視為模擬。否則，它會設定為 的內容`ancestor-bundle`。
+ `ancestor-bundle` - 如果藍圖輸出是使用一些先前選項和/或版本合成，則此套件代表藍圖輸出。如果這是第一次將此藍圖新增至專案，則祖先不存在，因此設定為與 相同的內容`existing-bundle`。在本機，如果此套件已存在於此位置，則會將其視為模擬。
+ `proposed-bundle` - 如果藍圖是使用一些新選項和/或版本合成，則這是模擬藍圖的套件。這是`synth()`由函數產生的相同套件。在本機，一律會覆寫此套件。

每個套件都是在重新合成階段建立，可從 下的藍圖類別存取`this.context.resynthesisPhase`。
+ `resolved-bundle` - 這是最終套件，這是 CodeCatalyst 專案封裝和部署內容的表示。您可以檢視哪些檔案和差異會傳送到部署機制。這是解析三個其他套件之間合併的`resynth()`函數輸出。

三向合併的套用方式是取得 `ancestor-bundle`和 之間的差異，`proposed-bundle`並將其新增至 `existing-bundle`以產生 `resolved-bundle`。所有合併策略都會將檔案解析為 `resolved-bundle`。重新合成會在 期間透過藍圖的合併策略來解析這些套件的觸角，`resynth()`並從結果產生已解析的套件。

## 使用合併策略
<a name="vended-merge-strategies-lm"></a>

您可以使用藍圖程式庫提供的合併策略。這些策略提供解決 [使用重新合成產生檔案](#three-way-merge-lm)區段中提及之檔案的檔案輸出和衝突的方法。
+ `alwaysUpdate` - 一律解析為提議檔案的策略。
+ `neverUpdate` - 一律解析為現有檔案的策略。
+ `onlyAdd` - 當現有檔案不存在時，解析為提議檔案的策略。否則， 會解析為現有的 檔案。
+ `threeWayMerge` - 在現有、提議和常見上階檔案之間執行三向合併的策略。如果檔案無法完全合併，解析的檔案可能包含衝突標記。提供的檔案內容必須經過 UTF-8 編碼，才能產生有意義的輸出。策略會嘗試偵測輸入檔案是否為二進位檔案。如果策略偵測到二進位檔案中的合併衝突，一律會傳回提議的檔案。
+ `preferProposed` - 在現有、提議和常見上階檔案之間執行三向合併的策略。此策略透過選取每個衝突的提議檔案端來解決衝突。
+ `preferExisting` - 在現有、提議和常見上階檔案之間執行三向合併的策略。此策略透過選取每個衝突的現有檔案端來解決衝突。

若要檢視合併策略的原始程式碼，請參閱[開放原始碼 GitHub 儲存庫](https://github.com/aws/codecatalyst-blueprints/blob/main/packages/blueprints/blueprint/src/resynthesis/merge-strategies/merge-strategies.ts#L17)。

## 指定生命週期管理更新的檔案
<a name="specify-files-lm-updates"></a>

在重新合成期間，藍圖會控制變更如何合併到現有的來源儲存庫。不過，您可能不想將更新推送到藍圖中的每個單一檔案。例如，CSS 樣式表之類的範本程式碼旨在為專案特定。如果您未指定其他策略，則三向合併策略是預設選項。藍圖可以透過在儲存庫建構體上指定合併策略，來指定他們擁有哪些檔案，以及他們不擁有哪些檔案。藍圖可以更新其合併策略，並且可以在重新合成期間使用最新的策略。

```
const sourceRepo = new SourceRepository(this, {
      title: 'my-repo',
    });
    sourceRepo.setResynthStrategies([
      {
        identifier: 'dont-override-sample-code',
        description: 'This strategy is applied accross all sample code. The blueprint will create sample code, but skip attempting to update it.',
        strategy: MergeStrategies.neverUpdate,
        globs: [
          '**/src/**',
          '**/css/**',
        ],
      },
    ]);
```

您可以指定多個合併策略，並以最後一個策略為優先。未涵蓋的檔案預設為three-way-merge，類似於 Git。透過 `MergeStrategies` 建構提供數種合併策略，但您可以自行撰寫。提供的策略遵循 [git 合併策略](https://git-scm.com/docs/merge-strategies)驅動程式。

## 撰寫合併策略
<a name="write-merge-strategies-lm"></a>

除了使用其中一個提供的建置合併策略之外，您也可以撰寫自己的策略。策略必須遵循標準策略界面。您必須撰寫策略函數，從 `existing-bundle`、 `proposed-bundle`和 取得檔案的版本`ancestor-bundle`，並將其合併到單一解析的檔案。例如：

```
type StrategyFunction = (
   /**
   * file from the ancestor bundle (if it exists)
   */
    commonAncestorFile: ContextFile | undefined, 
   /**
   * file from the existing bundle (if it exists)
   */
    existingFile: ContextFile | undefined,
   /**
   * file from the proposed bundle (if it exists)
   */ 
    proposedFile: ContextFile | undefined, 
    options?: {}) 
    /**
    * Return: file you'd like in the resolved bundle
    * passing undefined will delete the file from the resolved bundle
    */ 
=> ContextFile | undefined;
```

如果檔案不存在 （未定義），則該檔案路徑不存在於該特定位置套件中。

**範例：**

```
strategies: [
          {
            identifier: 'dont-override-sample-code',
            description: 'This strategy is applied across all sample code. The blueprint will create sample code, but skip attempting to update it.',
            strategy: (ancestor, existing, proposed) => {
                const resolvedfile = ...
                ...
                // do something
                ...
                return resolvedfile
            },
            globs: [
              '**/src/**',
              '**/css/**',
            ],
          },
        ],
```

# 存取專案詳細資訊的內容物件
<a name="context-objects-lm"></a>

身為藍圖作者，您可以在合成期間從藍圖專案存取內容，以取得空間和專案名稱，或專案來源儲存庫中現有檔案等資訊。您也可以取得詳細資訊，例如藍圖產生的重新合成階段。例如，您可以存取內容，以了解您是否正在重新合成以產生原始套件或提議的套件。然後，可以使用現有的程式碼內容來轉換儲存庫中的程式碼。例如，您可以撰寫自己的重新合成策略來設定特定的程式碼標準。您可以將策略新增至小型藍圖的 `blueprint.ts` 檔案，也可以為策略建立個別的檔案。

下列範例示範如何在專案內容中尋找檔案、設定工作流程建置器，以及為特定檔案設定藍圖提供的重新合成策略：

```
const contextFiles = this.context.project.src.findAll({
      fileGlobs: ['**/package.json'],
    });

    // const workflows = this.context.project.src.findAll({
    //   fileGlobs: ['**/.codecatalyst/**.yaml'],
    // });

    const security = new WorkflowBuilder(this, {
      Name: 'security-workflow',
    });
    new Workflow(this, repo, security.getDefinition());
    repo.setResynthStrategies([
      {
        identifier: 'force-security',
        globs: ['**/.codecatalyst/security-workflow.yaml'],
        strategy: MergeStrategies.alwaysUpdate,
      },
    ]);


    for (const contextFile of contextFiles) {
      const packageObject = JSON.parse(contextFile.buffer.toString());
      new SourceFile(internalRepo, contextFile.path, JSON.stringify({
        ...packageObject,
      }, null, 2));
    }
  }
```