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 템플릿을 merge request로 제출하기 전에 다음을 수행해야 합니다:

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

템플릿 디렉터리

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

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

템플릿 작성 가이드라인

템플릿 제출에서 표준을 준수하기 위해 다음 가이드라인을 사용합니다:

템플릿 유형

템플릿에는 프로젝트 구조, 언어 등과 일치하는 종단간 CI/CD 워크플로우를 제공하는 파이프라인 템플릿과, 특정 작업을 수행하는 명시적 작업을 제공하는 작업 템플릿 두 가지 유형이 있습니다. 템플릿의 스타일은 두 가지 유형 중 하나와 일치해야 합니다:

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

  • image 또는 before_script와 같은 전역 키워드를 템플릿 상단에 있는 default 섹션에 두십시오.
  • 템플릿이 기존의 .gitlab-ci.yml 파일의 include 키워드와 함께 사용되도록 설계된 경우 코드 주석에서 명확히 설명하십시오.

작업 템플릿 작성 시:

  • 전역 또는 default 키워드를 사용하지 마십시오. 루트 .gitlab-ci.yml이 템플릿을 포함하는 경우, 전역 또는 기본 키워드가 재정의될 수 있어 예기치 않은 동작을 일으킬 수 있습니다. 작업 템플릿이 특정 스테이지를 필요로 하는 경우 코드 주석에서 사용자가 주요 .gitlab-ci.yml 구성에 매뉴얼으로 스테이지를 추가해야 함을 명시해야 합니다.
  • 템플릿이 include 키워드와 함께 사용되거나 기존 구성에 복사되어 사용되도록 설계된 경우 코드 주석에서 명확히 설명하십시오.
  • 가장 최신 및 안정적인 버전으로 템플릿을 형상 관리하여 역호환성 문제를 피합니다. include로 가져온 템플릿을 유지하는 것은 보다 복잡하기 때문에 변경 사항이 모든 프로젝트의 파이프라인을 망가뜨릴 수 있습니다.

템플릿 프로덕션 시 추가 고려 사항:

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

구문 지침

템플릿을 더 쉽게 따를 수 있도록, 모든 템플릿은 일관된 형식으로 명확한 구문 스타일을 사용해야 합니다.

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

ShellCheck는 스크립트가 Bash를 사용하여 실행되도록 설계되었다고 가정합니다. Bash 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 키워드를 사용하여 사용해야 하는지.
  • 프로젝트의 CI/CD 설정에 저장해야 하는 변수가 있는지.
# ABC 서버를 사용하는 응용 프로그램을 게시하려면 이 템플릿을 사용하세요.
# 이 템플릿을 새 `.gitlab-ci.yml` 파일에 복사하여 사용할 수 있습니다.
# 기존 `.gitlab-ci.yml` 파일에 `include:` 키워드를 사용하여 이 템플릿을 추가하지 마십시오.
#
# 요구 사항:
# - /content에 저장된 ABC 프로젝트 및 /test에 테스트가 있어야 합니다.
# - 프로젝트 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>  # 해당 변수를 상대 경로로 사용할 수 있도록 업데이트하십시오.

job1:
  variables:
    ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid"  # (여기에 주석을 추가할 필요가 없습니다. 이미 명확합니다)
  script:
    - echo ${ERROR_MESSAGE}

로컬 변수에 대문자 이름 사용

CI/CD 설정을 통해 제공되거나 variables 키워드를 통해 제공될 것으로 예상되는 변수는 모든 단어를 대문자로 쓰고 밑줄 (_)로 분리해야 합니다.

.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에서 CI/CD 변수 TARGET_URL을 지정함으로써 수행할 수 있습니다.

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은 안정 템플릿을 최신 템플릿의 내용으로 다음 GitLab의 주 버전 릴리스에서 덮어쓸 DRI를 선택해야 합니다. 그리고 DRI는 변경과 관련하여 문제가있는 사용자를 지원할 책임이 있습니다.
  • 새로운 비중대한 변경 사항이 발생하면 안정 및 최신 템플릿이 가능한 한 일치하도록 업데이트되어야 합니다.
  • 많은 사용자가 계속해서 존재할 것으로 기대되어 최신 템플릿이 예상보다 오래 유지될 수 있습니다.

새로운 최신 템플릿을 추가하기 전에 안정 템플릿을 변경할 수 있는지 확인하고 심지어 중대한 변경 사항이 있는 경우에도 가능합니다. 템플릿이 복사 및 붙여넣기용인 경우 직접 안정 버전을 변경할 수 있습니다. 중대한 변경 사항을 가진 안정 템플릿을 마이너 마일스톤에서 변경하기 전에 다음 사항을 확인하세요:

안정 버전

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

GitLab 13.0과 같은 주요 마일스톤 릴리스에서 사용 가능한 최신 템플릿을 복사하여 새로운 안정한 템플릿을 만들 수 있습니다. 모든 중대한 변경 사항은 예를 들어 GitLab.com은 좁은 중대한 변경사항을 동반하여 13.0으로 이동합니다와 같은 블로그 게시물에서 공지되어야 합니다.

GitLab 13.1과 같은 마이너 GitLab 릴리스에서 안정한 템플릿 버전을 변경할 수 있습니다. 이 때 조건은 다음과 같습니다:

최신 버전

최신으로 표시된 템플릿은 중대한 변경 사항을 포함하여 모든 릴리스에서 업데이트할 수 있습니다. 최신 버전이라고 간주되는 경우 템플릿 이름에 .latest를 추가하면 됩니다. 예를 들어 Jobs/Deploy.latest.gitlab-ci.yml입니다.

중대한 변경 사항을 도입하는 경우에는 업그레이드 경로를 테스트하고 문서화하여야 합니다. 일반적으로 최신 템플릿을 가장 좋은 옵션으로 홍보하지 않는 것이 좋습니다. 왜냐하면 예상치 못한 문제로 사용자를 놀라게 할 수 있기 때문입니다.

최신 템플릿이 아직 없는 경우 안정한 템플릿을 복사할 수 있습니다.

이전 안정 템플릿 포함 방법

사용자는 현재 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. 파이프라인을 실행하고 모든 가능한 경우(Merge Request 파이프라인, 일정 등)에 모든 것이 제대로 실행되는지 확인합니다.
  4. 새로운 템플릿을 추가하는 Merge Request 설명에 프로젝트에 대한 링크를 추가합니다.

이는 리뷰어가 템플릿이 안전하게 Merge될 수 있는지 확인할 수 있도록 유용한 정보입니다.

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(Merge Request) 기여

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