

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 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`를 생성하면 3방향 병합이 적용됩니다. 모든 병합 전략은 파일을 `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방향 병합을 수행하는 전략입니다. 이 전략은 각 충돌에서 기존 파일 측을 선택하여 충돌을 해결합니다.

병합 전략의 소스 코드를 보려면 [open-source GitHub repository](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>

제공된 빌드 병합 전략 중 하나를 사용하는 것 외에도 자체 전략을 작성할 수도 있습니다. 전략은 표준 전략 인터페이스를 준수해야 합니다. `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));
    }
  }
```