rules
를 사용하여 작업 실행 시기 지정
rules
를 사용하여 파이프라인에서 작업을 포함하거나 제외합니다.
규칙은 첫 번째 일치 때까지 순서대로 평가됩니다. 일치되는 경우, 작업은 구성에 따라 파이프라인에 포함되거나 제외됩니다.
규칙에서는 작업이 실행되기 전에 평가되기 때문에 작업 스크립트에서 생성된 dotenv 변수는 규칙에서 사용할 수 없습니다.
향후 키워드 개선사항은 규칙 개선을 위한 업데이트에서 논의되며 누구나 제안이나 요청을 추가할 수 있습니다.
rules
예제
다음 예제는 작업이 특정 경우에만 실행되도록 if
를 사용하여 정의합니다:
job:
script: echo "안녕, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "schedule"
- 파이프라인이 Merge Request용인 경우 첫 번째 규칙이 일치하여 작업이 수행되며, 작업은 다음과 같은 속성을 갖는 Merge Request 파이프라인에 추가됩니다:
-
when: manual
(매뉴얼 작업) -
allow_failure: true
(매뉴얼 작업이 실행되지 않아도 파이프라인이 계속 실행됨)
-
- 파이프라인이 Merge Request용이 아닌 경우, 첫 번째 규칙은 일치하지 않으며, 두 번째 규칙이 평가됩니다.
- 파이프라인이 예약된 파이프라인인 경우, 두 번째 규칙이 일치하여 작업이 예약된 파이프라인에 추가됩니다. 속성이 정의되지 않았으므로 다음과 같이 추가됩니다:
-
when: on_success
(기본값) -
allow_failure: false
(기본값)
-
- 다른 모든 경우에는 규칙이 일치하지 않으므로 작업은 어떠한 다른 파이프라인에도 추가되지 않습니다.
또는 일부 경우에 작업을 제외하도록 규칙 세트를 정의하고 다른 모든 경우에는 실행하도록 할 수도 있습니다:
job:
script: echo "안녕, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
- 파이프라인이 Merge Request용인 경우, 작업이 파이프라인에 추가되지 않습니다.
- 파이프라인이 예약된 파이프라인인 경우, 작업이 파이프라인에 추가되지 않습니다.
-
다른 모든 경우에는
when: on_success
와 함께 파이프라인에 추가됩니다.
when
절을 사용하는 경우(when: never
를 포함하지 않음) 동시에 두 개의 파이프라인이 시작될 수 있습니다. 푸시 파이프라인과 Merge Request 파이프라인은 동일한 이벤트(열린 Merge Request의 소스 브랜치로의 푸시)에 의해 트리거될 수 있습니다. 자세한 내용은 중복 파이프라인 방지를 참조하십시오.예약된 파이프라인에서 작업 실행
파이프라인이 예약된 경우에만 작업을 실행하도록 구성할 수 있습니다. 예를 들어:
job:on-schedule:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
script:
- make world
job:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
script:
- make build
이 예제에서 make world
는 예약된 파이프라인에서 실행되고, make build
는 브랜치 및 태그 파이프라인에서 실행됩니다.
브랜치가 비어 있는 경우 작업 건너뛰기
rules:changes:compare_to
를 사용하여 브랜치가 비어 있는 경우 작업을 건너뛸 수 있으며, 이는 CI/CD 리소스를 저장합니다. 이 구성에서는 브랜치를 기본 브랜치와 비교하며, 브랜치가:
- 변경된 파일이 없는 경우, 작업을 실행하지 않습니다.
- 변경된 파일이 있는 경우, 작업을 실행합니다.
예를 들어, main
을 기본 브랜치로 하는 프로젝트에서:
job:
script:
- echo "빈 브랜치에 대해서만 이 작업이 실행됩니다"
rules:
- if: $CI_COMMIT_BRANCH
changes:
compare_to: 'refs/heads/main'
paths:
- '**/*'
이 작업의 규칙은 현재 브랜치의 모든 파일과 경로(**/*
)를 main
브랜치로 재귀적으로 비교합니다. 이 규칙은 브랜치의 파일에 변경 사항이 있을 때만 일치하여 작업이 실행됩니다.
rules:changes
에서 변수 사용하기
CI/CD 변수를 rules:changes
표현식에서 사용하여 파이프라인에 작업을 추가할 시기를 결정할 수 있습니다:
docker build:
variables:
DOCKERFILES_DIR: 'path/to/files'
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- changes:
- $DOCKERFILES_DIR/**/*
$
문자를 변수와 경로 모두에 사용할 수 있습니다. 예를 들어, DOCKERFILES_DIR
변수가 있는 경우 해당 값을 사용하고, 없는 경우 경로 일부임으로 해석됩니다.
미리 정의된 변수를 사용한 일반적인 if
절
rules:if
절은 미리 정의된 CI/CD 변수와 함께 일반적으로 사용됩니다.
다음 예제는 예약된 파이프라인이나 브랜치 또는 태그로 푸시한 경우 when: on_success
(기본값)으로 작업을 실행하며, 다른 파이프라인 유형에는 작업을 추가하지 않습니다.
job:
script: echo "안녕, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "push"
다음 예제는 Merge Request 파이프라인 및 예약된 파이프라인에서 when: on_success
작업으로 실행되며, 다른 파이프라인 유형에서는 실행되지 않습니다.
job:
script: echo "안녕, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"
일반적으로 사용되는 if
절:
-
if: $CI_COMMIT_TAG
: 태그에 변경 사항이 푸시된 경우. -
if: $CI_COMMIT_BRANCH
: 브랜치로 변경 사항이 푸시된 경우. -
if: $CI_COMMIT_BRANCH == "main"
:main
에 변경 사항이 푸시된 경우. -
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
: 기본 브랜치에 변경 사항이 푸시된 경우. 여러 프로젝트에서 동일한 구성을 원할 때 사용합니다. -
if: $CI_COMMIT_BRANCH =~ /정규표현식/
: 커밋 브랜치가 정규 표현식과 일치하는 경우. -
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /브랜치 Merge.*/
: 커밋 브랜치가 기본 브랜치이면서 커밋 메시지 제목이 정규 표현식과 일치하는 경우. 예를 들어, Merge 커밋의 기본 커밋 메시지가브랜치 Merge
으로 시작하는 경우. -
if: $CUSTOM_VARIABLE == "value1"
: 사용자 정의 변수CUSTOM_VARIABLE
이 정확히value1
인 경우.
특정 파이프라인 유형에서만 작업 실행
미리 정의된 CI/CD 변수를 사용하여 작업이 실행될 파이프라인 유형을 선택할 수 있으며, 다음을 통해 가능합니다:
다음 표는 사용할 수 있는 일부 변수 및 변수가 제어할 수 있는 파이프라인 유형을 나열합니다:
- Git
push
이벤트(새 커밋 또는 태그와 같은)에 대한 브랜치 파이프라인. - 새 Git 태그가 브랜치로 푸시되었을 때 실행되는 태그 파이프라인.
- Merge Request 파이프라인은 Merge Request에 대한 변경(새 커밋 또는 Merge Request의 파이프라인 탭에서 파이프라인 실행 선택과 같은)에 대한 실행.
- 예약된 파이프라인.
변수 | 브랜치 | 태그 | Merge Request | 예약된 |
---|---|---|---|---|
CI_COMMIT_BRANCH
| 예 | 예 | ||
CI_COMMIT_TAG
| 예 | 예, 예약된 파이프라인이 태그에 실행 구성되어 있는 경우. | ||
CI_PIPELINE_SOURCE = push
| 예 | 예 | ||
CI_PIPELINE_SOURCE = schedule
| 예 | |||
CI_PIPELINE_SOURCE = merge_request_event
| 예 | |||
CI_MERGE_REQUEST_IID
| 예 |
예를 들어, 작업을 Merge Request 파이프라인 및 예약된 파이프라인에만 실행되도록 구성하고, 브랜치 또는 태그 파이프라인에는 추가되지 않도록 설정할 수 있습니다:
job1:
script:
- echo
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "push"
when: never
복잡한 규칙
동일한 규칙 내에서 if
, changes
, exists
와 같은 모든 rules
키워드를 함께 사용할 수 있습니다. 해당 규칙은 모든 포함된 키워드가 true로 평가될 때에만 true로 평가됩니다.
예를 들어:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: $VAR == "string value"
changes: # Include the job and set to when:manual if any of the follow paths match a modified file.
- Dockerfile
- docker/scripts/**/*
when: manual
allow_failure: true
만약 Dockerfile
파일 또는 /docker/scripts
에 있는 파일 중 하나가 변경되었고 그리고 $VAR
== “string value”라면, 작업은 매뉴얼으로 실행되고 실패할 수 있습니다.
&&
및 ||
와 함께 괄호를 사용하여 더 복잡한 변수 표현식을 구축할 수 있습니다.
job1:
script:
- echo This rule uses parentheses.
rules:
- if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
중복 파이프라인 방지
작업이 rules
을 사용하는 경우, 브랜치에 커밋을 푸시하는 것과 같은 하나의 작업이 여러 파이프라인을 트리거할 수 있습니다. 실수로 파이프라인을 트리거하지 않도록 별도로 구성할 필요가 없습니다.
중복 파이프라인을 유발하는 잠재적인 구성은 파이프라인 경고가 표시됩니다.
예를 들어:
job:
script: echo "This job creates double pipelines!"
rules:
- if: $CUSTOM_VARIABLE == "false"
when: never
- when: always
이 작업은 $CUSTOM_VARIABLE
이 false 일 때 실행되지 않지만, 모든 다른 파이프라인에서 실행되며, 푸시(브랜치) 및 Merge Request 파이프라인을 포함합니다. 이 구성으로 인해 열린 Merge Request의 소스 브랜치로의 모든 푸시가 중복된 파이프라인을 유발합니다.
중복 파이프라인을 피하려면 다음을 수행할 수 있습니다:
-
workflow
을 사용하여 실행할 수 있는 파이프라인 유형을 지정합니다. -
작업을 실행할 구체적인 경우에만 작업을 실행하도록 규칙을 다시 작성하고 최종
when
규칙을 피합니다:job: script: echo "This job does NOT create double pipelines!" rules: - if: $CUSTOM_VARIABLE == "true" && $CI_PIPELINE_SOURCE == "merge_request_event"
또한 workflow: rules
을 사용하지 않고 작업 규칙을 변경하여 푸시(브랜치) 파이프라인 또는 Merge Request 파이프라인을 피할 수 있습니다. 그러나 workflow: rules
없이 - when: always
규칙을 사용하는 경우, GitLab은 여전히 파이프라인 경고를 표시합니다.
예를 들어, 다음은 이중 파이프라인을 트리거하지만 workflow: rules
가 없으면 권장되지 않습니다:
job:
script: echo "This job does NOT create double pipelines!"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- when: always
workflow:rules
로 중복 파이프라인 방지을 위해 동일한 작업에서 푸시 및 Merge Request 파이프라인을 포함하지 않아야 합니다:
job:
script: echo "This job creates double pipelines!"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
또한 동일한 파이프라인에서 only/except
작업 및 rules
작업을 섞어서 사용하지 마십시오. 이는 YAML 오류를 발생시키지 않을 수 있지만, only/except
및 rules
의 다른 기본 동작으로 인해 해결하기 어려운 문제를 유발할 수 있습니다:
job-with-no-rules:
script: echo "This job runs in branch pipelines."
job-with-rules:
script: echo "This job runs in merge request pipelines."
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
브랜치로 푸시된 변경마다 중복되는 파이프라인이 실행됩니다. 하나의 브랜치 파이프라인에서 단일 작업(job-with-no-rules
)이 실행되고, 하나의 Merge Request 파이프라인에서 다른 작업(job-with-rules
)이 실행됩니다. 규칙이 지정되지 않은 작업은 기본적으로 except: merge_requests
이므로 job-with-no-rules
은 Merge Request을 제외한 모든 경우에 실행됩니다.
다른 작업에서 규칙 재사용
!reference
태그를 사용하여 서로 다른 작업에서 규칙을 재사용할 수 있습니다. !reference
규칙을 일반 작업 정의 규칙과 결합할 수 있습니다. 예를 들어:
.default_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
job1:
rules:
- !reference [.default_rules, rules]
script:
- echo "This job runs for the default branch, but not schedules."
job2:
rules:
- !reference [.default_rules, rules]
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- echo "This job runs for the default branch, but not schedules."
- echo "It also runs for merge requests."
CI/CD 변수 표현식
rules:if
와 함께 변수 표현식을 사용하여 작업이 파이프라인에 추가되는 조건을 제어할 수 있습니다.
문자열과 변수를 비교하기 위해 등호 연산자 ==
및 !=
를 사용할 수 있습니다. 작은 따옴표와 큰 따옴표 모두 유효합니다. 순서는 중요하지 않으므로 변수가 먼저이거나 문자열이 먼저일 수 있습니다. 예를 들어:
if: $VARIABLE == "some value"
if: $VARIABLE != "some value"
if: "some value" == $VARIABLE
두 변수의 값을 비교할 수 있습니다. 예를 들어:
if: $VARIABLE_1 == $VARIABLE_2
if: $VARIABLE_1 != $VARIABLE_2
null
키워드에 변수를 비교하여 정의 상태를 확인할 수 있습니다. 예를 들어:
if: $VARIABLE == null
if: $VARIABLE != null
변수가 정의되었지만 비어 있는지 확인할 수 있습니다. 예를 들어:
if: $VARIABLE == ""
if: $VARIABLE != ""
변수가 정의되어 있고 비어 있지 않은지 확인할 수 있습니다. 이를 위해 표현식에 변수 이름만 사용하면 됩니다. 예를 들어:
if: $VARIABLE
정규 표현식을 사용하여 변수 비교
=~
및 !~
연산자를 사용하여 변수 값에 대한 정규식 일치를 확인할 수 있습니다.
정규 표현식을 사용하여 변수 패턴 일치는 RE2 정규 표현식 구문을 사용합니다.
표현식은 다음과 같이 true
로 평가됩니다:
-
=~
를 사용하여 일치를 찾았을 때. -
!~
를 사용하여 일치를 찾지 못했을 때.
예를 들어:
if: $VARIABLE =~ /^content.*/
if: $VARIABLE !~ /^content.*/
더불어:
-
/./
와 같은 한 글자 정규 표현식은 지원되지 않으며유효하지 않은 표현식 구문
오류가 발생합니다. - 패턴 일치는 기본적으로 대소문자를 구분하며, 패턴을 대소문자 구분 없이 만들기 위해
i
플래그 수정자를 사용할 수 있습니다. 예를 들어:/pattern/i
. - 리포지터리 경로가 항상 문자 그대로 일치하므로 태그나 브랜치 이름만이 일치됩니다.
- 전체 패턴은 반드시
/
로 둘러싸야 합니다. 예를 들어,issue-/.*/
로 시작하는 모든 태그 이름이나 브랜치 이름을 일치시키려면 사용할 수 없지만,/issue-.*/
를 사용할 수 있습니다. -
@
기호는 참조의 리포지터리 경로의 시작을 나타냅니다. 정규 표현식을 사용하여@
문자를 포함하는 참조 이름을 일치시키기 위해, 16진수 문자 코드 일치인\x40
를 사용해야 합니다. - 정규식이 태그 이름이나 브랜치 이름의 부분 문자열만을 일치시키지 않도록
^
와$
앵커를 사용합니다. 예를 들어,/^issue-.*$/
는/^issue-/
과 동일하며, 단순히/issue/
는severe-issues
라는 브랜치도 일치시킵니다.
정규 표현식을 변수에 저장
- GitLab 15.0에서 도입되었습니다. 기본적으로 비활성화된
ci_fix_rules_if_comparison_with_regexp_variable
이라는 플래그와 함께 feature_flags.md에 포함되어 있습니다.- 일반적으로 이용 가능하며, GitLab 15.1에서
ci_fix_rules_if_comparison_with_regexp_variable
피처 플래그가 제거되었습니다.
=~
및 !~
표현식의 오른쪽에 있는 변수는 정규 표현식으로 평가됩니다.
정규 표현식은 슬래시(/
)로 묶어야 합니다. 예를 들면:
variables:
pattern: '/^ab.*/'
regex-job1:
variables:
teststring: 'abcde'
script: echo "'abcde'가 /^ab.*/ 패턴과 일치하므로 이 작업이 실행됩니다."
rules:
- if: '$teststring =~ $pattern'
regex-job2:
variables:
teststring: 'fghij'
script: echo "'fghi'가 /^ab.*/ 패턴과 일치하지 않으므로 이 작업이 실행되지 않습니다."
rules:
- if: '$teststring =~ $pattern'
정규 표현식에 있는 변수는 해결되지 않습니다. 예를 들면:
variables:
string1: 'regex-job1'
string2: 'regex-job2'
pattern: '/$string2/'
regex-job1:
script: "'string1' 변수가 정규 표현식 내에서 해결되지 않았기 때문에 이 작업이 실행되지 않습니다."
rules:
- if: '$CI_JOB_NAME =~ /$string1/'
regex-job2:
script: "'pattern' 변수 내에서 'string2' 변수가 해결되지 않았기 때문에 이 작업이 실행되지 않습니다."
rules:
- if: '$CI_JOB_NAME =~ $pattern'
변수 표현식 결합
&&
(그리고) 또는 ||
(또는)을 사용하여 여러 표현식을 결합할 수 있습니다. 예를 들면:
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 =~ /thing$/ && $VARIABLE3
$VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/ && $VARIABLE3
연산자의 우선순위는 Ruby 2.5 표준에 따릅니다.
따라서 &&
는 ||
보다 먼저 계산됩니다.
괄호를 사용하여 표현식을 그룹화할 수 있습니다. 괄호는 &&
와 ||
보다 먼저 계산되므로, 괄호로 둘러싼 표현식이 먼저 계산되고,
결과가 나머지 표현식에 사용됩니다.
복잡한 조건을 만들기 위해 괄호를 중첩시킬 수 있으며, 괄호 안의 가장 내부 표현식이 먼저 계산됩니다. 예를 들면:
($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)
($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3
$CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)
문제 해결
=~
로 정규 표현식 일치시 예상치 못한 동작
=~
문자를 사용할 때는 비교의 오른쪽에 항상 유효한 정규 표현식이 포함되어 있는지 확인하십시오.
비교의 오른쪽이 /
문자로 둘러싸인 유효한 정규 표현식이 아닌 경우, 표현식이 예상치 않은 방식으로 평가됩니다. 이 경우 비교는
왼쪽 항목이 오른쪽 항목의 부분 문자열인지 확인합니다. 예를 들면, "23" =~ "1234"
은 true로 평가되며, 이는 "23" =~ /1234/
의 반대로,
false로 평가됩니다.
파이프라인을 이러한 동작을 의존하도록 구성해서는 안 됩니다.