CI/CD 단계

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-Managed형, GitLab Dedicated Status: Experimental

단계는 작업의 재사용 가능하며 구성 가능한 부분입니다. 각 단계는 다른 단계에서 사용될 수 있는 구조화된 입력 및 출력을 정의합니다. 단계는 로컬 파일, GitLab.com 리포지터리 또는 기타 Git 소스에서 가져올 수 있습니다.

단계를 발행하는 CI 카탈로그 지원이 이슈 425891에서 제안되었습니다.

단계 정의

단계는 step.yml 파일에 정의됩니다. 각 파일에는 명세와 정의 두 가지 문서가 있습니다.

명세는 입력, 출력, 유형, 설명 및 기본값을 제공합니다.

# 명세 예시
spec:
  inputs:
    name:
      type: string
      default: joe steppy

정의는 단계의 구현을 제공합니다. 단계 정의에는 두 가지 유형이 있습니다.

  • exec 유형: 명령을 실행합니다.

     # 정의 예시
     exec:
     command: [ docker, run, -it, ubuntu, uname, -a ]
    
  • steps 유형: 다른 단계의 시퀀스를 실행합니다.

     # 정의 예시
     steps:
       - name: greet_user
         step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
         inputs:
           echo: hello ${{ inputs.name }}
       - name: print_system_information
         step: ./my-local-steps/uname
    

단계 구현을 리팩토링할 수 있도록 단계를 exec에서 steps 유형으로, 또는 steps에서 exec 유형으로 변경할 수 있습니다. 이는 Workflows(또는 단계 호출)에 영향을 미치지 않습니다.

입력

입력은 다음과 같은 유형일 수 있습니다.

  • string
  • number
  • boolean
  • array
  • struct

기본 입력 유형은 string입니다.

입력에 기본값이 정의되어 있지 않으면 필수입니다. 기본값은 단계 정의에서만 허용되는 표현식(${{ }})을 사용할 수 없습니다.

출력

출력은 다음과 같은 유형일 수 있습니다.

  • string
  • number
  • boolean
  • array
  • struct
  • raw_string
  • step_result

출력은 key=value 형식으로 ${{ output_file }}에 작성되며, 여기서 key는 출력의 이름입니다. value는 형식이 raw_string이 아닌 경우 JSON으로 작성되어야 합니다.

단계에 의해 작성된 값의 유형은 선언된 유형과 일치해야 합니다. 기본 출력 유형은 raw_string입니다.

특수한 출력 유형인 step_result는 다른 단계에게 단계 실행을 위임할 때 사용됩니다. 예를 들어, scriptaction-runner 단계에서 사용됩니다.

steps 유형 정의의 출력은 하위 단계에서 집계하기 위해 표현식을 사용합니다. 명세에 표현식을 사용할 수 없기 때문에 정의outputs 키워드가 나타납니다. 캡슐화를 유지하고 리팩토링을 허용하기 위해 호출자는 하위 단계의 출력에 직접 액세스할 수 없습니다.

# 여러 단계로부터의 출력 예시
spec:
  outputs:
    full_name:
      type: string
---
steps:
  - name: first_name
    step: ./fn
  - name: last_name
    step: ./ln
outputs:
  full_name: "hello ${{ steps.first_name.outputs.name }} ${{ steps.last_name.outputs.name }}"

단계 사용

키워드 step은 원격 또는 로컬 단계를 가리킵니다.

원격 단계 참조는 Git 리포지터리의 URL, 문자 @ 및 태그 또는 브랜치(버전)입니다. 단계 러너는 리포지터리 루트에 step.yml 파일을 찾습니다.

로컬 단계는 .으로 시작하고 단계 러너가 step.yml을 찾을 디렉터리를 가리킵니다. 로컬 참조는 운영 체제에 관계없이 항상 경로 구분자 /를 사용합니다. 파일을 로드할 때는 해당 OS에 맞는 분리가 사용됩니다.

# 단계를 사용하는 작업 예시
my-job:
  run:
    - name: greet_user
      step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
      inputs:
        echo: hello $[[ GITLAB_USER_LOGIN ]]
    - name: print_system_information
      step: ./my-local-steps/uname

작업에서 단계를 사용하려면 변수에 단계를 제공하고 작업의 script 키워드에서 단계 러너를 호출합니다. GitLab CI 파이프라인 구성에서 run 키워드로 단계를 사용하는 지원이 에픽 11525에서 제안되었습니다.

# run 키워드가 구현될 때까지의 예시 작업
my-job:
  image: registry.gitlab.com/gitlab-org/step-runner:v0
  variables:
    STEPS: |
      - name: greet_user
        step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
        inputs:
          echo: hello $GITLAB_USER_LOGIN
      - name: print_system_information
        step: ./my-local-steps/uname
  script:
    - /step-runner ci  # STEPS 환경 변수에서 준비된 단계 러너의 ci 명령을 실행합니다

환경 변수 설정

환경 변수를 단계에 대해 선언할 필요가 없습니다. ${{ export_file }}에 기록된 모든 내보내기는 전역 실행 환경에 추가됩니다. 내보낸 값은 일반 문자열(불이 아님)입니다.

env 키워드를 사용하여 단계에서 임시로 환경 변수를 설정할 수 있습니다.

# env를 사용한 예시 작업
my-job:
  run:
    - name: greet_user
      step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
      env:
        USER: $[[ GITLAB_USER_LOGIN ]]
      inputs:
        echo: hello ${{ env.USER }}

단계 정의는 임시로 환경 변수를 설정할 수도 있습니다.

# env를 사용한 예시 단계 정의
env:
  USER: ${{ inputs.user }}
steps:
  - name: greet_user
    step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
    inputs:
      echo: hello ${{ env.USER }}    

환경 변수 우선 순위는 다음과 같습니다.

  1. 단계 정의
  2. 단계 참조 (단계 호출)
  3. 전역 환경

단계 정의에서 설정한 env 변수는 단계 호출할 때 설정한 변수 및 기타 변수를 재정의합니다.

로컬에서 단계 실행

로컬에서 단계를 실행하려면 step-runner 다운로드ci 명령을 실행합니다. 이는 프로덕션에서 단계를 실행하는 데 사용되는 동일한 이진 파일입니다.

STEPS=$(yq '."my-job"'.run .gitlab-ci.yml) step-runner ci

delve로 디버깅할 수 있습니다. pkg/runner.goRun에 중단점 설정할 수 있습니다.

STEPS=$(yq '."my-job"'.run .gitlab-ci.yml) dlv debug . ci

스크립트

단계는 작업을 실행하기 위한 셸 스크립트의 대안입니다. 더 구조화되어 있으며 결합, 테스트 및 재사용이 가능합니다. exec:command는 셸을 실행하는 것이 아니라 Exec 시스템 호출을 사용하여 실행됩니다.

그러나 때로는 셸 스크립트가 필요합니다. script 키워드는 올바른 셸을 자동으로 선택하고 스크립트를 실행합니다.

# script를 사용한 예시 작업
my-job:
  run:
    - name: greet_user
      script: echo hello $[[ GITLAB_USER_LOGIN ]]
note
bash 셸만 지원됩니다. 조건 표현 지원이 에픽 12168에서 제안되었습니다.

작업

action 키워드로 GitHub actions를 실행할 수 있습니다. 입력과 출력은 단계와 마찬가지로 동일하게 작동합니다. 단계와 액션은 서로 교차하여 사용할 수 있습니다.

# Action을 사용하는 작업 예시
my-job:
  run:
    - name: greet_user
      step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
      inputs:
        echo: hello $[[ GITLAB_USER_LOGIN ]]
    - name: greet_user_again
      action: mikefarah/yq@master
      inputs:
        cmd: echo ["${{ steps.greet_user.outputs.echo }} again!"] | yq .[0]

알려진 문제

GitLab에서 실행되는 actions은 직접 아티팩트를 업로드하는 것을 지원하지 않습니다. 아티팩트는 파일 시스템 및 캐시에 작성하고 기존의 artifacts 키워드로 선택해야 합니다.

액션을 실행하려면 dind 서비스가 필요합니다. 더 자세한 정보는 도커를 사용하여 도커 이미지 빌드를 참조하세요.

GitLab의 actions은 실험적이며 버그가 있을 수 있습니다. 버그를 보고하려면 action-runner repo에서 이슈를 작성하세요.

표현식

표현식은 이중 중괄호(${{ }})로 둘러싸인 미니 언어입니다. inputs, env (단계에서 공유하는 환경) 및 이전 단계의 출력(steps.<step_name>.outputs)을 참조할 수 있습니다.

표현식은 빌드 디렉터리인 work_dir을 참조할 수 있습니다. 또한 캐시된 단계 정의와 관련 파일이 있는 step_dir을 참조할 수 있습니다. 또한, 출력 및 익스포트가 작성되는 output_fileexport_file을 참조할 수 있습니다.

표현식은 작업 생성 중에 평가되는 템플릿 보간과는 다릅니다. 표현식은 작업 환경에서 단계 실행 직전에 평가됩니다.