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 템플릿으로 병합 요청을 제출하기 전에 다음 사항을 준수해야 합니다:

  • 템플릿을 올바른 디렉터리에 배치하십시오.
  • 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 워크플로우를 제공하는 파이프라인 템플릿과, 특정 작업을 수행하기 위해 기존 CI/CD 워크플로우에 추가할 수 있는 작업 템플릿이라는 두 가지 유형이 있습니다. 템플릿에서 스타일은 이 두 유형 중 하나와 일치해야 합니다.

파이프라인 템플릿 작성 시:

  • image 또는 before_script와 같은 전역 키워드를 템플릿 상단에 default 섹션에 배치하십시오.
  • 템플릿이 기존의 .gitlab-ci.yml 파일의 includes 키워드와 함께 사용되도록 설계되었는지, 코드 주석을 명확히 남겨주십시오.

작업 템플릿 작성 시:

  • 전역 또는 default 키워드를 사용하지 마십시오. 루트 .gitlab-ci.yml이 템플릿을 포함하는 경우, 전역 또는 기본 키워드가 재정의되어 예기치 않은 동작을 일으킬 수 있습니다. 작업 템플릿이 특정 스테이지를 필요로 하는 경우, 메인 .gitlab-ci.yml 설정에 스테이지를 수동으로 추가해야 한다는 것을 코드 주석으로 명확히 설명하십시오.
  • 템플릿이 includes 키워드와 함께 사용하도록 설계되었는지 또는 기존 구성에 복사하여 추가할 수 있도록 코드 주석을 명확히 남겨주십시오.
  • 역호환성 문제를 피하기 위해 최신 버전 및 안정 버전과 함께 템플릿에 버전을 지정해야 합니다. includes로 가져온 템플릿을 유지하는 일은 더 복잡합니다. 왜냐하면 변경사항이 프로젝트의 모든 템플릿을 사용하는 파이프라인을 망가뜨릴 수 있기 때문입니다.

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

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

구문 지침

템플릿을 이해하기 쉽게 만들기 위해, 모든 템플릿은 일관된 형식을 가진 명확한 구문 스타일을 사용해야 합니다.

모든 job의 before_script, script, after_script 키워드는 ShellCheck를 사용하여 linting되어야 하며, Shell 스크립팅 표준 및 스타일 지침을 가능한 한 따라야 합니다.

ShellCheck는 스크립트가 Bash를 사용하도록 설계되었다고 가정합니다. Bash ShellCheck 규칙과 호환되지 않는 쉘에 대한 스크립트를 사용하는 템플릿은 ShellCheck linting에서 제외될 수 있습니다. 스크립트를 제외하려면 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에 있는 테스트
# - 아래 라인의 URL을 수정하여 ABC 서버와 포트를 가리키도록 변경해야 합니다.
# - 프로젝트 CI/CD 설정에 ABC-PASSWORD라는 CI/CD 변수가 있어야 합니다. 값은
#   ABC 서버에 배포하는 데 사용하는 비밀번호여야 합니다.
# - ABC 서버가 포트 12345에서 수신하도록 설정되어 있어야 합니다.
#
# 자세한 내용은 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}

로컬 변수에 대문자로 명명하기

프로젝트 설정 또는 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 "Server responded with: $message"'

하위 호환성

템플릿은 include:template: 키워드로 동적으로 포함될 수 있습니다. 기존 템플릿을 변경하는 경우, 기존 프로젝트의 CI/CD에 영향을 주지 않도록 해야 합니다.

예를 들어, 템플릿의 job 이름을 변경하면 기존 프로젝트의 파이프라인이 중단될 수 있습니다. 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.ymlTARGET_URL CI/CD 변수를 지정함으로써 이뤄질 수 있습니다:

include:
  template: Performance.gitlab-ci.yml

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

템플릿에서 performance 작업 이름을 browser-performance로 변경하면, 사용자의 .gitlab-ci.yml은 더 이상 포함된 템플릿에 performance로 명명된 작업이 없기 때문에 즉시 lint 오류가 발생합니다. 따라서 사용자는 그들의 workflow를 방해하는 .gitlab-ci.yml을 수정해야 합니다.

중단 변경을 안전하게 소개하기 위해 버전 관리 섹션을 참조하세요.

버전 관리

기존 템플릿을 사용하는 기존 프로젝트에 영향을 미치지 않으면서 중대한 변경 사항을 도입하려면 안정 버전최신 버전 버전 관리를 사용하세요.

일반적으로 안정 버전 템플릿은 주 버전 릴리스에서만 중대한 변경 사항을 받지만, 최신 템플릿은 어떤 릴리스에서든 중대한 변경 사항을 받을 수 있습니다. 주 버전 릴리스 마일스톤에서 최신 템플릿을 새로운 안정 템플릿으로 전환합니다(그리고 최신 템플릿은 삭제될 수 있음).

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

  • GitLab은 다음 GitLab의 주 버전 릴리스에서 안정 템플릿을 최신 템플릿으로 덮어써야 하는 담당자(DRI)를 선택해야 합니다. DRI는 변경에 문제가 있는 사용자를 지원해야 합니다.
  • 새로운 비중대적인 변경 사항이 있는 경우, 안정 및 최신 템플릿은 가능한 한 일치하도록 업데이트되어야 합니다.
  • 많은 사용자가 직접적으로 의존하기 때문에 최신 템플릿이 예상보다 오래 유지될 수 있습니다.

새로운 최신 템플릿을 추가하기 전에, 안정 템플릿에 변경 사항을 도입할 수 있는지 확인하고, 중대한 변경 사항이더라도 가능한 경우 안정 버전을 직접 변경할 수 있습니다. 주변 버전 마일스톤에서 중대한 변경을 가진 안정 템플릿을 변경하기 전에, 다음 사항을 확인하세요:

안정 버전

안정 CI/CD 템플릿은 주 버전 릴리스 마일스톤에서만 중대한 변경 사항을 도입하는 템플릿입니다. 템플릿의 안정 버전을 <템플릿-이름>.gitlab-ci.yml로 지정합니다. 예를 들어 Jobs/Deploy.gitlab-ci.yml와 같이 지정할 수 있습니다.

GitLab 15.0과 같은 주 버전 릴리스에서 사용 가능한 최신 템플릿을 복사하여 새로운 안정 템플릿을 만들 수 있습니다. 중대한 변경 사항은 버전에 따른 폐기 및 제거 페이지에서 모두 공지되어야 합니다.

GitLab 15.1과 같은 GitLab의 마이너 릴리스에서 안정 템플릿 버전을 변경할 수 있습니다만:

최신 버전

최신으로 표시된 템플릿은 어떤 릴리스에서도 업데이트가 가능하며 중대한 변경 사항을 포함할 수 있습니다. 최신 버전을 나타내기 위해 템플릿 이름에 .latest를 추가하세요. 예를 들어 Jobs/Deploy.latest.gitlab-ci.yml와 같이 지정할 수 있습니다.

중대한 변경 사항을 도입할 때, 업그레이드 경로를 테스트하고 문서화해야 합니다. 일반적으로 최신 템플릿을 가장 좋은 옵션으로 홍보해서는 안 되며, 그렇게 하면 사용자들이 예상하지 못한 문제에 직면할 수 있습니다.

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

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

사용자가 현재 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. 파이프라인을 실행하고 모든 가능한 경우(병합 요청 파이프라인, 스케줄 등)에 모든 것이 올바르게 실행되는지 확인하세요.
  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_*: 섹션, 스테이지, 그룹 및 기능 카테고리에 따라 메트릭 사전 가이드를 따르세요. 이러한 키워드에 대해 확신이 없다면 MR에서 도움을 요청할 수 있습니다.
    • 각 파일 끝에 다음을 추가하세요:

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

예를 들어, 이것은 5분 프로덕션 앱 템플릿의 메트릭 구성 파일입니다:

보안

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

CI/CD 템플릿 MR 기여

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