GitLab CI/CD 구성 파일 최적화
당신은 다음을 사용하여 GitLab CI/CD 구성 파일에서 복잡성과 중복 구성을 줄일 수 있습니다:
- 
앵커(
&)와 별칭(*), 그리고 맵 Merge(<<)과 같은 YAML 특정 기능 다양한 YAML 특징에 대해 더 읽어보세요. - 
extends키워드, 더 유연하고 가독성이 좋습니다. 가능한 경우extends를 사용해야 합니다. 
앵커
YAML에는 문서 전체에서 콘텐츠를 복제하는 데 사용할 수 있는 ‘앵커’라는 기능이 있습니다.
앵커를 사용하여 속성을 복제하거나 상속하세요. 숨겨진 작업과 앵커를 사용하여 작업에 대한 템플릿을 제공하세요. 중복 키가 있는 경우, 최근에 포함된 키가 다른 키를 재정의합니다.
특정 경우(여기 참조: 스크립트용 YAML 앵커)에서는 다른 곳에서 정의된 여러 컴포넌트로 배열을 구축하는 데 YAML 앵커를 사용할 수 있습니다. 예를 들어:
.default_scripts: &default_scripts
  - ./default-script1.sh
  - ./default-script2.sh
job1:
  script:
    - *default_scripts
    - ./job-script.sh
당신은 include 키워드를 사용할 때 앵커를 여러 파일에 걸쳐 사용할 수 없습니다. 앵커는 정의된 파일에서만 유효합니다. 다른 YAML 파일에서 구성을 재사용하려면 !reference 태그 또는 extends 키워드를 사용하세요.
다음 예제는 앵커와 맵 Merge을 사용합니다. .job_template 구성을 상속하는 test1과 test2라는 두 작업을 생성하며, 각각 고유한 script을 정의합니다:
.job_template: &job_configuration  # 'job_configuration'이라는 앵커를 정의하는 숨겨진 YAML 구성
  image: ruby:2.6
  services:
    - postgres
    - redis
test1:
  <<: *job_configuration           # 'job_configuration' 별칭의 내용을 추가합니다
  script:
    - test1 project
test2:
  <<: *job_configuration           # 'job_configuration' 별칭의 내용을 추가합니다
  script:
    - test2 project
&는 앵커의 이름(job_configuration)을 설정하며, <<는 “주어진 해시를 현재 해시로 Merge”을 의미하며, *은 명명된 앵커(job_configuration 다시)를 포함합니다. 이 예제의 전개된 버전은 다음과 같습니다:
.job_template:
  image: ruby:2.6
  services:
    - postgres
    - redis
test1:
  image: ruby:2.6
  services:
    - postgres
    - redis
  script:
    - test1 project
test2:
  image: ruby:2.6
  services:
    - postgres
    - redis
  script:
    - test2 project
당신은 앵커를 사용하여 두 세트의 서비스를 정의할 수 있습니다. 예를 들어, test:postgres와 test:mysql은 .job_template에서 정의된 script를 공유하지만, .postgres_services와 .mysql_services에 정의된 서로 다른 services를 사용합니다:
.job_template: &job_configuration
  script:
    - test project
  tags:
    - dev
.postgres_services:
  services: &postgres_configuration
    - postgres
    - ruby
.mysql_services:
  services: &mysql_configuration
    - mysql
    - ruby
test:postgres:
  <<: *job_configuration
  services: *postgres_configuration
  tags:
    - postgres
test:mysql:
  <<: *job_configuration
  services: *mysql_configuration
전개된 버전은 다음과 같습니다:
.job_template:
  script:
    - test project
  tags:
    - dev
.postgres_services:
  services:
    - postgres
    - ruby
.mysql_services:
  services:
    - mysql
    - ruby
test:postgres:
  script:
    - test project
  services:
    - postgres
    - ruby
  tags:
    - postgres
test:mysql:
  script:
    - test project
  services:
    - mysql
    - ruby
  tags:
    - dev
숨겨진 작업이 편리하게 템플릿으로 사용되며, tags: [postgres]가 tags: [dev]를 덮어쓰는 것을 볼 수 있습니다.
스크립트용 YAML 앵커
- GitLab 12.5에서 도입됨.
 stages키워드와 함께 앵커를 지원하는 것은 GitLab 16.9에서 도입됨.
스크립트, before_script, 그리고 after_script와 함께 YAML 앵커를 사용하여 여러 작업에서 미리 정의된 명령을 사용할 수 있습니다:
.some-script-before: &some-script-before
  - echo "이 스크립트를 먼저 실행"
.some-script: &some-script
  - echo "이 스크립트를 다음에 실행"
  - echo "이 스크립트도 실행"
.some-script-after: &some-script-after
  - echo "이 스크립트를 마지막으로 실행"
job1:
  before_script:
    - *some-script-before
  script:
    - *some-script
    - echo "이 작업만을 위해 뭔가를 실행"
  after_script:
    - *some-script-after
job2:
  script:
    - *some-script-before
    - *some-script
    - echo "다른 작업을 실행"
    - *some-script-after
extends를 사용하여 구성 섹션 재사용하기
여러 작업에서 구성을 재사용하기 위해 extends 키워드를 사용할 수 있습니다. 이는 YAML 앵커와 유사하지만 더 간단하며 includes와 함께 extends를 사용할 수 있습니다.
extends는 다중 상속을 지원합니다. 추가 복잡성으로 인해 세 단계 이상을 사용하는 것을 피해야 하지만, 최대 열한 개 이상을 사용할 수 있습니다. 다음 예제는 두 단계의 상속을 갖습니다:
.tests:
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
.rspec:
  extends: .tests
  script: rake rspec
rspec 1:
  variables:
    RSPEC_SUITE: '1'
  extends: .rspec
rspec 2:
  variables:
    RSPEC_SUITE: '2'
  extends: .rspec
spinach:
  extends: .tests
  script: rake spinach
extends에서 키 제외
확장된 내용에서 키를 제외하려면 다음과 같이 null로 할당해야 합니다. 예를 들어:
.base:
  script: test
  variables:
    VAR1: base var 1
test1:
  extends: .base
  variables:
    VAR1: test1 var 1
    VAR2: test2 var 2
test2:
  extends: .base
  variables:
    VAR2: test2 var 2
test3:
  extends: .base
  variables: {}
test4:
  extends: .base
  variables: null
합병된 구성:
test1:
  script: test
  variables:
    VAR1: test1 var 1
    VAR2: test2 var 2
test2:
  script: test
  variables:
    VAR1: base var 1
    VAR2: test2 var 2
test3:
  script: test
  variables:
    VAR1: base var 1
test4:
  script: test
  variables: null
extends와 include 함께 사용
다른 구성 파일에서 구성을 재사용하려면 extends와 include를 결합하세요.
다음 예제에서 included.yml 파일에 script가 정의됩니다. 그런 다음 .gitlab-ci.yml 파일에서 extends가 script 내용을 참조합니다.
- 
included.yml:.template: script: - echo Hello! - 
.gitlab-ci.yml:include: included.yml useTemplate: image: alpine extends: .template 
세부 정보 Merge
extends를 사용하여 해시를 Merge할 수 있지만 배열은 Merge할 수 없습니다. Merge에 사용되는 알고리즘은 “가장 가까운 스코프가 이김”입니다. 중복 키가 있는 경우 GitLab은 키를 기반으로 역방향으로 깊이 Merge을 수행합니다. 마지막 멤버에서 정의된 키는 항상 다른 수준에서 정의된 내용을 재정의합니다. 예를 들어:
.only-important:
  variables:
    URL: "http://my-url.internal"
    IMPORTANT_VAR: "the details"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH == "stable"
  tags:
    - production
  script:
    - echo "Hello world!"
.in-docker:
  variables:
    URL: "http://docker-url.internal"
  tags:
    - docker
  image: alpine
rspec:
  variables:
    GITLAB: "is-awesome"
  extends:
    - .only-important
    - .in-docker
  script:
    - rake rspec
그 결과 rspec 작업은 다음과 같습니다:
rspec:
  variables:
    URL: "http://docker-url.internal"
    IMPORTANT_VAR: "the details"
    GITLAB: "is-awesome"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH == "stable"
  tags:
    - docker
  image: alpine
  script:
    - rake rspec
이 예에서:
- 
variables섹션이 Merge되지만URL: "http://docker-url.internal"이URL: "http://my-url.internal"을 덮어씁니다. - 
tags: ['docker']가tags: ['production']을 덮어씁니다. - 
script는 Merge되지 않지만script: ['rake rspec']이script: ['echo "Hello world!"']을 덮어씁니다. 배열을 Merge하려면 YAML 앵커를 사용할 수 있습니다. 
!reference 태그
!reference 사용자 정의 YAML 태그를 사용하여 다른 작업 섹션에서 키워드 구성을 선택하고 현재 섹션에서 재사용할 수 있습니다. YAML 앵커와 달리 !reference 태그를 사용하여 포함된 구성 파일에서 구성을 재사용할 수 있습니다.
다음 예에서 setup.yml에 있는 script와 after_script가 test 작업에서 재사용됩니다:
- 
setup.yml:.setup: script: - echo creating environment - 
.gitlab-ci.yml:include: - local: setup.yml .teardown: after_script: - echo deleting environment test: script: - !reference [.setup, script] - echo running my own command after_script: - !reference [.teardown, after_script] 
다음 예에서 test-vars-1은 .vars의 모든 변수를 재사용하고, test-vars-2는 특정 변수를 선택하여 새로운 MY_VAR 변수로 재사용합니다.
.vars:
  variables:
    URL: "http://my-url.internal"
    IMPORTANT_VAR: "the details"
test-vars-1:
  variables: !reference [.vars, variables]
  script:
    - printenv
test-vars-2:
  variables:
    MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
  script:
    - printenv
script, before_script, 및 after_script에서 !reference 태그 중첩
script, before_script, 및 after_script 섹션에서 !reference 태그를 최대 10단계까지 중첩할 수 있습니다. 중첩된 태그를 사용하여 더 복잡한 스크립트를 작성할 때 재사용 가능한 섹션을 정의하세요. 예를 들어:
.snippets:
  one:
    - echo "ONE!"
  two:
    - !reference [.snippets, one]
    - echo "TWO!"
  three:
    - !reference [.snippets, two]
    - echo "THREE!"
nested-references:
  script:
    - !reference [.snippets, three]
이 예에서 nested-references 작업은 세 개의 echo 명령을 모두 실행합니다.
IDE를 구성하여 !reference 태그를 지원하도록 설정
파이프라인 편집기는 !reference 태그를 지원합니다. 그러나 !reference와 같은 사용자 정의 YAML 태그에 대한 스키마 규칙은 기본적으로 편집기에서 잘못된 것으로 처리될 수 있습니다.
일부 편집기는 !reference 태그를 수용하도록 구성할 수 있습니다. 예를 들면:
- 
VS Code에서
settings.json파일에서customTags를 구문 분석하도록vscode-yaml을 설정할 수 있습니다:"yaml.customTags": [ "!reference sequence" ] - 
Sublime Text에서
LSP-yaml패키지를 사용하는 경우,LSP-yaml사용자 설정에서customTags를 설정할 수 있습니다:{ "settings": { "yaml.customTags": ["!reference sequence"] } } 
도움말