InfoGrab Docs

`rules`로 잡 실행 시점 지정

요약

파이프라인에서 잡을 포함하거나 제외하려면 rules 키워드를 사용하세요. 규칙은 첫 번째 매치가 발견될 때까지 순서대로 평가됩니다. rules가 평가되기 전에 어떤 잡도 실행되지 않으므로, 잡 스크립트에서 생성된 dotenv 변수를 rules에서 사용할 수 없습니다.

파이프라인에서 잡을 포함하거나 제외하려면 rules 키워드를 사용하세요.

규칙은 첫 번째 매치가 발견될 때까지 순서대로 평가됩니다. 매치가 발견되면 설정에 따라 잡이 파이프라인에 포함되거나 제외됩니다.

rules가 평가되기 전에 어떤 잡도 실행되지 않으므로, 잡 스크립트에서 생성된 dotenv 변수를 rules에서 사용할 수 없습니다.

rules 예시#

다음 예시는 if를 사용하여 두 가지 특정 경우에만 잡이 실행되도록 정의합니다:

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
      allow_failure: true
    - if: $CI_PIPELINE_SOURCE == "schedule"
  • 파이프라인이 머지 요청을 위한 것이면 첫 번째 규칙이 매치되고, 잡이 다음 속성으로 머지 요청 파이프라인에 추가됩니다:
    • when: manual (수동 잡)
    • allow_failure: true (수동 잡이 실행되지 않아도 파이프라인은 계속 실행됨)
  • 파이프라인이 머지 요청을 위한 것이 아니면 첫 번째 규칙이 매치되지 않고, 두 번째 규칙이 평가됩니다.
  • 파이프라인이 예약된 파이프라인이면 두 번째 규칙이 매치되고, 잡이 예약된 파이프라인에 추가됩니다. 속성이 정의되지 않았으므로 다음 설정으로 추가됩니다:
    • when: on_success (기본값)
    • allow_failure: false (기본값)
  • 다른 모든 경우에는 규칙이 매치되지 않으므로, 잡이 다른 파이프라인에 추가되지 않습니다.

또는 몇 가지 경우에 잡을 제외하고 다른 모든 경우에 실행하도록 규칙 세트를 정의할 수 있습니다:

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: never
    - when: on_success
  • 파이프라인이 머지 요청을 위한 것이면 잡이 파이프라인에 추가되지 않습니다.
  • 파이프라인이 예약된 파이프라인이면 잡이 파이프라인에 추가되지 않습니다.
  • 다른 모든 경우에는 잡이 when: on_success로 파이프라인에 추가됩니다.
Warning

마지막 규칙으로 when 절을 사용하면(when: never 제외), 두 개의 파이프라인이 동시에 시작될 수 있습니다. 푸시 파이프라인과 머지 요청 파이프라인 모두 동일한 이벤트(열린 머지 요청의 소스 브랜치에 푸시)에 의해 트리거될 수 있습니다. 자세한 내용은 중복 파이프라인 방지를 참조하세요.

예약된 파이프라인에서 잡 실행#

파이프라인이 예약된 경우에만 잡을 실행하도록 구성할 수 있습니다. 예를 들면:

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는 브랜치 및 태그 파이프라인에서 실행됩니다.

브랜치가 비어 있으면 잡 건너뜀#

CI/CD 리소스를 절약하기 위해 브랜치가 비어 있을 때 잡을 건너뛰려면 rules:changes:compare_to를 사용하세요. 구성은 브랜치를 기본 브랜치와 비교하며, 브랜치가:

  • 변경된 파일이 없으면 잡이 실행되지 않습니다.
  • 변경된 파일이 있으면 잡이 실행됩니다.

예를 들어, main을 기본 브랜치로 사용하는 프로젝트에서:

job:
  script:
    - echo "This job only runs for branches that are not empty"
  rules:
    - if: $CI_COMMIT_BRANCH
      changes:
        compare_to: 'refs/heads/main'
        paths:
          - '**/*'

이 잡의 규칙은 현재 브랜치의 모든 파일과 경로를 재귀적으로(**/*) main 브랜치와 비교합니다. 브랜치에 변경 사항이 있을 때만 규칙이 매치되어 잡이 실행됩니다.

parallel:matrix 잡의 경우, rules:changes 경로에 매트릭스 변수를 사용하여 해당 매트릭스 값과 관련된 파일이 변경된 경우에만 각 잡 인스턴스를 실행할 수 있습니다.

파일이 없을 때 잡 실행#

rules: exists를 사용하여 특정 파일이 없을 때만 잡이 실행되도록 구성할 수 있습니다.

예를 들어, example.yml 파일이 없을 때 머지 요청 파이프라인에서 잡을 실행하려면:

job:
  script: echo "Hello, Rules!"
  rules:
    - exists:
      - "example_dir/example.yml"
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

이 예시에서 브랜치에 example_dir/example.yml 파일이 있으면 잡이 실행되지 않습니다. 파일이 없으면 머지 요청 파이프라인에서 잡이 실행될 수 있습니다.

parallel:matrix 잡의 경우, rules:exists 경로에 매트릭스 변수를 사용하여 특정 파일이 존재할 때만 잡 인스턴스를 포함할 수 있습니다.

사전 정의된 변수를 사용하는 일반적인 if#

rules:if 절은 일반적으로 사전 정의된 CI/CD 변수, 특히 CI_PIPELINE_SOURCE와 함께 사용됩니다.

다음 예시는 예약된 파이프라인이나 푸시 파이프라인(브랜치 또는 태그)에서 잡을 수동 잡으로 실행하고, 그 외에는 when: on_success(기본값)로 실행합니다. 다른 파이프라인 유형에는 잡을 추가하지 않습니다.

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: manual
      allow_failure: true
    - if: $CI_PIPELINE_SOURCE == "push"

다음 예시는 머지 요청 파이프라인과 예약된 파이프라인에서 잡을 when: on_success 잡으로 실행합니다. 다른 파이프라인 유형에서는 실행되지 않습니다.

job:
  script: echo "Hello, 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 =~ /regex-expression/: 커밋 브랜치가 정규 표현식과 매치되는 경우.
  • if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /Merge branch.*/: 커밋 브랜치가 기본 브랜치이고 커밋 메시지 제목이 정규 표현식과 매치되는 경우.
  • if: $CUSTOM_VARIABLE == "value1": 사용자 정의 변수 CUSTOM_VARIABLE이 정확히 value1인 경우.

특정 파이프라인 유형에서만 잡 실행#

사전 정의된 CI/CD 변수를 rules와 함께 사용하여 잡이 어떤 파이프라인 유형에서 실행될지 선택할 수 있습니다.

다음 표는 사용할 수 있는 몇 가지 변수와 해당 변수가 제어할 수 있는 파이프라인 유형을 나열합니다:

  • 브랜치에 새 커밋이나 태그 등 Git push 이벤트가 발생할 때 실행되는 브랜치 파이프라인.
  • 새 Git 태그가 브랜치에 푸시될 때만 실행되는 태그 파이프라인.
  • 새 커밋 추가나 머지 요청의 파이프라인 탭에서 파이프라인 실행을 선택하는 등 머지 요청에 변경 사항이 있을 때 실행되는 머지 요청 파이프라인.
  • 예약된 파이프라인.
변수 브랜치 태그 머지 요청 예약됨
CI_COMMIT_BRANCH
CI_COMMIT_TAG 예, 예약된 파이프라인이 태그에서 실행되도록 구성된 경우.
CI_PIPELINE_SOURCE = push
CI_PIPELINE_SOURCE = schedule
CI_PIPELINE_SOURCE = merge_request_event
CI_MERGE_REQUEST_IID

예를 들어, 브랜치나 태그 파이프라인이 아닌 머지 요청 파이프라인과 예약된 파이프라인에서만 잡이 실행되도록 구성하려면:

job1:
  script:
    - echo
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "push"
      when: never

CI_PIPELINE_SOURCE 사전 정의 변수#

CI_PIPELINE_SOURCE 변수를 사용하여 다음 파이프라인 유형에 대해 잡을 추가할 시점을 제어합니다:

설명
api 파이프라인 API에 의해 트리거된 파이프라인.
chat GitLab ChatOps 명령을 사용하여 생성된 파이프라인.
external GitLab 이외의 CI 서비스를 사용하는 경우.
external_pull_request_event GitHub에서 외부 풀 요청이 생성되거나 업데이트될 때.
merge_request_event 머지 요청이 생성되거나 업데이트될 때 생성되는 파이프라인. 머지 요청 파이프라인, 병합된 결과 파이프라인, 머지 트레인을 활성화하는 데 필요합니다.
ondemand_dast_scan DAST 온디맨드 스캔 파이프라인.
ondemand_dast_validation DAST 온디맨드 유효성 검사 파이프라인.
parent_pipeline 부모 파이프라인에 의해 트리거된 자식 파이프라인. 자식 파이프라인 구성에서 이 파이프라인 소스를 사용하여 부모 파이프라인에 의해 트리거될 수 있도록 합니다.
pipeline 다중 프로젝트 파이프라인.
push 브랜치 및 태그를 포함한 Git 푸시 이벤트에 의해 트리거된 파이프라인.
schedule 예약된 파이프라인.
security_orchestration_policy 예약된 스캔 실행 정책 파이프라인.
trigger 트리거 토큰을 사용하여 생성된 파이프라인.
web 프로젝트의 빌드 > 파이프라인 섹션에서 GitLab UI의 새 파이프라인을 선택하여 생성된 파이프라인.
webide Web IDE를 사용하여 생성된 파이프라인.

이 값들은 파이프라인 API 엔드포인트를 사용할 때 source 파라미터에 반환되는 값과 동일합니다.

복잡한 규칙#

동일한 규칙에서 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일 때 실행되지 않지만, 푸시(브랜치)와 머지 요청 파이프라인 모두를 포함한 다른 모든 파이프라인에서 실행됩니다. 이 구성으로는 열린 머지 요청의 소스 브랜치에 푸시할 때마다 중복 파이프라인이 실행됩니다.

중복 파이프라인을 방지하려면 다음을 수행할 수 있습니다:

  • 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 없이 - 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 없이는 동일한 잡에 푸시와 머지 요청 파이프라인을 모두 포함하면 안 됩니다:

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/exceptrules의 서로 다른 기본 동작으로 인해 문제가 발생하여 문제를 해결하기 어려울 수 있습니다:

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)을 실행하고, 하나의 머지 요청 파이프라인은 다른 잡(job-with-rules)을 실행합니다. 규칙이 없는 잡은 기본적으로 except: merge_requests가 적용되므로 job-with-no-rules는 머지 요청을 제외한 모든 경우에 실행됩니다.

다른 잡에서 규칙 재사용#

!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: $VARIABLE_1 == $VARIABLE_2
  • if: $VARIABLE_1 != $VARIABLE_2

변수가 정의되었는지 확인하기 위해 null 키워드와 비교할 수 있습니다. 예를 들면:

  • if: $VARIABLE == null
  • if: $VARIABLE != null

변수가 정의되었지만 비어 있는지 확인할 수 있습니다. 예를 들면:

  • if: $VARIABLE == ""
  • if: $VARIABLE != ""

표현식에서 변수 이름만 사용하여 변수가 정의되었고 비어 있지 않은지 확인할 수 있습니다. 예를 들면:

  • if: $VARIABLE

다음을 수행할 수도 있습니다:

변수를 정규 표현식과 비교#

=~!~ 연산자를 사용하여 변수 값에 대해 정규 표현식 매칭을 수행할 수 있습니다.

다음의 경우 표현식이 true로 평가됩니다:

  • =~를 사용할 때 매치가 발견된 경우.
  • !~를 사용할 때 매치가 발견되지 않은 경우.

예를 들면:

  • if: $VARIABLE =~ /^content.*/
  • if: $VARIABLE !~ /^content.*/

추가 사항:

  • /./와 같은 단일 문자 정규 표현식은 지원되지 않으며 invalid expression syntax 오류를 생성합니다.
  • 패턴 매칭은 기본적으로 대소문자를 구분합니다. 패턴을 대소문자 구분 없이 만들려면 i 플래그 수정자를 사용하세요. 예: /pattern/i.
  • 태그나 브랜치 이름만 정규 표현식으로 매칭할 수 있습니다. 저장소 경로는 주어진 경우 항상 문자 그대로 매칭됩니다.
  • 전체 패턴은 /로 둘러싸여야 합니다. 예를 들어, issue-로 시작하는 모든 태그나 브랜치 이름을 매칭하기 위해 issue-/.*/를 사용할 수 없지만 /issue-.*/를 사용할 수 있습니다.
  • @ 기호는 ref의 저장소 경로 시작을 나타냅니다. 정규 표현식에서 @ 문자가 포함된 ref 이름을 매칭하려면 16진수 문자 코드 매치 \x40을 사용해야 합니다.
  • 태그 이름이나 브랜치 이름의 일부만 매칭하는 정규 표현식을 피하기 위해 앵커 ^$를 사용하세요. 예를 들어, /^issue-.*$//^issue-/와 동일하며, /issue/severe-issues라는 브랜치도 매칭합니다.
  • 정규 표현식을 사용한 변수 패턴 매칭은 RE2 정규 표현식 구문을 사용합니다.

변수에 정규 표현식 저장#

=~!~ 표현식의 오른쪽에 있는 변수는 정규 표현식으로 평가됩니다. 정규 표현식은 슬래시(/)로 둘러싸여야 합니다. 예를 들면:

variables:
  pattern: '/^ab.*/'

regex-job1:
  variables:
    teststring: 'abcde'
  script: echo "This job will run, because 'abcde' matches the /^ab.*/ pattern."
  rules:
    - if: '$teststring =~ $pattern'

regex-job2:
  variables:
    teststring: 'fghij'
  script: echo "This job will not run, because 'fghi' does not match the /^ab.*/ pattern."
  rules:
    - if: '$teststring =~ $pattern'

정규 표현식의 변수는 확장되지 않습니다. 예를 들면:

variables:
  string1: 'regex-job1'
  string2: 'regex-job2'
  pattern: '/$string2/'

regex-job1:
  script: echo "This job will NOT run, because the 'string1' variable inside the regex pattern is not expanded."
  rules:
    - if: '$CI_JOB_NAME =~ /$string1/'

regex-job2:
  script: echo "This job will NOT run, because the 'string2' variable inside the 'pattern' variable is not expanded."
  rules:
    - if: '$CI_JOB_NAME =~ $pattern'

변수 표현식 결합#

&&(and)나 ||(or)를 사용하여 여러 표현식을 결합할 수 있습니다. 예를 들면:

  • $VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"
  • $VARIABLE1 =~ /^content.*/ && $VARIABLE2 =~ /thing$/ && $VARIABLE3
  • $VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/ && $VARIABLE3

괄호를 사용하여 표현식을 그룹화할 수 있습니다. 괄호는 &&||보다 우선순위가 높으므로 괄호 안의 표현식이 먼저 평가되고, 결과가 나머지 표현식에 사용됩니다. 연산자 우선순위의 경우 &&||보다 먼저 평가됩니다.

복잡한 조건을 만들기 위해 괄호를 중첩하면 가장 안쪽의 표현식이 먼저 평가됩니다. 예를 들면:

  • ($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)
  • ($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3
  • $CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)

표현식 부정#

히스토리

! 연산자를 사용하여 표현식 또는 표현식의 일부를 부정할 수 있습니다. 예를 들면:

  • if: "!$VAR1": 변수가 비어 있거나 정의되지 않은 경우 true.
  • if: !($VAR1 == "my variable"): 변수 값이 my variable과 일치하지 않는 경우 true.
  • if: $VAR1 && !$VAR2: VAR1이 존재하고 비어 있지 않으며, VAR2가 존재하지 않거나 비어 있는 경우 true.
  • if: !($VAR1 || $VAR2): 두 변수 모두 존재하지 않거나 비어 있는 경우에만 true.
  • if: !($VAR1 && $VAR2): 두 변수 중 하나라도 존재하지 않거나 비어 있는 경우 true.
Note

! 연산자는 변수가 비어 있거나 정의되지 않았는지 확인하며, 값이 false0인지 확인하는 것이 아닙니다. 예를 들면:

  • !"false"false로 평가됩니다. 문자열 "false"는 비어 있지 않기 때문입니다(비어 있지 않은 문자열은 truthy).
  • !"0"false로 평가됩니다. 문자열이 비어 있지 않기 때문입니다.
  • !""true로 평가됩니다. 문자열이 비어 있기 때문입니다(빈 문자열은 falsy).

특정 값을 확인하려면 비교 연산자를 사용하세요. 예를 들어 !($VAR == "false") 또는 !($VAR == "0").

only 또는 except에서 rules로 마이그레이션#

rules와 CI/CD 변수 표현식을 사용하여 폐기된 onlyexcept 키워드와 동일한 동작을 재현합니다.

예를 들어, 다음과 같은 폐기된 구성에서 시작합니다:

job1:
  script: echo
  only:
    - main
    - /^stable-branch.*$/
    - schedules

job2:
  script: echo
  except:
    - main
    - /^issue-.*$/
    - merge_requests

이 예시에서:

  • job1은 다음 경우에 실행하기 위해 only를 사용합니다:
    • 브랜치가 기본 브랜치(main)인 경우.
    • 브랜치 이름이 /^stable-branch.*$/ 패턴과 매치되는 경우.
    • 파이프라인이 일정에 따라 실행되는 경우.
  • job2는 다음 경우에 건너뛰기 위해 except를 사용합니다:
    • 브랜치가 기본 브랜치(main)인 경우.
    • 브랜치 이름이 /^issue-.*$/ 패턴과 매치되는 경우.
    • 파이프라인이 머지 요청 파이프라인인 경우.

rules를 사용하여 유사한 파이프라인 구성을 만들려면 CI/CD 변수 표현식을 사용합니다. 예를 들어, onlyexcept에서 rules로 직접 마이그레이션:

job1:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH =~ /^stable-branch.*$/
    - if: $CI_PIPELINE_SOURCE == "schedule"

job2:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never
    - if: $CI_COMMIT_BRANCH =~ /^issue-.*$/
      when: never
    - when: on_success

두 잡 모두 onlyexcept와 동일하게 rules로 동작합니다. 그러나 when: never 규칙을 피하기 위해 job2를 단순화할 수 있습니다.

job2가 실행되지 말아야 할 때 대신 실행되어야 할 때에 대한 규칙을 정의합니다. 예를 들어, job2가 기본 브랜치를 제외한 모든 브랜치와 태그에서 실행되어야 한다면:

job2:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_TAG

이 예시에서 job2는 브랜치가 기본 브랜치가 아닐 때와 새 Git 태그가 생성될 때 실행됩니다. 그렇지 않으면 잡이 실행되지 않습니다.

문제 해결#

=~를 사용한 정규 표현식 매칭의 예기치 않은 동작#

=~ 문자를 사용할 때 비교의 오른쪽이 항상 유효한 정규 표현식을 포함하도록 하세요.

비교의 오른쪽이 / 문자로 둘러싸인 유효한 정규 표현식이 아닌 경우, 표현식이 예기치 않은 방식으로 평가됩니다. 이 경우 비교는 왼쪽이 오른쪽의 부분 문자열인지 확인합니다. 예를 들어, "23" =~ "1234"는 true로 평가되는데, 이는 "23" =~ /1234/가 false로 평가되는 것과 반대입니다.

이 동작에 의존하도록 파이프라인을 구성하지 마세요.

`rules`로 잡 실행 시점 지정

Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

파이프라인에서 잡을 포함하거나 제외하려면 rules 키워드를 사용하세요. 규칙은 첫 번째 매치가 발견될 때까지 순서대로 평가됩니다. rules가 평가되기 전에 어떤 잡도 실행되지 않으므로, 잡 스크립트에서 생성된 dotenv 변수를 rules에서 사용할 수 없습니다.

파이프라인에서 잡을 포함하거나 제외하려면 rules 키워드를 사용하세요.

규칙은 첫 번째 매치가 발견될 때까지 순서대로 평가됩니다. 매치가 발견되면 설정에 따라 잡이 파이프라인에 포함되거나 제외됩니다.

rules가 평가되기 전에 어떤 잡도 실행되지 않으므로, 잡 스크립트에서 생성된 dotenv 변수를 rules에서 사용할 수 없습니다.

rules 예시#

다음 예시는 if를 사용하여 두 가지 특정 경우에만 잡이 실행되도록 정의합니다:

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
      allow_failure: true
    - if: $CI_PIPELINE_SOURCE == "schedule"
  • 파이프라인이 머지 요청을 위한 것이면 첫 번째 규칙이 매치되고, 잡이 다음 속성으로 머지 요청 파이프라인에 추가됩니다:
    • when: manual (수동 잡)
    • allow_failure: true (수동 잡이 실행되지 않아도 파이프라인은 계속 실행됨)
  • 파이프라인이 머지 요청을 위한 것이 아니면 첫 번째 규칙이 매치되지 않고, 두 번째 규칙이 평가됩니다.
  • 파이프라인이 예약된 파이프라인이면 두 번째 규칙이 매치되고, 잡이 예약된 파이프라인에 추가됩니다. 속성이 정의되지 않았으므로 다음 설정으로 추가됩니다:
    • when: on_success (기본값)
    • allow_failure: false (기본값)
  • 다른 모든 경우에는 규칙이 매치되지 않으므로, 잡이 다른 파이프라인에 추가되지 않습니다.

또는 몇 가지 경우에 잡을 제외하고 다른 모든 경우에 실행하도록 규칙 세트를 정의할 수 있습니다:

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: never
    - when: on_success
  • 파이프라인이 머지 요청을 위한 것이면 잡이 파이프라인에 추가되지 않습니다.
  • 파이프라인이 예약된 파이프라인이면 잡이 파이프라인에 추가되지 않습니다.
  • 다른 모든 경우에는 잡이 when: on_success로 파이프라인에 추가됩니다.
Warning

마지막 규칙으로 when 절을 사용하면(when: never 제외), 두 개의 파이프라인이 동시에 시작될 수 있습니다. 푸시 파이프라인과 머지 요청 파이프라인 모두 동일한 이벤트(열린 머지 요청의 소스 브랜치에 푸시)에 의해 트리거될 수 있습니다. 자세한 내용은 중복 파이프라인 방지를 참조하세요.

예약된 파이프라인에서 잡 실행#

파이프라인이 예약된 경우에만 잡을 실행하도록 구성할 수 있습니다. 예를 들면:

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는 브랜치 및 태그 파이프라인에서 실행됩니다.

브랜치가 비어 있으면 잡 건너뜀#

CI/CD 리소스를 절약하기 위해 브랜치가 비어 있을 때 잡을 건너뛰려면 rules:changes:compare_to를 사용하세요. 구성은 브랜치를 기본 브랜치와 비교하며, 브랜치가:

  • 변경된 파일이 없으면 잡이 실행되지 않습니다.
  • 변경된 파일이 있으면 잡이 실행됩니다.

예를 들어, main을 기본 브랜치로 사용하는 프로젝트에서:

job:
  script:
    - echo "This job only runs for branches that are not empty"
  rules:
    - if: $CI_COMMIT_BRANCH
      changes:
        compare_to: 'refs/heads/main'
        paths:
          - '**/*'

이 잡의 규칙은 현재 브랜치의 모든 파일과 경로를 재귀적으로(**/*) main 브랜치와 비교합니다. 브랜치에 변경 사항이 있을 때만 규칙이 매치되어 잡이 실행됩니다.

parallel:matrix 잡의 경우, rules:changes 경로에 매트릭스 변수를 사용하여 해당 매트릭스 값과 관련된 파일이 변경된 경우에만 각 잡 인스턴스를 실행할 수 있습니다.

파일이 없을 때 잡 실행#

rules: exists를 사용하여 특정 파일이 없을 때만 잡이 실행되도록 구성할 수 있습니다.

예를 들어, example.yml 파일이 없을 때 머지 요청 파이프라인에서 잡을 실행하려면:

job:
  script: echo "Hello, Rules!"
  rules:
    - exists:
      - "example_dir/example.yml"
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

이 예시에서 브랜치에 example_dir/example.yml 파일이 있으면 잡이 실행되지 않습니다. 파일이 없으면 머지 요청 파이프라인에서 잡이 실행될 수 있습니다.

parallel:matrix 잡의 경우, rules:exists 경로에 매트릭스 변수를 사용하여 특정 파일이 존재할 때만 잡 인스턴스를 포함할 수 있습니다.

사전 정의된 변수를 사용하는 일반적인 if#

rules:if 절은 일반적으로 사전 정의된 CI/CD 변수, 특히 CI_PIPELINE_SOURCE와 함께 사용됩니다.

다음 예시는 예약된 파이프라인이나 푸시 파이프라인(브랜치 또는 태그)에서 잡을 수동 잡으로 실행하고, 그 외에는 when: on_success(기본값)로 실행합니다. 다른 파이프라인 유형에는 잡을 추가하지 않습니다.

job:
  script: echo "Hello, Rules!"
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: manual
      allow_failure: true
    - if: $CI_PIPELINE_SOURCE == "push"

다음 예시는 머지 요청 파이프라인과 예약된 파이프라인에서 잡을 when: on_success 잡으로 실행합니다. 다른 파이프라인 유형에서는 실행되지 않습니다.

job:
  script: echo "Hello, 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 =~ /regex-expression/: 커밋 브랜치가 정규 표현식과 매치되는 경우.
  • if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /Merge branch.*/: 커밋 브랜치가 기본 브랜치이고 커밋 메시지 제목이 정규 표현식과 매치되는 경우.
  • if: $CUSTOM_VARIABLE == "value1": 사용자 정의 변수 CUSTOM_VARIABLE이 정확히 value1인 경우.

특정 파이프라인 유형에서만 잡 실행#

사전 정의된 CI/CD 변수를 rules와 함께 사용하여 잡이 어떤 파이프라인 유형에서 실행될지 선택할 수 있습니다.

다음 표는 사용할 수 있는 몇 가지 변수와 해당 변수가 제어할 수 있는 파이프라인 유형을 나열합니다:

  • 브랜치에 새 커밋이나 태그 등 Git push 이벤트가 발생할 때 실행되는 브랜치 파이프라인.
  • 새 Git 태그가 브랜치에 푸시될 때만 실행되는 태그 파이프라인.
  • 새 커밋 추가나 머지 요청의 파이프라인 탭에서 파이프라인 실행을 선택하는 등 머지 요청에 변경 사항이 있을 때 실행되는 머지 요청 파이프라인.
  • 예약된 파이프라인.
변수 브랜치 태그 머지 요청 예약됨
CI_COMMIT_BRANCH
CI_COMMIT_TAG 예, 예약된 파이프라인이 태그에서 실행되도록 구성된 경우.
CI_PIPELINE_SOURCE = push
CI_PIPELINE_SOURCE = schedule
CI_PIPELINE_SOURCE = merge_request_event
CI_MERGE_REQUEST_IID

예를 들어, 브랜치나 태그 파이프라인이 아닌 머지 요청 파이프라인과 예약된 파이프라인에서만 잡이 실행되도록 구성하려면:

job1:
  script:
    - echo
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "push"
      when: never

CI_PIPELINE_SOURCE 사전 정의 변수#

CI_PIPELINE_SOURCE 변수를 사용하여 다음 파이프라인 유형에 대해 잡을 추가할 시점을 제어합니다:

설명
api 파이프라인 API에 의해 트리거된 파이프라인.
chat GitLab ChatOps 명령을 사용하여 생성된 파이프라인.
external GitLab 이외의 CI 서비스를 사용하는 경우.
external_pull_request_event GitHub에서 외부 풀 요청이 생성되거나 업데이트될 때.
merge_request_event 머지 요청이 생성되거나 업데이트될 때 생성되는 파이프라인. 머지 요청 파이프라인, 병합된 결과 파이프라인, 머지 트레인을 활성화하는 데 필요합니다.
ondemand_dast_scan DAST 온디맨드 스캔 파이프라인.
ondemand_dast_validation DAST 온디맨드 유효성 검사 파이프라인.
parent_pipeline 부모 파이프라인에 의해 트리거된 자식 파이프라인. 자식 파이프라인 구성에서 이 파이프라인 소스를 사용하여 부모 파이프라인에 의해 트리거될 수 있도록 합니다.
pipeline 다중 프로젝트 파이프라인.
push 브랜치 및 태그를 포함한 Git 푸시 이벤트에 의해 트리거된 파이프라인.
schedule 예약된 파이프라인.
security_orchestration_policy 예약된 스캔 실행 정책 파이프라인.
trigger 트리거 토큰을 사용하여 생성된 파이프라인.
web 프로젝트의 빌드 > 파이프라인 섹션에서 GitLab UI의 새 파이프라인을 선택하여 생성된 파이프라인.
webide Web IDE를 사용하여 생성된 파이프라인.

이 값들은 파이프라인 API 엔드포인트를 사용할 때 source 파라미터에 반환되는 값과 동일합니다.

복잡한 규칙#

동일한 규칙에서 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일 때 실행되지 않지만, 푸시(브랜치)와 머지 요청 파이프라인 모두를 포함한 다른 모든 파이프라인에서 실행됩니다. 이 구성으로는 열린 머지 요청의 소스 브랜치에 푸시할 때마다 중복 파이프라인이 실행됩니다.

중복 파이프라인을 방지하려면 다음을 수행할 수 있습니다:

  • 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 없이 - 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 없이는 동일한 잡에 푸시와 머지 요청 파이프라인을 모두 포함하면 안 됩니다:

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/exceptrules의 서로 다른 기본 동작으로 인해 문제가 발생하여 문제를 해결하기 어려울 수 있습니다:

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)을 실행하고, 하나의 머지 요청 파이프라인은 다른 잡(job-with-rules)을 실행합니다. 규칙이 없는 잡은 기본적으로 except: merge_requests가 적용되므로 job-with-no-rules는 머지 요청을 제외한 모든 경우에 실행됩니다.

다른 잡에서 규칙 재사용#

!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: $VARIABLE_1 == $VARIABLE_2
  • if: $VARIABLE_1 != $VARIABLE_2

변수가 정의되었는지 확인하기 위해 null 키워드와 비교할 수 있습니다. 예를 들면:

  • if: $VARIABLE == null
  • if: $VARIABLE != null

변수가 정의되었지만 비어 있는지 확인할 수 있습니다. 예를 들면:

  • if: $VARIABLE == ""
  • if: $VARIABLE != ""

표현식에서 변수 이름만 사용하여 변수가 정의되었고 비어 있지 않은지 확인할 수 있습니다. 예를 들면:

  • if: $VARIABLE

다음을 수행할 수도 있습니다:

변수를 정규 표현식과 비교#

=~!~ 연산자를 사용하여 변수 값에 대해 정규 표현식 매칭을 수행할 수 있습니다.

다음의 경우 표현식이 true로 평가됩니다:

  • =~를 사용할 때 매치가 발견된 경우.
  • !~를 사용할 때 매치가 발견되지 않은 경우.

예를 들면:

  • if: $VARIABLE =~ /^content.*/
  • if: $VARIABLE !~ /^content.*/

추가 사항:

  • /./와 같은 단일 문자 정규 표현식은 지원되지 않으며 invalid expression syntax 오류를 생성합니다.
  • 패턴 매칭은 기본적으로 대소문자를 구분합니다. 패턴을 대소문자 구분 없이 만들려면 i 플래그 수정자를 사용하세요. 예: /pattern/i.
  • 태그나 브랜치 이름만 정규 표현식으로 매칭할 수 있습니다. 저장소 경로는 주어진 경우 항상 문자 그대로 매칭됩니다.
  • 전체 패턴은 /로 둘러싸여야 합니다. 예를 들어, issue-로 시작하는 모든 태그나 브랜치 이름을 매칭하기 위해 issue-/.*/를 사용할 수 없지만 /issue-.*/를 사용할 수 있습니다.
  • @ 기호는 ref의 저장소 경로 시작을 나타냅니다. 정규 표현식에서 @ 문자가 포함된 ref 이름을 매칭하려면 16진수 문자 코드 매치 \x40을 사용해야 합니다.
  • 태그 이름이나 브랜치 이름의 일부만 매칭하는 정규 표현식을 피하기 위해 앵커 ^$를 사용하세요. 예를 들어, /^issue-.*$//^issue-/와 동일하며, /issue/severe-issues라는 브랜치도 매칭합니다.
  • 정규 표현식을 사용한 변수 패턴 매칭은 RE2 정규 표현식 구문을 사용합니다.

변수에 정규 표현식 저장#

=~!~ 표현식의 오른쪽에 있는 변수는 정규 표현식으로 평가됩니다. 정규 표현식은 슬래시(/)로 둘러싸여야 합니다. 예를 들면:

variables:
  pattern: '/^ab.*/'

regex-job1:
  variables:
    teststring: 'abcde'
  script: echo "This job will run, because 'abcde' matches the /^ab.*/ pattern."
  rules:
    - if: '$teststring =~ $pattern'

regex-job2:
  variables:
    teststring: 'fghij'
  script: echo "This job will not run, because 'fghi' does not match the /^ab.*/ pattern."
  rules:
    - if: '$teststring =~ $pattern'

정규 표현식의 변수는 확장되지 않습니다. 예를 들면:

variables:
  string1: 'regex-job1'
  string2: 'regex-job2'
  pattern: '/$string2/'

regex-job1:
  script: echo "This job will NOT run, because the 'string1' variable inside the regex pattern is not expanded."
  rules:
    - if: '$CI_JOB_NAME =~ /$string1/'

regex-job2:
  script: echo "This job will NOT run, because the 'string2' variable inside the 'pattern' variable is not expanded."
  rules:
    - if: '$CI_JOB_NAME =~ $pattern'

변수 표현식 결합#

&&(and)나 ||(or)를 사용하여 여러 표현식을 결합할 수 있습니다. 예를 들면:

  • $VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"
  • $VARIABLE1 =~ /^content.*/ && $VARIABLE2 =~ /thing$/ && $VARIABLE3
  • $VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/ && $VARIABLE3

괄호를 사용하여 표현식을 그룹화할 수 있습니다. 괄호는 &&||보다 우선순위가 높으므로 괄호 안의 표현식이 먼저 평가되고, 결과가 나머지 표현식에 사용됩니다. 연산자 우선순위의 경우 &&||보다 먼저 평가됩니다.

복잡한 조건을 만들기 위해 괄호를 중첩하면 가장 안쪽의 표현식이 먼저 평가됩니다. 예를 들면:

  • ($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)
  • ($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3
  • $CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)

표현식 부정#

히스토리

! 연산자를 사용하여 표현식 또는 표현식의 일부를 부정할 수 있습니다. 예를 들면:

  • if: "!$VAR1": 변수가 비어 있거나 정의되지 않은 경우 true.
  • if: !($VAR1 == "my variable"): 변수 값이 my variable과 일치하지 않는 경우 true.
  • if: $VAR1 && !$VAR2: VAR1이 존재하고 비어 있지 않으며, VAR2가 존재하지 않거나 비어 있는 경우 true.
  • if: !($VAR1 || $VAR2): 두 변수 모두 존재하지 않거나 비어 있는 경우에만 true.
  • if: !($VAR1 && $VAR2): 두 변수 중 하나라도 존재하지 않거나 비어 있는 경우 true.
Note

! 연산자는 변수가 비어 있거나 정의되지 않았는지 확인하며, 값이 false0인지 확인하는 것이 아닙니다. 예를 들면:

  • !"false"false로 평가됩니다. 문자열 "false"는 비어 있지 않기 때문입니다(비어 있지 않은 문자열은 truthy).
  • !"0"false로 평가됩니다. 문자열이 비어 있지 않기 때문입니다.
  • !""true로 평가됩니다. 문자열이 비어 있기 때문입니다(빈 문자열은 falsy).

특정 값을 확인하려면 비교 연산자를 사용하세요. 예를 들어 !($VAR == "false") 또는 !($VAR == "0").

only 또는 except에서 rules로 마이그레이션#

rules와 CI/CD 변수 표현식을 사용하여 폐기된 onlyexcept 키워드와 동일한 동작을 재현합니다.

예를 들어, 다음과 같은 폐기된 구성에서 시작합니다:

job1:
  script: echo
  only:
    - main
    - /^stable-branch.*$/
    - schedules

job2:
  script: echo
  except:
    - main
    - /^issue-.*$/
    - merge_requests

이 예시에서:

  • job1은 다음 경우에 실행하기 위해 only를 사용합니다:
    • 브랜치가 기본 브랜치(main)인 경우.
    • 브랜치 이름이 /^stable-branch.*$/ 패턴과 매치되는 경우.
    • 파이프라인이 일정에 따라 실행되는 경우.
  • job2는 다음 경우에 건너뛰기 위해 except를 사용합니다:
    • 브랜치가 기본 브랜치(main)인 경우.
    • 브랜치 이름이 /^issue-.*$/ 패턴과 매치되는 경우.
    • 파이프라인이 머지 요청 파이프라인인 경우.

rules를 사용하여 유사한 파이프라인 구성을 만들려면 CI/CD 변수 표현식을 사용합니다. 예를 들어, onlyexcept에서 rules로 직접 마이그레이션:

job1:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_BRANCH =~ /^stable-branch.*$/
    - if: $CI_PIPELINE_SOURCE == "schedule"

job2:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: never
    - if: $CI_COMMIT_BRANCH =~ /^issue-.*$/
      when: never
    - when: on_success

두 잡 모두 onlyexcept와 동일하게 rules로 동작합니다. 그러나 when: never 규칙을 피하기 위해 job2를 단순화할 수 있습니다.

job2가 실행되지 말아야 할 때 대신 실행되어야 할 때에 대한 규칙을 정의합니다. 예를 들어, job2가 기본 브랜치를 제외한 모든 브랜치와 태그에서 실행되어야 한다면:

job2:
  script: echo
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
    - if: $CI_COMMIT_TAG

이 예시에서 job2는 브랜치가 기본 브랜치가 아닐 때와 새 Git 태그가 생성될 때 실행됩니다. 그렇지 않으면 잡이 실행되지 않습니다.

문제 해결#

=~를 사용한 정규 표현식 매칭의 예기치 않은 동작#

=~ 문자를 사용할 때 비교의 오른쪽이 항상 유효한 정규 표현식을 포함하도록 하세요.

비교의 오른쪽이 / 문자로 둘러싸인 유효한 정규 표현식이 아닌 경우, 표현식이 예기치 않은 방식으로 평가됩니다. 이 경우 비교는 왼쪽이 오른쪽의 부분 문자열인지 확인합니다. 예를 들어, "23" =~ "1234"는 true로 평가되는데, 이는 "23" =~ /1234/가 false로 평가되는 것과 반대입니다.

이 동작에 의존하도록 파이프라인을 구성하지 마세요.