GitLab CI/CD 템플릿에 대한 개발 가이드 (사용 중단)

note
CI/CD 카탈로그의 도입과 함께,
GitLab은 더 이상 코드베이스에 새로운 CI/CD 템플릿 기여를 받고 있지 않습니다. 대신,
우리는 팀원들이 카탈로그를 위한 CI/CD 구성 요소를 생성하도록 권장합니다.
이 전환은 우리의 공유 CI/CD 자원의 모듈성과 유지 관리를 강화하고 새로운 CI/CD 템플릿 기여의 복잡성을 피합니다.
기존 템플릿을 업데이트해야 하는 경우, 해당 CI/CD 구성 요소도 업데이트해야 합니다.
해당 CI/CD 템플릿에 맞는 구성 요소가 아직 존재하지 않는다면, 적절한 구성 요소를 생성하는 것을 고려하세요.
이는 템플릿과 구성 요소 기능이 동기화되도록 보장하며 우리의 새로운 개발 관행에 맞추는 것입니다.

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

CI/CD 템플릿 요구 사항

새로운 CI/CD 템플릿 또는 업데이트된 템플릿으로 병합 요청을 제출하기 전에, 다음을 준수해야 합니다:

  • 템플릿을 올바른 디렉토리에 배치하세요.
  • CI/CD 템플릿 작성 가이드라인을 따르세요.
  • 템플릿 이름은 *.gitlab-ci.yml 형식을 따라야 합니다.
  • 유효한 .gitlab-ci.yml 구문을 사용하세요. CI/CD 린트 도구를 사용해 유효성을 확인하세요.
  • 템플릿 메트릭 추가를 하세요.
  • 병합 요청이 사용자에게 영향을 미치는 변경을 도입하는 경우 변경 로그를 포함하세요.
  • 템플릿 검토 프로세스를 따르세요.
  • (선택사항이지만 강력히 권장) 리뷰어가 접근할 수 있는 예제 GitLab 프로젝트에서 템플릿을 테스트하세요.
    리뷰어는 템플릿이 필요한 데이터나 구성을 생성할 수 없기 때문에, 예제 프로젝트는 리뷰어가 템플릿이 올바른지 확인하는 데 도움을 줍니다.
    병합 요청을 리뷰를 위해 제출하기 전에 예제 프로젝트 파이프라인이 성공해야 합니다.

템플릿 디렉토리

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

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

템플릿 작성 가이드라인

다음 가이드라인을 사용하여 템플릿 제출이 기준을 준수하는지 확인하세요:

템플릿 유형

템플릿에는 작성 방식과 사용 방법에 영향을 미치는 두 가지 유형이 있습니다. 템플릿의 스타일은 이 두 가지 유형 중 하나에 맞아야 합니다:

파이프라인 템플릿은 프로젝트의 구조, 언어 등에 맞는 종단 간 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로 가져온 템플릿의 변경 사항이 템플릿을 사용하는 모든 프로젝트의 파이프라인을 중단할 수 있기 때문입니다.

템플릿 작성 시 유의해야 할 추가 사항:

템플릿 디자인 포인트 파이프라인 템플릿 작업 템플릿
전역 키워드, stages 포함 가능합니다. 아니오
작업을 정의할 수 있습니다.
새 파일 UI에서 선택할 수 있습니다. 아니오
include로 다른 작업 템플릿을 포함할 수 있습니다. 아니오
include로 다른 파이프라인 템플릿을 포함할 수 있습니다. 아니오 아니오

문법 지침

템플릿을 쉽게 따를 수 있도록 하기 위해, 모든 템플릿은 명확한 문법 스타일을 사용하고 일관된 형식을 가져야 합니다.

각 작업의 before_script, script, 및 after_script 키워드는 ShellCheck를 사용하여 검사되며, 가능한 한 쉘 스크립팅 표준 및 스타일 지침을 따라야 합니다.

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 "예시 작업 1"

job2:
  only:
    variables:
      - $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    echo "예시 작업 2"

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

가능한 경우 only 또는 except 사용을 피하세요.

Only와 except는 더 이상 개발되고 있지 않으며, 이제 rules가 선호되는 문법입니다:

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

긴 명령을 나누세요

명령이 매우 길거나 -o 또는 --option과 같은 많은 명령 줄 플래그가 있는 경우:

  • 이러한 명령을 여러 줄 명령으로 나누어 명령의 모든 부분을 쉽게 볼 수 있도록 하세요.
  • 플래그의 긴 이름을 사용할 수 있을 때 사용하세요.

예를 들어 짧은 CLI 플래그가 있는 긴 명령인 docker run --e SOURCE_CODE="$PWD" -v "$PWD":/code -v /var/run/docker.sock:/var/run/docker.sock "$CODE_QUALITY_IMAGE" /code의 경우:

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 키워드와 함께 사용해야 하는지 여부.
  • 프로젝트의 CI/CD 설정에 저장해야 하는 변수.
# 이 템플릿을 사용하여 ABC 서버를 사용하는 응용 프로그램을 게시하세요.
# 이 템플릿을 새 `.gitlab-ci.yml` 파일로 복사 및 붙여넣기할 수 있습니다.
# 이 템플릿을 기존의 `.gitlab-ci.yml` 파일에 `include:` 키워드를 사용하여 추가하지 않아야 합니다.
#
# 요구 사항:
# - /content에 저장된 콘텐츠와 /test에 저장된 테스트가 있는 ABC 프로젝트.
# - 프로젝트 CI/CD 설정에 저장된 ABC-PASSWORD라는 이름의 CI/CD 변수. 값은
#   ABC 서버에 배포하는 데 사용되는 비밀번호여야 합니다.
# - 포트 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 키워드를 통해 제공될 변수를 예상하는 경우, 해당 변수는 대문자 이름과 단어를 구분하는 언더스코어(_)를 사용해야 합니다.

.with_login:
  before_script:
    # SECRET_TOKEN은 프로젝트 설정을 통해 제공되어야 합니다
    - echo "$SECRET_TOKEN" | docker login -u my-user --password-stdin 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에서 CI/CD 변수를 TARGET_URL로 지정함으로써 가능합니다:

include:
  template: Performance.gitlab-ci.yml

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

템플릿의 작업 이름인 performancebrowser-performance로 변경되면, 사용자의 .gitlab-ci.yml는 더 이상 포함된 템플릿에 performance라는 이름의 작업이 없기 때문에 즉시 린트 오류가 발생합니다. 따라서 사용자는 자신의 .gitlab-ci.yml을 수정해야 하며, 이는 그들의 작업 흐름에 지장을 줄 수 있습니다.

버전 관리 섹션을 읽어보세요. 안전하게 주요 변경 사항을 도입하세요.

버전 관리

현재 템플릿에 의존하는 기존 프로젝트에 영향을 미치지 않도록 파괴적인 변경 사항을 도입하려면 안정적인최신 버전 관리를 사용하세요.

안정적인 템플릿은 일반적으로 주요 버전 릴리스에서만 파괴적인 변경을 받으며, 최신 템플릿은 어떤 릴리스에서도 파괴적인 변경을 받을 수 있습니다. 주요 릴리스 이정표에서 최신 템플릿이 새로운 안정적인 템플릿으로 설정되며, 최신 템플릿은 삭제될 수 있습니다.

최신 템플릿을 추가하는 것은 안전하지만 유지 관리 부담이 따릅니다:

  • GitLab은 다음 주요 GitLab 릴리스에서 최신 템플릿의 내용을 사용하여 안정적인 템플릿을 교체할 책임이 있는 DRI를 선택해야 합니다. DRI는 변경으로 인해 문제가 발생한 사용자 지원을 담당합니다.
  • 새로운 비파괴적 변경을 수행할 때, 안정적인 템플릿과 최신 템플릿 모두 가능한 한 일치하도록 업데이트해야 합니다.
  • 최신 템플릿은 여러 사용자가 계속 존재하는 것에 직접 의존할 수 있으므로 예정보다 오랫동안 남아 있을 수 있습니다.

새로운 최신 템플릿을 추가하기 전에, 변경 사항이 안정적인 템플릿에 대해 수행될 수 있는지 확인하세요. 복사-붙여넣기 용도로만 intended된 템플릿인 경우, 안정적인 버전을 직접 변경하는 것이 가능할 수 있습니다. 파괴적인 변경으로 인해 소문자 마일스톤에서 안정적인 템플릿을 변경하기 전에 확인하십시오:

안정적인 버전

안정적인 CI/CD 템플릿은 주요 릴리스 이정표에서만 파괴적인 변경을 도입하는 템플릿입니다. 안정적인 템플릿의 이름을 <template-name>.gitlab-ci.yml로 지정하세요. 예: Jobs/Deploy.gitlab-ci.yml.

15.0과 같이 GitLab의 주요 릴리스에서 사용 가능한 최신 템플릿을 복사하여 새로운 안정적인 템플릿을 만들 수 있습니다. 모든 파괴적인 변경 사항은 버전별 사용 중단 및 제거 페이지에서 발표해야 합니다.

안정적인 템플릿 버전은 다음과 같은 경우에 마이너 GitLab 릴리스인 15.1에서 변경할 수 있습니다.

최신 버전

latest로 표시된 템플릿은 모든 릴리스에서 업데이트할 수 있으며, 파괴적인 변경을 포함할 수 있습니다. 최신 버전으로 간주되는 경우 템플릿 이름에 .latest를 추가하세요. 예: Jobs/Deploy.latest.gitlab-ci.yml.

파괴적인 변경을 도입할 때는,

반드시 업그레이드 경로를 테스트하고 문서화해야 합니다.

일반적으로 최신 템플릿을 최상의 옵션으로 홍보하지 않아야 합니다. 이는 사용자에게 예기치 않은 문제로 놀라움을 줄 수 있기 때문입니다.

latest 템플릿이 아직 존재하지 않는 경우, 안정적인 템플릿을 복사할 수 있습니다.

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

사용자는 현재 GitLab 패키지에 포함되지 않은 이전 안정적인 템플릿을 사용하고 싶어할 수 있습니다. 예를 들어, GitLab 15.0과 GitLab 16.0의 안정적인 템플릿이 상당히 다를 수 있으므로, 사용자가 GitLab 16.0으로 업그레이드한 후에도 GitLab 15.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. 파이프라인을 실행하고 모든 가능성(case)에서 정상적으로 실행되는지 확인합니다 (병합 요청 파이프라인, 일정 등을 포함하여).

  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 (GitLab 팀 구성원만 해당)에서 확인할 수 있습니다. 템플릿을 선택하여 해당 템플릿의 그래프를 볼 수 있습니다.

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

  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은 코드를 검토할 수 있는 한 명의 검토자와 한 명의 유지관리자를 제안합니다. 병합 요청이 검토를 위해 준비되면, mention 검토자에게 언급하고 CI/CD 템플릿 변경 사항을 검토해 달라고 요청하세요. CI/CD 템플릿 MR에 대한 DangerBot 작업 추가에 대한 세부정보를 참조하세요.