CI/CD inputs

CI/CD inputs

CI/CD inputs는 CI/CD 구성을 더 유연하게 만들어 주는 기능이에요. inputs와 CI/CD 변수는 비슷한 방식으로 쓸 수 있지만 이점이 달라요.

  • inputs는 재사용 템플릿용 타입이 있는 매개변수를 제공하고, 파이프라인 생성 시점에 검증이 내장돼 있어요. 파이프라인이 실행될 때 특정 값을 정의하려면 CI/CD 변수 대신 inputs를 쓰세요.
  • CI/CD 변수는 여러 레벨에서 정의할 수 있는 유연한 값을 제공하지만 파이프라인 실행 중에 수정될 수 있어요. job의 런타임 환경에서 접근해야 하는 값에는 변수를 쓰세요. 조건부 include를 통한 동적 파이프라인 구성에는 사전 정의 변수include:rules를 함께 쓸 수도 있습니다.

출처: 문서

본문

CI/CD inputs와 변수 비교 (CI/CD Inputs and variables comparison)

Inputs:

  • 목적: CI/CD 구성(템플릿, 컴포넌트 또는 .gitlab-ci.yml)에 정의되고 파이프라인이 트리거될 때 값이 할당되어, 소비자가 재사용 CI 구성을 커스터마이즈할 수 있게 해줘요.
  • 수정: 파이프라인 초기화 시 전달되면 input 값은 CI/CD 구성에서 보간되고 파이프라인 실행 전체 동안 고정됩니다.
  • 범위: .gitlab-ci.yml이든 include 되는 파일이든 정의된 파일에서만 사용할 수 있어요. include:inputs로 다른 파일에, trigger:inputs로 파이프라인에 명시적으로 전달할 수 있습니다.
  • 검증: 타입 검사, 정규 표현식 패턴, 미리 정의된 옵션 목록, 사용자에게 유용한 설명을 포함한 강력한 검증 기능을 제공해요.

CI/CD Variables:

  • 목적: job 실행 중 환경 변수로 설정하고 파이프라인의 다양한 부분에서 job 간 데이터를 전달하는 데 쓸 수 있는 값.
  • 수정: dotenv artifacts, 조건부 rules, 또는 job 스크립트에서 직접 파이프라인 실행 중 동적으로 생성·수정될 수 있어요.
  • 범위: 전역(모든 job에 영향), job 레벨(특정 job에만 영향), 또는 GitLab UI를 통해 프로젝트·그룹 전체에 정의할 수 있어요.
  • 검증: 최소한의 내장 검증을 가진 키-값 쌍. 다만 프로젝트 변수의 경우 GitLab UI를 통해 일부 제어를 추가할 수 있어요.

spec:inputs로 입력 매개변수 정의 (Define input parameters with spec:inputs)

CI/CD 구성의 헤더에서 spec:inputs를 사용해 구성 파일에 전달할 수 있는 입력 매개변수를 정의해요. 입력을 사용할 위치를 선언하려면 헤더 섹션 밖에서 $[[ inputs.input-id ]] 보간 형식을 사용합니다. 예를 들면 이렇습니다.

spec:
  inputs:
    job-stage:
      default: test
    environment:
      default: production
---
scan-website:
  stage: $[[ inputs.job-stage ]]
  script: ./scan-website $[[ inputs.environment ]]

이 예시에서 inputs는 job-stageenvironment예요. inputs 값은 spec 섹션이 있는 파일에서만 쓸 수 있습니다. include로 추가된 다른 파일에서 입력 값을 쓰려면 포함된 파일에 명시적으로 전달해야 해요.

spec:inputs와 함께:

  • default가 지정되지 않으면 inputs는 필수예요.
  • inputs는 파이프라인 생성 중 구성이 가져와질 때 평가되고 채워집니다.
  • 입력을 포함하는 문자열은 1MB보다 작아야 해요.
  • 입력 안의 문자열은 1KB보다 작아야 해요.
  • inputs는 CI/CD 변수를 쓸 수 있지만 include 키워드와 같은 변수 제한이 있어요.
  • spec:inputs를 정의하는 파일에 job 정의도 있다면 헤더 뒤에 YAML 문서 구분자(---)를 추가하세요.

그런 다음 이 구성 파일을 다음 방법으로 사용할 때 inputs의 값을 설정합니다.

  • 이 구성 파일로 새 파이프라인 실행. include가 아닌 다른 방법으로 새 파이프라인을 구성할 때는 항상 기본값을 설정해야 해요. 그렇지 않으면 MR 파이프라인, 브랜치 파이프라인, 태그 파이프라인 같은 자동 트리거에서 새 파이프라인이 실패할 수 있습니다.
  • 파이프라인에 구성 추가(include). 필수 inputs는 모두 include:inputs 섹션에 추가해야 하고, 구성이 include될 때마다 사용됩니다.

입력 구성 (Input configuration)

inputs를 구성하려면:

  • spec:inputs:default로 지정하지 않았을 때 inputs의 기본값을 정의. 기본값을 지정하면 inputs가 더 이상 필수가 아니에요.
  • spec:inputs:description으로 특정 입력에 대한 설명 제공. 설명은 입력에 영향을 주지 않지만, 사람들이 입력 세부 사항이나 기대값을 이해하는 데 도움이 돼요.
  • spec:inputs:options으로 입력에 허용되는 값 목록을 지정.
  • spec:inputs:regex로 입력이 일치해야 하는 정규 표현식을 지정.
  • spec:inputs:type으로 특정 입력 타입을 강제. string(지정하지 않을 때 기본), array, number, boolean이 될 수 있어요.
  • spec:inputs:rules로 다른 inputs의 값에 따라 조건부 optionsdefault 값을 정의.

CI/CD 구성 파일당 여러 inputs를 정의할 수 있고, 각 입력은 여러 구성 매개변수를 가질 수 있어요. 예를 들어 scan-website-job.yml이라는 파일에서:

spec:
  inputs:
    job-prefix:     # Mandatory string input
      description: "Define a prefix for the job name"
    job-stage:      # Optional string input with a default value when not provided
      default: test
    environment:    # Mandatory input that must match one of the options
      options: ['test', 'staging', 'production']
    concurrency:
      type: number  # Optional numeric input with a default value when not provided
      default: 1
    version:        # Mandatory string input that must match the regular expression
      type: string
      regex: ^v\d\.\d+(\.\d+)$
    export_results: # Optional boolean input with a default value when not provided
      type: boolean
      default: true
---


"$[[ inputs.job-prefix ]]-scan-website":
  stage: $[[ inputs.job-stage ]]
  script:
    - echo "scanning website -e $[[ inputs.environment ]] -c $[[ inputs.concurrency ]] -v $[[ inputs.version ]]"
    - if $[[ inputs.export_results ]]; then echo "export results"; fi

이 예시에서:

  • job-prefix는 필수 string 입력이고 반드시 정의해야 해요.
  • job-stage는 선택 사항입니다. 정의하지 않으면 값은 test예요.
  • environment는 정의된 옵션 중 하나와 일치해야 하는 필수 string 입력.
  • concurrency는 선택적 숫자 입력입니다. 지정하지 않으면 1로 기본값이 돼요.
  • version은 지정된 정규 표현식과 일치해야 하는 필수 string 입력.
  • export_results는 선택적 boolean 입력입니다. 지정하지 않으면 true로 기본값이 돼요.

입력 타입 (Input types)

선택적 spec:inputs:type 키워드로 입력이 특정 타입을 사용해야 한다고 지정할 수 있어요. 입력 타입은:

  • array
  • boolean
  • number
  • string(지정하지 않을 때 기본)

입력이 CI/CD 구성에서 전체 YAML 값을 대체할 때는 지정된 타입으로 구성에 보간됩니다. 예를 들면 이렇습니다.

spec:
  inputs:
    array_input:
      type: array
    boolean_input:
      type: boolean
    number_input:
      type: number
    string_input:
      type: string
---

test_job:
  allow_failure: $[[ inputs.boolean_input ]]
  needs: $[[ inputs.array_input ]]
  parallel: $[[ inputs.number_input ]]
  script: $[[ inputs.string_input ]]

입력이 더 큰 문자열의 일부로 YAML 값에 삽입되면 항상 문자열로 보간됩니다. 예를 들면 이렇습니다.

spec:
  inputs:
    port:
      type: number
---

test_job:
  script: curl "https://gitlab.com:$[[ inputs.port ]]"
배열 타입 (Array type)

배열 타입 항목의 내용은 유효한 YAML 맵, 시퀀스 또는 스칼라일 수 있어요. !reference 같은 더 복잡한 YAML 기능은 사용할 수 없습니다. 구성 파일 전체에 목록을 재사용하려면 외부 파일에 배열 입력을 정의한 뒤 추가 항목으로 확장할 수 있어요.

문자열에서 배열 입력의 값을 쓸 때(예: script: 섹션의 echo "My rules: $[[ inputs.rules-config ]]") 예상치 못한 결과가 나올 수 있어요. 배열 입력은 문자열 표현으로 변환되는데, 맵 같은 복잡한 YAML 구조에서는 기대와 다를 수 있습니다.

spec:
  inputs:
    rules-config:
      type: array
      default:
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
          when: manual
        - if: $CI_PIPELINE_SOURCE == "schedule"
---

test_job:
  rules: $[[ inputs.rules-config ]]
  script: ls

배열 입력은 다음에 대해 수동으로 전달할 때 반드시 JSON 형식(예: ["array-input-1", "array-input-2"])이어야 해요.

추가 항목으로 배열 입력 확장 (Extend an array input with additional items)

배열 입력이 배열의 전체 항목일 때, 그 항목들은 주변 배열에 중첩되지 않고 추가됩니다. 이걸로 공유 목록을 추가 항목으로 확장할 수 있어요.

spec:
  inputs:
    tags:
      type: array
---

test_job:
  tags:
    - $[[ inputs.tags ]]
    - additional-tag
  script: ls

입력 값이 [shared-tag-1, shared-tag-2]이면 test_job[shared-tag-1, shared-tag-2, additional-tag]를 사용합니다. 입력은 배열의 전체 항목이어야 해요. 배열 항목이 입력을 다른 텍스트와 결합할 때(예: - prefix-$[[ inputs.tags ]]) GitLab은 입력을 문자열로 보간합니다. 항목은 배열의 문자열 표현을 포함하는 단일 문자열이 됩니다.

옵션이 있는 배열 입력 (Array inputs with options)

배열 입력의 허용 값을 제한하는 옵션 목록을 정의할 수 있어요. 파이프라인을 수동으로 실행하면 UI가 텍스트 필드 대신 다중 선택 드롭다운 목록을 표시해요. 예를 들면 이렇습니다.

spec:
  inputs:
    runner_tags:
      type: array
      default: ["docker"]
      options:
        - docker
        - linux
        - gpu
        - macos
---

test:
  script:
    - run_tests.sh
  tags: $[[ inputs.runner_tags ]]

배열 입력의 값이 나열된 옵션과 일치하지 않으면 파이프라인이 시작에 실패합니다.

개별 배열 요소 접근 (Access individual array elements)
  • ci_inputs_array_index_operator라는 기능 플래그와 함께 GitLab 18.10에서 도입. 기본적으로 비활성화.
  • GitLab 18.11에서 일반 공개. 기능 플래그 ci_inputs_array_index_operator 제거.

인덱스 번호가 있는 대괄호 표기법으로 배열 입력의 개별 요소에 접근할 수 있어요. 배열 항목은 YAML 배열에 정의된 순서대로 양수로 인덱싱됩니다. [0] 인덱스 항목이 배열의 첫 번째 항목이에요. 예를 들면 이렇습니다.

spec:
  inputs:
    supported_versions:
      type: array
      default:
        - '2.0'
        - '1.0'
        - '0.1'
---

job:
  script:
    # Outputs: 'Latest version is 2.0'
    - echo 'Latest version is $[[ inputs.supported_versions[0] ]]'

점 표기법과 함께 배열 인덱싱을 연결해서 중첩 값을 접근할 수 있어요.

spec:
  inputs:
    servers:
      type: array
      default:
        - host: server1.example.com
          port: 8080
---

job:
  script:
    - curl "https://$[[ inputs.servers[0].host ]]:$[[ inputs.servers[0].port ]]"

다차원 배열에는 여러 인덱스를 연속으로 쓰세요. 예를 들어 2차원 배열에는 [0][1]을 쓸 수 있어요.

spec:
  inputs:
    matrix:
      type: array
      default:
        - ['a', 'b']
        - ['c', 'd']
---

job:
  script:
    # Outputs: 'b'
    - echo $[[ inputs.matrix[0][1] ]]

세그먼트당 최대 5개의 인덱스를 연결할 수 있어요. 예: arr[0][1][2][3][4].

여러 줄 입력 문자열 값 (Multi-line input string values)

inputs는 다양한 값 타입을 지원해요. 다음 형식으로 여러 문자열 값을 전달할 수 있습니다.

spec:
  inputs:
    closed_message:
      description: Message to announce when an issue is closed.
      default: 'Hi {{author}} :wave:,

        Based on the policy for inactive issues, this is now being closed.

        If this issue requires further attention, reopen this issue.'
---

spec:inputs:rules로 조건부 입력 옵션 정의 (Define conditional input options with spec:inputs:rules)

spec:inputs:rules로 다른 inputs의 값에 따라 입력의 서로 다른 optionsdefault 값을 정의할 수 있어요. 한 입력이 다른 inputs가 제공하는 컨텍스트에 따라 다른 허용 값을 가져야 할 때 이 구성을 사용할 수 있습니다. rules 목록의 각 규칙은 가질 수 있어요.

  • if: 이 규칙이 언제 적용되는지 결정하기 위해 하나 이상의 inputs 값을 확인하는 표현식. $[[ inputs.input-id ]] 보간과 같은 문법을 사용해요.
  • options: 이 규칙이 일치할 때 입력의 허용 값 목록.
  • default: 이 규칙이 일치할 때 사용할 기본값.

규칙은 순서대로 평가됩니다. if 조건이 일치하는 첫 번째 규칙이 사용됩니다. if 조건이 없는 마지막 규칙은 다른 규칙이 일치하지 않을 때 폴백으로 동작합니다. 예를 들어 클라우드 제공자와 환경에 따라 달라지는 인스턴스 타입을 정의하려면:

spec:
  inputs:
    cloud_provider:
      options: ['aws', 'gcp', 'azure']
      default: 'aws'
      description: 'Cloud provider'

    environment:
      options: ['development', 'staging', 'production']
      default: 'development'
      description: 'Target environment'

    instance_type:
      description: 'VM instance type'
      rules:
        - if: $[[ inputs.cloud_provider ]] == 'aws' && $[[ inputs.environment ]] == 'development'
          options: ['t3.micro', 't3.small']
          default: 't3.micro'
        - if: $[[ inputs.cloud_provider ]] == 'aws' && $[[ inputs.environment ]] == 'production'
          options: ['t3.xlarge', 't3.2xlarge', 'm5.xlarge']
          default: 't3.xlarge'
        - if: $[[ inputs.cloud_provider ]] == 'gcp'
          options: ['e2-micro', 'e2-small', 'e2-standard-4']
          default: 'e2-micro'
        - if: $[[ inputs.cloud_provider ]] == 'azure'
          options: ['Standard_B1s', 'Standard_B2s', 'Standard_D2s_v3']
          default: 'Standard_B1s'
        - options: ['small', 'medium', 'large']  # Fallback for any other case
          default: 'small'
---

deploy:
  script: |
    echo "Deploying to $[[ inputs.cloud_provider ]]"
    echo "Environment: $[[ inputs.environment ]]"
    echo "Instance: $[[ inputs.instance_type ]]"

이 예시에서:

  • cloud_provideraws이고 environmentdevelopment일 때 사용자는 t3.micro 또는 t3.small에서 선택할 수 있고 기본값은 t3.micro예요.
  • cloud_provideraws이고 environmentproduction이면 다른 인스턴스 타입(t3.xlarge, t3.2xlarge, m5.xlarge)을 사용할 수 있어요.
  • cloud_providergcp이면 환경과 관계없이 GCP 특화 인스턴스 타입을 사용할 수 있어요.
  • 어떤 조건도 일치하지 않으면 폴백 규칙이 일반 size 옵션을 제공해요.

||(OR) 연산자로 여러 조건을 일치시킬 수도 있어요. 예를 들면 이렇습니다.

spec:
  inputs:
    deployment_type:
      options: ['canary', 'blue-green', 'rolling', 'recreate']
      default: 'rolling'

    requires_approval:
      description: 'Whether deployment requires manual approval'
      rules:
        - if: $[[ inputs.deployment_type ]] == 'canary' || $[[ inputs.deployment_type ]] == 'blue-green'
          options: ['true']
          default: 'true'
        - options: ['true', 'false']
          default: 'false'
---

deploy:
  script: echo "Deploying with $[[ inputs.deployment_type ]] strategy"

이 예시에서 requires_approval 입력은 deployment_typecanary 또는 blue-green일 때 true로 설정됩니다. 그 외의 경우 기본값은 false이고 truefalse가 모두 허용 옵션이에요.

default: null로 사용자 입력 값 허용 (Allow user-entered values with default: null)

spec:inputs:rulesoptions 없이 default: null과 함께 사용하면 사용자가 환경 이름이나 테스트 구성 같은 자신의 값을 입력할 수 있게 해요. 예를 들면 이렇습니다.

spec:
  inputs:
    deployment_type:
      options: ['standard', 'custom']
      default: 'standard'

    custom_config:
      description: 'Custom configuration value'
      rules:
        - if: $[[ inputs.deployment_type ]] == 'custom'
          default: null
---

deploy:
  script: echo "Config: $[[ inputs.custom_config ]]"

이 예시에서 deployment_typecustom일 때 custom_config 입력이 Run new pipeline 페이지에 나타나고 사용자가 값을 입력해야 해요.

spec:inputs:rules와 함께 boolean inputs 사용 (Use boolean inputs with spec:inputs:rules)

규칙 조건에서 boolean inputs를 쓸 수 있어요. boolean 값은 boolean 리터럴(true/false)로 비교할 수 있습니다.

spec:
  inputs:
    publish:
      type: boolean
      default: true

    publish_stage:
      rules:
        - if: $[[ inputs.publish ]] == true
          default: 'publish'
        - if: $[[ inputs.publish ]] == false
          default: 'test'
---

job:
  stage: $[[ inputs.publish_stage ]]
  script: echo "Publishing is $[[ inputs.publish ]]"

이 예시에서 publishtrue이면 publish_stagepublish로 기본값이 되고, false이면 test로 기본값이 돼요.

입력 값 설정 (Set input values)

파이프라인 구성에서 또는 파이프라인을 트리거할 때 입력 값을 설정할 수 있어요. 파이프라인이 시작된 뒤에는 사용된 입력 값을 가져올 수 없습니다. 노출해도 안전한 값이라면 job 로그에 값을 출력해 나중에 참조하거나 artifact에 저장할 수 있어요.

include로 추가된 구성에서 (For configuration added with include)

include:inputs로 포함된 구성이 파이프라인에 추가될 때 입력 값을 설정할 수 있어요. 여기에는 CI/CD componentsinclude로 추가되는 다른 구성이 포함됩니다. 예를 들어 입력 구성 예시scan-website-job.yml을 include하고 입력 값을 설정하려면:

include:
  - local: 'scan-website-job.yml'
    inputs:
      job-prefix: 'some-service-'
      environment: 'staging'
      concurrency: 2
      version: 'v1.3.2'
      export_results: false

이 예시에서 포함된 구성의 inputs는: | 입력 | 값 | 세부 사항 | | --- | --- | --- | | job-prefix | some-service- | 반드시 명시적으로 정의해야 해요. | | job-stage | test | include:inputs에 정의되지 않아, 포함된 구성의 spec:inputs:default에서 값이 옵니다. | | environment | staging | 반드시 명시적으로 정의하고, 포함된 구성의 spec:inputs:options 값 중 하나와 일치해야 해요. | | concurrency | 2 | 포함된 구성의 typenumberspec:inputs:type과 일치하려면 숫자 값이어야 해요. 기본값을 덮어씁니다. | | version | v1.3.2 | 반드시 명시적으로 정의하고, 포함된 구성의 spec:inputs:regex의 정규 표현식과 일치해야 해요. | | export_results | false | 포함된 구성의 typebooleanspec:inputs:type과 일치하려면 true 또는 false여야 해요. 기본값을 덮어씁니다. |

입력 값은 정의하는 spec 섹션과 같은 파일에서만 사용할 수 있어요. include로 추가된 파일은 다른 파일이나 include하는 파일에 정의된 inputs에 접근할 수 없습니다. 포함된 파일의 값을 쓰려면 include:inputs로 명시적으로 전달하세요.

여러 include 항목에서 (With multiple include entries)

inputs는 각 include 항목별로 별도로 지정해야 해요. 예를 들면 이렇습니다.

include:
  - component: $CI_SERVER_FQDN/the-namespace/the-project/[email protected]
    inputs:
      stage: my-stage
  - local: path/to/file.yml
    inputs:
      stage: my-stage

파이프라인에서 (For a pipeline)

inputs는 타입 검사, 검증, 명확한 계약을 포함해 변수보다 이점을 제공해요. 예상치 못한 inputs는 거부됩니다. 파이프라인용 inputs는 메인 .gitlab-ci.yml 파일의 spec:inputs 헤더에 정의해야 해요. 파이프라인 레벨 구성에는 include된 파일에 정의된 inputs를 쓸 수 없습니다.

[!NOTE] GitLab 17.7부터 파이프라인 변수를 전달하는 것보다 파이프라인 inputs가 권장됩니다. 보안을 강화하려면 inputs를 사용할 때 파이프라인 변수를 비활성화해야 해요.

파이프라인용 inputs를 정의할 때는 항상 기본값을 설정해야 해요. 어떤 입력에 기본값이 없으면 파이프라인이 자동으로 트리거될 때 실패합니다. 예를 들어 MR 파이프라인은 MR의 소스 브랜치 변경으로 트리거될 수 있어요. MR 파이프라인은 수동으로 inputs를 설정할 수 없으므로, 어느 입력이든 기본값이 없으면 파이프라인이 실패합니다. 브랜치 파이프라인, 태그 파이프라인, 기타 자동 트리거 파이프라인에서도 이렇게 될 수 있어요.

입력 값은 다음으로 설정할 수 있습니다.

파이프라인은 최대 20개의 inputs를 받을 수 있어요. 이 이슈에 대한 피드백을 환영합니다. 다운스트림 파이프라인의 구성 파일이 spec:inputs를 사용한다면 다운스트림 파이프라인에 inputs를 전달할 수 있어요. 예를 들어 trigger:inputs로:

trigger-job:
  trigger:
    strategy: mirror
    include:
      - local: path/to/child-pipeline.yml
        inputs:
          job-name: "defined"
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
trigger-job:
  trigger:
    strategy: mirror
    project: project-group/my-downstream-project
    inputs:
      job-name: "defined"
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
외부 파일에 파이프라인 inputs 정의 (Define pipeline inputs in external files)
  • ci_file_inputs라는 기능 플래그와 함께 GitLab 18.6에서 도입. 기본적으로 비활성화.
  • GitLab 18.9에서 일반 공개. 기능 플래그 ci_file_inputs 제거.

여러 CI/CD 구성에서 파이프라인 input 정의를 재사용하려면 외부 파일에 정의한 뒤 spec:include로 프로젝트의 파이프라인 구성에 포함하세요. shared-inputs.yml이라는 파일에 input 정의를 만들 수 있어요.

inputs:
  environment:
    description: "Deployment environment"
    options: ['staging', 'production']
  region:
    default: 'us-east-1'

그런 다음 local.gitlab-ci.yml에 외부 inputs를 포함할 수 있어요.

spec:
  include:
    - local: /shared-inputs.yml
---

deploy:
  script: echo "Deploying to $[[ inputs.environment ]] in $[[ inputs.region ]]"

파일이 프로젝트 외부에 저장되어 있다면 다음을 쓸 수 있습니다.

  • project: 다른 GitLab 프로젝트의 파일. 전체 프로젝트 경로를 사용하고 file로 파일 이름을 정의하세요. 선택적으로 ref를 정의해서 파일을 가져올 수도 있어요.
  • remote: 다른 서버의 파일. 파일의 전체 URL을 사용.

여러 input 파일을 동시에 include할 수도 있어요. 예를 들면 이렇습니다.

spec:
  include:
    - local: /shared-inputs.yml
    - project: 'my-group/shared-configs'
      ref: main
      file: '/ci/common-inputs.yml'
    - remote: 'https://example.com/ci/shared-inputs.yml'
---

[!NOTE] CI/CD component inputs에는 spec:include를 쓸 수 없어요.

다른 프로젝트의 구성에서 외부 input 파일 사용 (Use external input files in configuration from another project)
  • ci_spec_include_own_context라는 기능 플래그와 함께 GitLab 19.4에서 도입. 기본적으로 비활성화.

[!제목] 이 기능의 가용성은 기능 플래그가 제어합니다. 자세한 내용은 변경 내역(history)을 참고하세요.

구성 파일이 다른 프로젝트에서 include될 때 해당 파일의 spec:include 위치는 다른 프로젝트의 저장소와 ref에서 해석됩니다. 파이프라인을 실행하는 프로젝트는 이 해석에 영향을 주지 않아요. 예를 들어 my-group/pipelines 프로젝트의 templates/deploy.yml 파일은 외부 파일에 inputs를 정의합니다.

spec:
  include:
    - local: shared-inputs.yml
---

deploy:
  script: echo "Deploying to $[[ inputs.environment ]]"

다른 프로젝트가 그 파일을 자체 .gitlab-ci.yml 파일에 include합니다.

include:
  - project: 'my-group/pipelines'
    ref: main
    file: '/templates/deploy.yml'

이 예시에서 shared-inputs.yml은 파이프라인을 실행하는 프로젝트가 아니라 my-group/pipelines 프로젝트에서 읽혀요.

외부 파일의 inputs 오버라이드 (Override inputs from an external file)

입력 키는 모든 포함된 파일과 인라인 사양에서 고유해야 해요. 같은 입력 키가 여러 포함 파일에 나타나거나 포함 파일과 인라인 inputs: 섹션에 모두 나타나면 GitLab이 이 오류를 반환합니다.

Duplicate input keys found: environment. Input keys must be unique across all included files and inline specifications.

이 오류를 고치려면 각 입력 키가 포함 파일 또는 인라인 inputs: 섹션 중 하나에만 정의되도록 하세요.

입력 값을 다루는 함수 지정 (Specify functions to manipulate input values)

보간 블록에서 사전 정의 함수를 지정해서 입력 값을 가공할 수 있어요. 지원되는 형식은 이렇습니다.

$[[ input.input-id | <function1> | <function2> | ... <functionN> ]]

함수와 함께:

  • 사전 정의된 보간 함수만 허용됩니다.
  • 단일 보간 블록에 최대 3개의 함수를 지정할 수 있어요.
  • 함수는 지정된 순서대로 실행됩니다.
spec:
  inputs:
    test:
      default: 'test $MY_VAR'
---

test-job:
  script: echo $[[ inputs.test | expand_vars | truncate(5,8) ]]

이 예시에서 입력이 기본값을 사용하고 $MY_VAR가 값 my value를 가진 마스킹되지 않은 프로젝트 변수라고 가정하면:

  1. 먼저 expand_vars 함수가 값을 test my value로 확장.
  2. 그다음 truncatetest my value에 문자 오프셋 5, 길이 8로 적용.
  3. script의 출력은 echo my value.

사전 정의된 보간 함수 (Predefined interpolation functions)

expand_vars

입력 값에서 CI/CD 변수를 확장하려면 expand_vars를 쓰세요. include 키워드와 함께 쓸 수 있는 변수마스킹되지 않은 것만 확장할 수 있어요. 중첩 변수 확장은 지원되지 않습니다.

[!NOTE] 환경 스코프의 프로젝트·그룹 변수는 expand_vars에 사용할 수 없어요. input 보간은 job이 환경에 할당되기 전인 파이프라인 생성 중에 일어나기 때문입니다. expand_vars가 일치하는 변수를 찾지 못하면 $MY_VAR 같은 리터럴 문자열을 구성에 그대로 두는데, 셸이 런타임에 계속 확장할 수 있습니다. 같은 이름의 환경 스코프 변수와 비스코프 변수가 모두 존재하면 expand_vars는 비스코프 값을 사용해요.

예시:

spec:
  inputs:
    test:
      default: 'test $MY_VAR'
---

test-job:
  script: echo $[[ inputs.test | expand_vars ]]

이 예시에서 $MY_VAR가 값 my value로 마스킹되지 않았다면(job 로그에 노출) 입력은 test my value로 확장됩니다.

truncate

보간된 값을 줄이려면 truncate를 쓰세요. 예를 들면:

  • truncate(<offset>,<length>)
이름 타입 설명
offset Integer 오프셋할 문자 수.
length Integer 오프셋 뒤에 반환할 문자 수.

예시:

$[[ inputs.test | truncate(3,5) ]]

inputs.test의 값이 0123456789라고 가정하면 출력은 34567이 됩니다.

posix_escape

입력 값의 POSIX Bourne shell 제어·메타 문자를 이스케이프하려면 posix_escape를 쓰세요. posix_escape는 입력의 관련 문자 앞에 \를 삽입해서 문자를 이스케이프합니다.

예시:

spec:
  inputs:
    test:
      default: |
        A string with single ' and double " quotes and   blanks
---

test-job:
  script: printf '%s\n' $[[ inputs.test | posix_escape ]]

이 예시에서 posix_escape는 셸 제어 또는 메타 문자일 수 있는 문자를 이스케이프합니다.

$ printf '%s\n' A\ string\ with\ single\ \'\ and\ double\ \""\ quotes\ and\ \ \ blanks
A string with single ' and double " quotes and   blanks

이스케이프된 입력은 특수 문자와 공백을 제공된 대로 보존해요.

[!WARNING] 신뢰할 수 없는 입력 값에 보안 목적으로 posix_escape를 의존하지 마세요.

posix_escape는 입력 값을 정확히 보존하려고 최선을 다하지만, 일부 문자 조합은 여전히 원치 않는 결과를 일으킬 수 있어요. posix_escape를 써도 다음이 가능합니다.

  • 문자열에 포함된 셸 코드가 실행될 수 있음.
  • 단일·이중 따옴표가 주변 인용을 이스케이프하는 데 사용될 수 있음.
  • 변수 참조로 보호된 변수에 접근할 수 있음.
  • 입력·출력 리다이렉션으로 로컬 파일을 읽거나 쓸 수 있음.
  • 셸이 이스케이프되지 않은 공백으로 문자열을 여러 인자로 분리함.

보안을 위해 inputs가 신뢰할 수 있는지 확인해야 해요. 이렇게 할 수 있습니다.

posix_escapeexpand_vars와 결합한다면 expand_vars를 먼저 설정해야 해요. 그렇지 않으면 posix_escape가 변수의 $를 이스케이프해서 확장을 막아버립니다. 예를 들면 이렇습니다.

test-job:
  script: echo $[[ inputs.test | expand_vars | posix_escape ]]
split
  • ci_interpolation_split_function이라는 기능 플래그와 함께 GitLab 19.2에서 도입. 기본적으로 비활성화.
  • GitLab 19.2에서 일반 공개. 기능 플래그 ci_interpolation_split_function 제거.

구분 기호에서 문자열 입력을 부분 문자열 배열로 나누려면 split을 쓰세요. 예를 들면:

  • split('<separator>')
이름 타입 설명
separator String 분할할 문자 또는 문자열.

split은 각 요소의 앞뒤 공백을 제거하고 빈 요소를 제거해요. 예시:

spec:
  inputs:
    runner_tags:
      default: 'docker,linux'
---

deploy:
  tags: $[[ inputs.runner_tags | split(',') ]]
  script: echo "Deploying..."

이 예시에서 'docker,linux' 값을 가진 inputs.runner_tags['docker', 'linux']를 만들어 tags에 배열로 할당합니다.

트러블슈팅 (Troubleshooting)

rules에서 inputs를 쓸 때 YAML 문법 오류

rules:if 표현식을 수정하는 데 input을 쓰면 여러 문법 오류 중 하나를 볼 수 있어요. 이 오류들은 종종 CI/CD 변수 표현식에서 문자열이 처리되는 방식과 관련됩니다. rules:if의 표현식은 CI/CD 변수를 따옴표(' 또는 ")로 감싼 문자열이나 다른 변수와 비교하길 기대해요. 입력 값이 파이프라인 런타임에 rules 구성에 삽입되면 결과 값이 따옴표 문자열이나 변수가 아닐 수 있어요. 이 불일치가 오류를 일으킵니다.

예를 들어 include할 구성에서:

spec:
  inputs:
    branch:
      default: $CI_DEFAULT_BRANCH
    branch2:
      default: $CI_DEFAULT_BRANCH
---

job-name:
  rules:
    - if: $CI_COMMIT_REF_NAME == $[[ inputs.branch ]]
    - if: $CI_COMMIT_REF_NAME == $[[ inputs.branch2 ]]

그런 다음 메인 구성 파일에서:

include:
  inputs:
    branch: $CI_DEFAULT_BRANCH  # Valid
    branch2: main               # Invalid

이 예시에서:

  • branch: $CI_DEFAULT_BRANCH 사용은 유효해요. if: 절이 if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH로 평가되어 유효한 변수 표현식이 됩니다. 변수는 따옴표가 필요 없어요.
  • branch2: main 사용은 무효입니다. if: 절이 if: $CI_COMMIT_REF_NAME == main으로 평가되는데, main이 문자열인데 따옴표가 없어서 무효예요.

이 문제를 해결하려면 입력 값이 구성에 삽입된 뒤 표현식이 올바른 형식을 유지하도록 하세요. 이는 추가 따옴표 문자가 필요할 수 있어요. 예를 들어 문자열 값을 사용하는 규칙에 따옴표를 추가합니다.

rules:
  if: $CI_COMMIT_REF_NAME == "$[[ inputs.branch2 ]]"

expand_vars 같은 보간 함수에서는 전체 if: 표현식을 따옴표로 감쌀 필요도 있어요. 예를 들면 이렇습니다.

spec:
  inputs:
    environment:
      default: "$ENVIRONMENT"
---

$[[ inputs.environment | expand_vars ]] job:
  script: echo
  rules:
    - if: '"$[[ inputs.environment | expand_vars ]]" == "production"'

이 예시에서 input과 전체 if: 표현식을 모두 따옴표로 감싸면 input이 평가된 뒤에도 유효한 문법을 보장해요. 따옴표를 중첩할 때는 내부 따옴표에 "를, 외부 따옴표에 '를 사용하거나 그 반대로 하세요. job 이름은 따옴표가 필요 없습니다.

더 알아보기

inputs는 변수와 달리 타입·옵션·정규식·조건부 rules로 검증이 이뤄진다는 점이 핵심 차이예요. 재사용 템플릿·컴포넌트에서는 include:inputs로, 파이프라인에서는 spec:inputs 헤더와 trigger:inputs로 값을 전달합니다. 배열 타입 확장, expand_vars·truncate·split 같은 보간 함수를 익혀 두면 파이프라인을 훨씬 유연하게 만들 수 있어요.