This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed devops verify -

단계 정의

단계는 사용자가 제공할 수 있는 최소 실행 가능한 단위로, step.yml 파일에서 정의됩니다.

다음 단계 정의는 지원되는 최소 구문을 설명합니다. 이 구문은 구문 설탕과 함께 확장됩니다.

단계 정의는 두 문서로 구성됩니다. 문서 분할의 목적은 선언과 구현을 구분하는 것입니다.

  1. 사양 / 선언:

    단계 입력 및 출력을 설명하는 사양을 제공하며, 라이선스, 작성자 등 향후 단계에서 필요할 수 있는 기타 메타데이터를 포함합니다. 프로그래밍 언어 용어로는 인수와 반환 값을 갖는 함수 선언과 유사합니다.

  2. 구현:

    문서의 구현 부분은 단계를 실행하는 방법을 설명하며, 환경이 구성되는 방법 또는 동작이 구성되는 방법을 포함합니다.

표준 출력에 메시지를 출력하는 단계의 예

다음 단계 예제에서:

  1. 선언은 message라는 단일 입력을 허용함을 지정합니다. messagedefault:를 정의하지 않았기 때문에 실행 중에 제공해야 하는 필수 인수입니다.
  2. 구현 부분은 단계가 exec 유형임을 지정합니다. 실행되는 경우 단계는 message 값을 사용하여 echo 명령을 실행합니다.
# .gitlab/ci/steps/exec-echo.yaml
spec:
  inputs:
    message:
---
type: exec
exec:
  command: [echo, "${{inputs.message}}"]

단계 사양

단계 사양은 현재 입력 및 출력만 정의합니다.

  • 입력:
    • 필수이거나 선택적일 수 있습니다.
    • 이름이 있고 설명이 있을 수 있습니다.
    • 허용되는 옵션 디렉터리을 포함할 수 있습니다. 옵션은 입력에 제공될 수 있는 값을 제한합니다.
    • 일치하는 정규표현식을 정의할 수 있습니다. 일치하는 정규표현식은 입력에 제공될 수 있는 값을 제한합니다.
    • 구문 ${{ inputs.input_name }}을 사용하여 확장할 수 있습니다.
  • 모든 입력 값type: exec을 사용할 때 $STEP_JSON 파일을 디코딩하여 실행 컨텍스트에 대한 정보를 제공하는 파일을 해독함으로써 액세스할 수 있습니다.
  • 출력:
    • 이름이 있고 설명이 있을 수 있습니다.
    • 특별한 dotenv 파일에 쓰여야 합니다. 형식은 output_name=VALUE입니다.

예를 들어:

spec:
  inputs:
    message_with_default:
      default: "Hello World"
    message_that_is_required:
      description: "This description explains that the input is required, because it does not specify a default:"
    type_with_limited_options:
      options: [bash, powershell, detect]
    type_with_default_and_limited_options:
      default: bash
      options: [bash, powershell, detect]
      description: "Since the options are provided, the default: needs to be one of the options"
    version_with_matching_regexp:
      match: ^v\d+\.\d+$
      description: "The match pattern only allows values similar to `v1.2`"
  outputs:
    code_coverage:
      description: "Measured code coverage that was calculated as part of the step"
---
type: steps
steps:
  - step: ./bash-script.yaml
    inputs:
      script: "echo Code Coverage = 95.4% >> $OUTPUT_FILE"

단계 구현

단계 정의에는 다음 유형을 사용하여 단계를 실행할 수 있습니다:

  • type: exec: STDOUT/STDERR를 사용하여 이진 명령을 실행합니다.
  • type: steps: 단계의 시퀀스를 실행합니다.
  • type: parallel (계획됨): 모든 단계를 병렬로 실행하고 모두 완료될 때까지 기다립니다.
  • type: grpc (계획됨): 이진 명령을 실행하되 intra-process 통신에 gRPC를 사용합니다.
  • type: container (계획됨): 선택한 컨테이너 이미지에서 중첩된 단계 실행기를 실행하고 모든 실행 흐름을 전송합니다.

exec 단계 유형

이진 명령을 실행하는 기능 중 하나입니다:

  • 실행할 명령은 exec: 섹션으로 정의됩니다.
  • 실행의 결과는 실행될 명령의 종료 코드입니다. 기본 동작이 덮어써지지 않으면.
  • 명령이 실행되는 기본 작업 디렉터리는 단계가 위치한 디렉터리입니다.
  • 기본적으로 명령은 시간 제한이 없지만 작업 실행 중 timeout:로 시간 제한이 설정될 수 있습니다.

예를 들어, 입력이 없는 exec 단계:

spec:
---
type: exec
exec:
  command: [/bin/bash, ./my-script.sh]
  timeout: 30m
  workdir: /tmp

사용자 정의 명령을 실행하는 예제 단계

다음 예제는 사용자 제공 명령을 실행하는 최소 단계 정의입니다:

  • 선언 섹션은 script라는 단일 입력을 허용함을 지정합니다.
  • script 입력은 default:가 정의되지 않았기 때문에 실행 중에 제공되어야 하는 필수 인수입니다.
  • 구현 섹션은 단계가 exec 유형임을 지정합니다. 실행되는 경우 단계는 bash에서 user command-c 인수로 전달하여 실행됩니다.
  • 실행할 명령은 set -veo pipefail로 시작하여 실행 내용을 작업 로그에 출력하고 첫 번째 실패 시 종료합니다.
# .gitlab/ci/steps/exec-script.yaml

spec:
  inputs:
    script:
      description: '사용자 스크립트를 실행합니다.'
---
type: exec
exec:
  command: [/usr/bin/env, bash, -c, "set -veo pipefail; ${{inputs.script}}"]

steps 단계 유형

여러 단계를 순차적으로 실행하는 기능 중 하나입니다:

  • 단계 시퀀스는 단계 참조 배열로 정의됩니다: steps: [].
  • 다음 단계는 이전 단계가 성공한 경우에만 실행됩니다. 기본 동작이 덮어써지지 않으면.
  • 실행 결과는 다음 중 하나입니다:
    • 첫 번째 단계에서 실패할 경우 실패입니다.
    • 시퀀스의 모든 단계가 성공할 경우 성공입니다.

다른 단계를 사용하는 단계

steps 유형은 다른 단계를 사용할 수 있는 것에 매우 의존합니다. 시퀀스의 각 항목은 다른 외부 단계를 참조할 수 있습니다. 예를 들어:

spec:
---
type: steps
steps:
  - step: ./.gitlab/ci/steps/ruby/install.yml
    inputs:
      version: 3.1
    env:
      HTTP_TIMEOUT: 10s
  - step: gitlab.com/gitlab-org/components/bash/script@v1.0
    inputs:
      script: echo Hello World

step: 값은 단계 정의의 위치를 설명하는 문자열입니다:

  • 로컬: step: ./path/to/local/step.yml와 같이 로컬 소스에서 정의를 가져올 수 있습니다. 경로가 ./ 또는 ../로 시작하는 경우 로컬 참조가 사용됩니다. 해결된 경로는 항상 현재 단계의 위치를 기준으로 상대적입니다. 단계가 리포지터리의 위치에 상관없이 어디에 위치하든지 상관없습니다.
  • 원격: step: gitlab.com/gitlab-org/components/bash/script@v1.0과 같이 원격 소스에서도 정의를 가져올 수 있습니다. FQDN을 사용하면 Step Runner가 제공된 버전을 사용하여 단계를 포함하는 리포지터리 또는 아카이브를 가져옵니다.

inputs: 섹션은 키-값 쌍 디렉터리입니다. inputs:단계 사양에 대해 전달 및 일치하는 값을 지정합니다.

env: 섹션은 키-값 쌍 디렉터리입니다. env:type: exec 또는 type: steps을 포함하여 모든 하위 단계에 주어진 환경 변수를 노출시킵니다.

원격 단계

step: gitlab.com/gitlab-org/components/bash/script@v1.0을 사용하여 원격 단계를 실행하려면 단계 정의가 구조화된 방식으로 저장되어 있어야 합니다. 단계 정의:

  • steps/ 폴더에 저장되어야 합니다.
  • 하위 디렉터리에 중첩될 수 있습니다.
  • 단계 정의가 step.yml 파일에 저장된 경우 디렉터리 이름만으로 참조할 수 있습니다.

예를 들어, git clone https://gitlab.com/gitlab-org/components.git에 호스팅된 리포지터리의 파일 구조는 다음과 같습니다.

├── steps/
├── ├── secret_detection.yml
|   ├── sast/
│   |   └── step.yml
│   └── dast
│       ├── java.yml
│       └── ruby.yml

이 구조를 통해 다음과 같은 단계에 접근할 수 있습니다:

  • step: gitlab.com/gitlab-org/components/secret_detection@v1.0: steps/secret_detection.yml에 저장된 정의에서
  • step: gitlab.com/gitlab-org/components/sast@v1.0: steps/sast/step.yml에 저장된 정의에서
  • step: gitlab.com/gitlab-org/components/dast/java@v1.0: steps/dast/java.yml에 저장된 정의에서
  • step: gitlab.com/gitlab-org/components/dast/ruby@v1.0: steps/dast/ruby.yml에 저장된 정의에서

다른 단계를 실행하는 예제 단계

다음 예제는 현재 단계에 로컬로 저장된 다른 단계를 실행하는 최소한의 단계 정의입니다.

  • 선언은 두 개의 입력을 기본값과 함께 허용한다고 지정합니다.
  • 구현 섹션은 단계가 steps 유형임을 지정하며, 나열된 단계를 순서대로 실행합니다. 최상위 env:의 사용으로 HTTP_TIMEOUT 변수가 모든 실행된 단계에서 사용 가능합니다.
spec:
  inputs:
    ruby_version:
      default: 3.1
    http_timeout:
      default: 10s
---
type: steps
env:
  HTTP_TIMEOUT: ${{inputs.http_timeout}}
steps:
  - step: ./.gitlab/ci/steps/exec-echo.yaml
    inputs:
      message: "Ruby ${{inputs.ruby_version}} 설치 중..."
  - step: ./.gitlab/ci/ruby/install.yaml
    inputs:
      version: ${{inputs.ruby_version}}

컨텍스트 및 보간

모든 단계 정의는 단계 정의에서 사용될 수 있는 다음 정보를 저장하는 컨텍스트 객체에서 실행됩니다.

  • inputs: 사용자 제공 또는 기본값을 포함하는 입력 디렉터리
  • outputs: 예상 출력 디렉터리
  • env: 현재 환경 변수 값
  • job: 실행 중인 현재 작업에 대한 메타데이터
    • job.project: 프로젝트에 관한 정보, 예를 들어 ID, 이름 또는 전체 경로
    • job.variables: CI/CD 실행에서 제공된 모든 CI/CD 변수, 프로젝트 변수, 미리 정의된 변수 등
    • job.pipeline: 실행 중인 현재 파이프라인에 관한 정보, ID, 이름, 전체 경로 등
  • step: 실행 중인 현재 단계에 관한 정보, 단계의 위치, 사용된 버전 또는 사양
  • steps (type: exec의 경우): 실행될 시퀀스의 각 단계에 관한 정보, 단계 실행의 결과, 성공 또는 추적 로그와 같은 단계의 상태
    • steps.<name-of-the-step>.status: 단계의 상태, 성공 또는 실패와 같은

컨텍스트 객체는 ${{ <value> }} 형식으로 보간의 지원을 가능하게 합니다.

보간:

  • 단계 사양 섹션에서 금지됩니다. 사양은 런타임 환경에 영향을 받아서는 안 되는 정적 구성입니다.
  • 단계 구현 섹션에서 사용될 수 있습니다. 구현은 단계의 실행 방법에 대한 런타임 지침 집합을 설명합니다.
  • 각 데이터 구조의 해시 값에 대해 적용됩니다.
  • 의 보간만 가능합니다 (현재로서는). 의 보간은 금지됩니다.
  • 설정이 로드될 때 한 번 실행되는 것이 아니라, 실행 및 제어를 전달하면서 주어진 단계에 대해 수행됩니다. 이를 통해 출력을 입력으로 연결하거나 단계를 이전 단계의 실행에 의존하게 만들 수 있습니다.

예를 들어:

# .gitlab/ci/steps/exec-echo.yaml
spec:
  inputs:
    timeout:
      default: 10s
    bash_support_version:
---
type: steps
env:
  HTTP_TIMEOUT: ${{inputs.timeout}}
  PROJECT_ID: ${{job.project.id}}
steps:
  - step: ./my/local/step/to/echo.yml
    inputs:
      message: "현재 프로젝트 빌드 중: ${{job.project.full_path}}"
  - step: gitlab.com/gitlab-org/components/bash/script@v${{inputs.bash_support_version}}

YAML 문서를 설명하는 참조 데이터 구조

package main

type StepEnvironment map[string]string

type StepSpecInput struct {
    Default     *string   `yaml:"default"`
    Description string    `yaml:"description"`
    Options     *[]string `yaml:"options"`
    Match       *string   `yaml:"match"`
}

type StepSpecOutput struct {
}

type StepSpecInputs map[string]StepSpecInput
type StepSpecOutputs map[string]StepSpecOutput

type StepSpec struct {
    Inputs  StepSpecInput   `yaml:"inputs"`
    Outputs StepSpecOutputs `yaml:"outputs"`
}

type StepSpecDoc struct {
    Spec StepSpec `yaml:"spec"`
}

type StepType string

const StepTypeExec StepType = "exec"
const StepTypeSteps StepType = "steps"

type StepDefinition struct {
    Def   StepSpecDoc             `yaml:"-"`
    Env   StepEnvironment         `yaml:"env"`
    Steps *StepDefinitionSequence `yaml:"steps"`
    Exec  *StepDefinitionExec     `yaml:"exec"`
}

type StepDefinitionExec struct {
    Command    []string       `yaml:"command"`
    WorkingDir *string        `yaml:"working_dir"`
    Timeout    *time.Duration `yaml:"timeout"`
}

type StepDefinitionSequence []StepReference

type StepReferenceInputs map[string]string

type StepReference struct {
    Step   string              `yaml:"step"`
    Inputs StepReferenceInputs `yaml:"inputs"`
    Env    StepEnvironment     `yaml:"env"`
}