

Amazon CodeCatalyst は新規のお客様には提供されなくなりました。既存のお客様は、通常どおりサービスを引き続き使用できます。詳細については、「[CodeCatalyst から移行する方法](migration.md)」を参照してください。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ブループリント作成者としてライフサイクル管理を使用する
<a name="lifecycle-management-dev"></a>

ライフサイクル管理を使用すると、ベストプラクティスの 1 つの共通のソースから多数のプロジェクトを同期させることができます。これにより、ソフトウェア開発ライフサイクル全体にわたって、修正の伝播と無数のプロジェクトのメンテナンスをスケールさせることができます。ライフサイクル管理を使用すると、内部キャンペーン、セキュリティ修正、監査、ランタイムアップグレード、ベストプラクティスの変更などのメンテナンスプラクティスが合理化されます。こうした基準が 1 か所で定義され、新しい基準が公開された場合も自動的に最新の状態に保たれるためです。

新しいバージョンのブループリントが公開されると、そのブループリントを含むすべてのプロジェクトが最新バージョンに更新するよう求められます。ブループリント作成者は、コンプライアンス上の目的で、各プロジェクトに含まれる特定のブループリントのバージョンを確認することもできます。既存のソースリポジトリに競合がある場合、ライフサイクル管理によってプルリクエストが作成されます。開発環境などの他のすべてのリソースでは、ライフサイクル管理によるすべての更新で、厳密に新しいリソースが作成されます。ユーザーは、このプルリクエストをマージするかしないかを自由に決めることができます。保留中のプルリクエストがマージされると、プロジェクトで使用されるオプションを含むブループリントのバージョンが更新されます。ブループリントユーザーとしてのライフサイクル管理の使用については、「[既存のプロジェクトでライフサイクル管理を使用する](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()` 関数から実行されます。再合成では、まずブループリントとプロジェクト状態のさまざまな側面を表す 3 つのバンドルが生成されます。`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 プロジェクトにパッケージ化およびデプロイされる内容を表します。デプロイメカニズムにどのファイルと差分が送信されるかを確認できます。これは、他の 3 つのバンドル間のマージを解決する `resynth()` 関数の出力です。

3 方向マージは、`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` - 既存のファイル、提案されたファイル、共通の祖先ファイル間で 3 方向マージを実行する戦略。ファイルをクリーンにマージできない場合、解決されたファイルに競合マーカーが含まれている可能性があります。戦略で意味のある出力を得るには、提供されたファイルの内容が UTF-8 でエンコードされている必要があります。この戦略は、入力ファイルがバイナリかどうかを検出しようとします。バイナリファイルでマージ競合が検出された場合、常に提案されたファイルが返されます。
+ `preferProposed` - 既存のファイル、提案されたファイル、共通の祖先ファイル間で 3 方向マージを実行する戦略。この戦略は、各競合の提案されたファイル側を選択することで競合を解決します。
+ `preferExisting` - 既存のファイル、提案されたファイル、共通の祖先ファイル間で 3 方向マージを実行する戦略。この戦略では、各競合の既存のファイル側を選択して競合を解決します。

マージ戦略のソースコードを確認するには、[オープンソースの 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 スタイルシートのようなサンプルコードは、プロジェクト固有のものです。別の戦略を指定しない場合、3 方向マージ戦略がデフォルトのオプションとなります。ブループリントは、リポジトリ構造自体のマージ戦略を指定することで、どのファイルを所有し、どのファイルを所有しないかを指定することができます。ブループリントはマージ戦略を更新でき、最新の戦略は再合成時に使用できます。

```
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/**',
        ],
      },
    ]);
```

複数のマージ戦略を指定でき、最新の戦略が優先されます。指定のないファイルは、デフォルトで Git に似た 3 方向マージになります。`MergeStrategies` コンストラクトを通じて提供されるマージ戦略はいくつかありますが、独自のマージ戦略を記述することもできます。提供される戦略は、[git マージ戦略](https://git-scm.com/docs/merge-strategies)ドライバーに準拠しています。

## マージ戦略を記述する
<a name="write-merge-strategies-lm"></a>

提供されているビルドマージ戦略の 1 つを使用するほかに、独自の戦略を作成することもできます。戦略は、標準戦略インターフェイスに従う必要があります。`existing-bundle`、`proposed-bundle`、`ancestor-bundle` からファイルの複数のバージョンを取得し、それらを 1 つの解決済みファイルにマージする戦略関数を記述する必要があります。例:

```
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));
    }
  }
```