GitLab CI/CD 템플릿 개발 안내서

참고: CI/CD 카탈로그가 소개되면서, GitLab은 더 이상 코드베이스에 새 CI/CD 템플릿을 받지 않습니다. 대신, 우리는 팀원들이 CI/CD 구성 요소를 카탈로그를 위해 생성하기를 권장합니다. 이 전환으로 우리의 공유 CI/CD 리소스의 모듈화 및 유지보수성이 향상되며, 새로운 CI/CD 템플릿을 기여하는 복잡함을 피할 수 있습니다. 기존 템플릿을 업데이트해야 하는 경우 해당 CI/CD 구성 요소도 업데이트해야 합니다. 아직 해당하는 CI/CD 템플릿과 일치하는 구성 요소가 없다면, 일치하는 구성 요소를 생성하십시오. 이렇게 함으로써 템플릿과 구성 요소의 기능이 동기화되어 새로운 개발 관행에 부합하도록 할 수 있습니다.

이 문서는 GitLab CI/CD 템플릿을 개발하는 방법에 대해 설명합니다.

CI/CD 템플릿 요구 사항

새로운 또는 업데이트된 CI/CD 템플릿을 merge(통합) 요청하기 전에 반드시 다음을 준수해야 합니다:

  • 템플릿을 올바른 디렉터리에 배치합니다.
  • CI/CD 템플릿 작성 지침을 준수합니다.
  • *.gitlab-ci.yml 형식을 따르는 이름으로 템플릿을 지정합니다.
  • 유효한 .gitlab-ci.yml 구문을 사용합니다. CI/CD lint 도구를 사용하여 유효성을 검사합니다.
  • 템플릿 메트릭을 추가합니다.
  • merge(통합) 요청이 사용자에게 노출되는 변경을 가져오는 경우 변경 로그를 포함합니다.
  • 템플릿 검토 프로세스를 따릅니다.
  • (선택 사항이지만 강력히 권장) 리뷰어가 접근할 수 있는 예제 GitLab 프로젝트에서 템플릿을 테스트합니다. 리뷰어는 템플릿이 올바른지 확인하는 데 필요한 데이터나 구성을 생성할 수 없을 수 있으므로 예제 프로젝트가 merge(통합) 요청 전에 진행되어야 합니다.

템플릿 디렉터리

모든 템플릿 파일은 lib/gitlab/ci/templates에 저장됩니다. 일반 템플릿은 이 디렉터리에 저장하지만, 특정 템플릿 유형은 해당 디렉터리가 예약되어 있습니다. 새 파일 UI에서 템플릿을 선택할 수 있는지 여부는 템플릿이 위치한 디렉터리에 따라 결정됩니다:

서브 디렉터리 UI에서 선택 가능 템플릿 유형
/* (루트) 일반 템플릿
/AWS/* 아니요 클라우드 배포(AWS)와 관련된 템플릿
/Jobs/* 아니요 Auto DevOps와 관련된 템플릿
/Pages/* GitLab Pages와 함께 정적 사이트 생성기를 사용하는 샘플 템플릿
/Security/* 보안 스캐너와 관련된 템플릿
/Terraform/* 아니요 인프라스트럭처를 위한 코드(Terraform)와 관련된 템플릿
/Verify/* 테스트 기능과 관련된 템플릿
/Workflows/* 아니요 workflow: 키워드를 사용하는 샘플 템플릿

템플릿 작성 지침

귀하의 템플릿 제출이 표준을 준수하는지 확인하기 위해 다음 지침을 사용합니다:

템플릿 유형

템플릿에는 템플릿이 작성되고 사용되는 방식에 영향을 주는 두 가지 다른 유형이 있습니다. 템플릿의 스타일은 이 두 가지 유형 중 하나와 일치해야 합니다:

파이프라인 템플릿은 프로젝트의 구조, 언어 등과 일치하는 end-to-end CI/CD 워크플로우를 제공합니다. 일반적으로 .gitlab-ci.yml 파일이 없는 프로젝트에서만 사용해야 합니다.

파이프라인 템플릿을 작성할 때:

  • image 또는 before_script와 같은 전역 키워드를 템플릿 상단의 default 섹션에 배치합니다.
  • 템플릿이 기존의 .gitlab-ci.yml 파일에서 includes 키워드와 함께 사용되도록 설계되었는지 코드 주석으로 명확하게 표시합니다.

작업 템플릿은 특정 작업을 수행하기 위해 기존 CI/CD 워크플로우에 추가할 수 있는 특정 작업을 제공합니다. 이 템플릿은 주로 includes 키워드를 사용하여 기존의 .gitlab-ci.yml 파일에 추가함으로써 사용해야 합니다. 또는 템플릿 내용을 기존의 .gitlab-ci.yml 파일에 복사하여 사용할 수도 있습니다.

사용자가 현재의 파이프라인에 템플릿을 매우 적은 수정 또는 수정 없이 추가할 수 있도록 작업 템플릿을 구성해야 합니다. 다른 파이프라인 구성과 충돌하는 위험을 줄이기 위해 템플릿을 구성해야 합니다.

작업 템플릿을 작성할 때:

  • 전역 또는 default 키워드를 사용하지 않습니다. 루트 .gitlab-ci.yml이 템플릿을 포함할 때, 전역 또는 기본 키워드가 재정의되어 예기치 않은 동작을 일으킬 수 있습니다. 작업 템플릿이 특정 스테이지를 요구하는 경우, 사용자가 주요 .gitlab-ci.yml 구성에 스테이지를 수동으로 추가해야 한다는 사실을 코드 주석에 명확히 설명합니다.
  • 코드 주석에서 템플릿이 includes 키워드와 함께 사용하도록 설계되었는지 또는 기존 구성에 복사하여 사용하도록 표시합니다.
  • 버전 관리를 고려해 최신 및 안정적인 버전을 사용하여 템플릿의 역호환성 문제를 방지합니다. includes로 가져오는 템플릿의 유지 보수가 복잡해지므로 최신 및 안정적인 버전으로 템플릿을 관리해야 합니다.

템플릿을 작성할 때 유념해야 할 추가 사항:

템플릿 디자인 포인트 파이프라인 템플릿 작업 템플릿
stages를 포함한 전역 키워드 사용 가능 아니요
작업을 정의할 수 있음
새 파일 UI에서 선택 가능 아니요
다른 작업 템플릿을 include 키워드로 포함 가능 아니요
다른 파이프라인 템플릿을 include 키워드로 포함 가능 아니요 아니요

구문 가이드라인

템플릿을 더 쉽게 따르기 위해, 템플릿은 모두 일관된 형식을 갖춘 명확한 구문 스타일을 사용해야합니다.

모든 작업의 before_script, script, 그리고 after_script 키워드는 ShellCheck를 사용하여 린트 처리되어야 하며, Shell 스크립팅 표준 및 스타일 가이드라인을 가능한 한 준수해야 합니다.

ShellCheck는 해당 스크립트가 Bash를 사용하여 실행되도록 설계되었다고 가정합니다. Bash ShellCheck 규칙과 호환되지 않는 쉘에 대해 작성된 템플릿은 ShellCheck 린트 처리에서 제외될 수 있습니다. 스크립트를 제외하려면 scripts/lint_templates_bash.rbEXCLUDED_TEMPLATES 목록에 해당 스크립트를 추가하세요.

기본 브랜치를 하드코딩하지 마세요

하드코딩된 main 브랜치 대신에 $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH를 사용하고, 절대 master를 사용하지 마세요.

job1:
  rules:
    if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    echo "example job 1"

job2:
  only:
    variables:
      - $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    echo "example job 2"

only 또는 except 대신 rules를 사용하세요

가능한 경우, only 또는 except 사용을 피하세요. Only와 except는 더 이상 개발되지 않으며, rules이 이제 권장되는 구문입니다.

job2:
  script:
    - echo
  rules:
    - if: $CI_COMMIT_BRANCH

긴 명령을 분할하세요

명령어가 매우 길거나 -o 또는 --option과 같은 많은 명령행 플래그가 있는 경우 다음을 수행하세요:

  • 명령의 각 부분을 쉽게 볼 수 있도록 여러 줄로 나누세요.
  • 가능한 경우 플래그에 대해서는 긴 이름을 사용하세요.

예를 들어, -o--option과 같은 짧은 CLI 플래그가 있는 긴 명령에 대해 다음과 같이 여러 줄로 나눌 수 있습니다.

job1:
  script:
    - docker run
        --env SOURCE_CODE="$PWD"
        --volume "$PWD":/code
        --volume /var/run/docker.sock:/var/run/docker.sock
        "$CODE_QUALITY_IMAGE" /code

또한, |> YAML 연산자를 사용하여 여러 줄로 된 명령어를 분할할 수도 있습니다.

템플릿 설명에 주석 사용

새 파일 메뉴에서 템플릿 내용에 액세스할 수 있으며, 이것이 사용자가 템플릿에 대한 정보를 볼 수 있는 유일한 장소일 수 있습니다. 템플릿 내 자체에서 템플릿의 동작을 명확하게 문서화하는 것이 중요합니다.

다음 가이드라인은 모든 템플릿 제출에서 기대되는 기본 주석을 다룹니다. 사용자나 템플릿 리뷰어에게 도움이 될 것으로 생각되는 경우 추가 주석을 추가하세요.

요구 사항 및 기대 사항 설명

파일 상단에 # 주석을 사용하여 템플릿 사용 방법에 대한 세부 정보를 제공하세요. 이는 다음을 포함합니다.

  • 저장소/프로젝트 요구 사항.
  • 예상 동작.
  • 템플릿을 사용하기 전에 사용자가 편집해야 하는 부분.
  • 기존 파이프라인의 include 키워드를 사용하여 구성 파일에 복사하여 템플릿을 사용해야 하는지, 아니면 새로운 .gitlab-ci.yml 파일에 복사하여 사용해야 하는지 여부.
  • 프로젝트의 CI/CD 설정에 저장해야 하는 변수가 있는지 여부.
# ABC 서버를 사용하는 애플리케이션을 게시하기 위해 이 템플릿을 사용합니다.
# 이 템플릿을 새로운 `.gitlab-ci.yml` 파일에 복사하여 사용하세요.
# 기존 `.gitlab-ci.yml` 파일에 `include:` 키워드를 사용하여 이 템플릿을 추가해서는 안됩니다.
#
# 요구 사항:
# - /content에 저장된 ABC 프로젝트와 /test에 테스트가 있어야 합니다.
# - 프로젝트 CI/CD 설정에 ABC-PASSWORD라는 CI/CD 변수가 있어야 합니다. 값을
#   설정하려는암호가 되어야 합니다.
# - 12345 포트에서 수신 대기하도록 구성된 ABC 서버가 있어야 합니다.
#
# 123번째 줄의 URL을 ABC 서버 및 포트를 가리키도록 변경해야 합니다.
#
# 자세한 정보는 https://gitlab.com/example/abcserver/README.md을 참조하세요.

job1:
  ...

변수가 템플릿 동작에 미치는 영향 설명

템플릿이 변수를 사용하는 경우, 해당 변수가 처음 정의되는 위치에 # 주석으로 설명하세요. 변수가 명백한 경우 주석을 생략할 수 있습니다.

variables:                        # 예를 들어 여기에 주석을 추가하는 것이 좋습니다:
  TEST_CODE_PATH: <path/to/code>  # Ruby 스펙의 상대 경로로 이 변수를 업데이트하세요.

job1:
  variables:
    ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid"  # (여기에 주석을 추가할 필요가 없습니다. 이미 명확합니다.)
  script:
    - echo ${ERROR_MESSAGE}
#### 비-로컬 변수에 대문자로 이름 지정

CI/CD 설정을 통해 변수가 제공될 것으로 예상되거나 `variables` 키워드를 통해 변수가 제공된다면 해당 변수는 밑줄(`_`)로 단어를 구분하여 대문자로 이름을 지정해야 합니다.

```yaml
.with_login:
  before_script:
    # SECRET_TOKEN은 프로젝트 설정을 통해 제공되어야 합니다
    - docker login -u my-user -p "$SECRET_TOKEN my-registry

script 키워드 중 하나에서 로컬로 정의된 변수에는 소문자 이름을 선택적으로 사용할 수 있습니다:

job1:
  script:
    - response="$(curl "https://example.com/json")"
    - message="$(echo "$response" | jq -r .message)"
    - 'echo "서버 응답: $message"'

하위 호환성

include:template: 키워드를 사용하여 템플릿을 동적으로 포함할 수 있습니다. 기존 템플릿을 변경하는 경우 기존 프로젝트의 CI/CD가 깨지지 않도록 반드시 확인해야 합니다.

예를 들어, 템플릿의 작업 이름을 변경하면 기존 프로젝트의 파이프라인이 깨질 수 있습니다. 예를 들어, 다음과 같은 내용의 Performance.gitlab-ci.yml이라는 템플릿이 있다고 가정해보겠습니다:

performance:
  image: registry.gitlab.com/gitlab-org/verify-tools/performance:v0.1.0
  script: ./performance-test $TARGET_URL

그리고 사용자가 이 템플릿을 포함시켜 performance 작업에 인수를 전달합니다. 이를 사용자의 .gitlab-ci.yml에서 performance 작업에 TARGET_URL CI/CD 변수로 지정하여 수행할 수 있습니다:

include:
  template: Performance.gitlab-ci.yml

performance:
  variables:
    TARGET_URL: https://awesome-app.com

performance 작업의 작업 이름이 템플릿에서 browser-performance로 변경된다면 사용자의 .gitlab-ci.yml은 즉시 린트 오류를 발생시킵니다. 왜냐하면 더 이상 템플릿에 performance라는 작업이 없기 때문입니다. 따라서 사용자는 자신의 워크플로가 방해받을 수 있으므로 .gitlab-ci.yml을 수정해야 합니다.

버전 관리 섹션을 참조하여 깨지는 변경을 안전하게 도입하세요.

버전 관리

현재 템플릿에 의존하는 기존 프로젝트에 영향을 미치지 않고 깨지는 변경을 도입하려면 안정 버전최신 버전을 사용하세요.

안정한 템플릿은 보통 주요 버전 릴리스에서만 깨지는 변경을 받습니다. 반면에 최신 템플릿은 어떤 릴리스에서든 깨지는 변경을 받을 수 있습니다. 주요 릴리스에서 최신 템플릿이 새로운 안정 템플릿이 되며(최신 템플릿은 삭제될 수 있음), 안정 템플릿에서 깨지는 변경이 발생합니다.

새로운 최신 템플릿 추가는 안전하지만 유지 보수 부담을 동반합니다:

  • GitLab은 안정 템플릿을 다음 주요 릴리스에서 최신 템플릿으로 덮어쓸 DRI를 선택해야 합니다. 해당 DRI는 변경에 문제가 있는 사용자를 지원하는 책임이 있습니다.
  • 새로운 깨지는 변경이 생기면 안정 및 최신 템플릿이 가능한 한 일치하도록 업데이트되어야 합니다.
  • 최신 템플릿은 많은 사용자가 계속해서 존재할 것으로 예상되기 때문에 계획보다 오랫동안 남아 있을 수 있습니다.

새로운 최신 템플릿을 추가하기 전에 깨지는 변경이 안정 템플릿에서도 가능한지 확인하세요. 템플릿이 복사하여 사용되는 것이 의도된 경우, 안정 버전을 직접 변경할 수도 있습니다. 작은 주요 변경으로 안정 템플릿을 변경하기 전에 확인하세요:

  • 파이프라인 템플릿이며 include와 사용되지 않도록 설명하는 코드 주석.
  • CI/CD 템플릿 사용 메트릭이 해당 템플릿의 사용 양을 보여주지 않는지 확인하세요. 해당 템플릿의 메트릭이 제로인 경우, 해당 템플릿이 include와 함께 활발하게 사용되고 있지 않음을 나타냅니다.

안정 버전

안정한 CI/CD 템플릿이란, 주요 릴리스에서만 깨지는 변경을 받는 템플릿입니다. 템플릿의 안정 버전은 <템플릿-이름>.gitlab-ci.yml와 같이 이름을 붙입니다. 예를 들어, Jobs/Deploy.gitlab-ci.yml처럼 말입니다.

안정 템플릿을 새로 만들 때는 예를 들어 13.0과 같은 주요 릴리스에서 제공되는 최신 템플릿을 복사합니다. 모든 깨지는 변경은 공식 릴리스 전에 블로그 포스트 등을 통해 발표되어야 합니다. 예를 들어, GitLab.com은 13.0으로 이동하여, 깨지는 변경이 적습니다와 같이 말입니다.

안정한 템플릿을 13.1과 같은 마이너 GitLab 릴리스에서 변경할 수 있으면서:

최신 버전

최신으로 표시된 템플릿은 어떤 릴리스에서든 업데이트할 수 있습니다. 심지어 깨지는 변경이 있는 경우에도 해당 변경의 업그레이드 경로를 테스트하고 문서화해야 합니다. 일반적으로 최신 템플릿을 최상의 옵션으로 홍보하지 않아야 합니다. 사용자들이 예상치 못한 문제로 놀라지 않도록하는 것이 좋습니다.

최신 템플릿이 아직 존재하지 않는 경우 안정 템플릿을 복사할 수 있습니다. ```

이전 안정적인 템플릿 포함하는 방법

사용자는 현재 GitLab 패키지에 번들되지 않은 이전 안정된 템플릿을 사용하고 싶어할 수 있습니다. 예를 들어, GitLab 13.0과 GitLab 14.0의 안정된 템플릿이 너무 다르기 때문에 사용자가 GitLab 14.0으로 업그레이드한 후에도 GitLab 13.0 템플릿을 계속 사용하길 원할 수 있습니다.

템플릿이나 설명서에 노트를 추가하여 include:remote를 사용하여 이전 템플릿 버전을 포함하는 방법을 설명할 수 있습니다. 다른 템플릿이 include: template로 포함된 경우, 이를 include: remote와 결합할 수 있습니다:

# v14에 포함되지 않은 v13 안정 템플릿을 사용하려면, `include:remote:` 키워드를 사용하여 원격 템플릿 저장소에서 특정 템플릿을 가져옵니다.
# GitLab의 공식 프로젝트에서 가져오는 경우, 다음 URL 포맷을 사용하세요:
# https://gitlab.com/gitlab-org/gitlab/-/raw/<version>/lib/gitlab/ci/templates/<template-name>
include:
  - template: Auto-DevOps.gitlab-ci.yml
  - remote: https://gitlab.com/gitlab-org/gitlab/-/raw/v13.0.1-ee/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml

추가 자료

GitLab CI/CD 템플릿에 버전 관리 개념을 소개하는 것에 관한 오픈 이슈가 있습니다. 진행 상황을 확인하려면 해당 이슈를 확인하세요.

테스트

각 CI/CD 템플릿은 배포해도 안전한지 확인하려면 테스트해야 합니다.

수동 QA

최소한의 데모 프로젝트에서 템플릿을 테스트하는 것은 항상 좋은 실천 방법입니다. 아래 단계를 따라 데모 프로젝트에서 템플릿을 테스트하세요:

  1. https://gitlab.com에서 공개 샘플 프로젝트를 만드세요.
  2. 제안된 템플릿을 포함한 프로젝트에 .gitlab-ci.yml을 추가하세요.
  3. 모든 가능한 경우(병합 요청 파이프라인, 스케줄 등)에서 모든 것이 올바르게 작동하는지 확인하기 위해 파이프라인을 실행하세요.
  4. 새로운 템플릿을 추가하는 병합 요청의 설명에 프로젝트에 대한 링크를 추가하세요.

이는 리뷰어들이 템플릿을 안전하게 병합할 수 있는지 확인하는 데 유용한 정보입니다.

새 템플릿을 UI에서 선택할 수 있는지 확인

특정 디렉토리 아래에 있는 템플릿도 새 파일 UI에서 선택할 수 있습니다. 해당 디렉토리 중 하나에 템플릿을 추가할 때, 해당 템플릿이 드롭다운 목록에 올바르게 표시되는지 확인하세요:

CI/CD 템플릿 선택

RSpec 테스트 작성

파이프라인 작업이 올바르게 생성되는지 확인하기 위해 RSpec 테스트를 작성해야 합니다:

  1. spec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb에 테스트 파일을 추가하세요.
  2. Ci::CreatePipelineService를 통해 파이프라인 작업이 올바르게 생성되는지 테스트하세요.

호환성 파악

최신 템플릿에 호환되지 않는 변경 사항을 도입할 때는:

  1. 안정적인 템플릿에서 업그레이드 경로를 테스트하세요.
  2. 사용자가 마주칠 수 있는 오류 유형을 확인하세요.
  3. 해결 방법 가이드로 문서화하세요.

이 정보는 안정된 템플릿이 주요 버전의 GitLab 릴리스에서 업데이트될 때 사용자에게 중요합니다.

메트릭 추가하기

각 CI/CD 템플릿은 사용 추적을 위해 메트릭이 정의되어 있어야 합니다. CI/CD 템플릿의 월 사용량 보고서는 Sisense(깃랩 팀 멤버 전용)에서 확인할 수 있습니다. 단일 템플릿에 대한 그래프를 보려면 템플릿을 선택하세요.

새로운 템플릿에 대한 메트릭 정의를 추가하려면:

  1. GitLab GDK를 설치하고 시작하세요.
  2. GDK 내의 gitlab 디렉토리에서 새 템플릿이 포함된 브랜치를 확인하세요.
  3. 새 템플릿 이벤트 이름을 주간 및 월간 CI/CD 템플릿 총 합 계수 메트릭에 추가하세요:
  4. 다음 명령어를 사용하여 새 메트릭 정의를 추가하세요. 위의 이벤트 이름과 동일한 이벤트 이름을 마지막 인수로 사용하세요:

    bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates <template_metric_event_name>
    

    아래와 같은 출력이 나와야 합니다:

    $ bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates p_ci_templates_my_template_name
          create  config/metrics/counts_7d/20220120073740_p_ci_templates_my_template_name_weekly.yml
          create  config/metrics/counts_28d/20220120073746_p_ci_templates_my_template_name_monthly.yml
    
  5. 두 파일을 다음과 같이 편집하세요:

    • name:performance_indicator_type:: 삭제하세요(필요 없음).
    • introduced_by_url:: 템플릿을 추가하는 MR의 URL.
    • data_source:: redis_hll로 설정하세요.
    • description: 이 메트릭이 무엇을 세는지 간단히 설명하세요. 예를 들어, 최신 Auto Deploy 템플릿을 사용하는 파이프라인의 수
    • product_*: 섹션, 스테이지, 그룹, 피쳐 카테고리에 따라 (관련 메트릭 사전 가이드) 설정하세요. 만약 이 키워드에 대해 확실하지 않다면, 병합 요청에서 도움을 요청할 수 있습니다.
    • 각 파일 뒷부분에 다음을 추가하세요:

      options:
        events:
          - p_ci_templates_my_template_name
      
  6. 변경 사항을 커밋하고 푸시하세요.

예를 들어, 5분 프로덕션 앱 템플릿에 대한 메트릭 구성 파일은 다음과 같습니다:

보안

템플릿에는 악의적인 코드가 포함될 수 있습니다. 예를 들어 작업 내에서 export 셸 명령을 포함하는 템플릿은 실수로 작업 로그에서 비밀 프로젝트 CI/CD 변수를 노출할 수 있습니다. 안전한지 확신이 들지 않는다면 보안 전문가에게 상호 검증을 요청해야 합니다.

CI/CD 템플릿 병합 요청에 기여하기

CI/CD 템플릿 MR이 생성되고 ci::templates로 레이블이 지정된 경우, DangerBot은 코드를 검토할 수 있는 리뷰어와 유지 관리자를 한 명씩 제안합니다. 병합 요청이 검토 준비가 되면, 언급하여 리뷰어에게 CI/CD 템플릿 변경 사항을 검토해 달라고 요청하세요. CI/CD 템플릿 MR에 대한 DangerBot 작업의 자세한 내용을 확인하세요.