Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | devops verify | - |
단계 정의
단계는 사용자가 제공할 수 있는 최소 실행 단위로, step.yml
파일에 정의됩니다.
다음 단계 정의는 지원되는 최소 구문을 설명합니다. 구문은 구문적 설탕과 함께 확장됩니다.
단계 정의는 두 문서로 구성됩니다. 문서 분할의 목적은 선언과 구현을 구분하는 것입니다.
-
단계 입력 및 출력을 설명하는 사양을 제공하며, 미래에 단계에 필요한 라이선스, 저자 등의 기타 메타데이터를 확인할 수 있습니다. 프로그래밍 언어 용어로는 매개변수 및 반환 값이 있는 함수 선언과 유사합니다.
-
구현:
문서의 구현 부분은 단계를 실행하는 방법을 설명하며, 환경이 어떻게 구성되어야 하는지 또는 동작을 어떻게 구성할 수 있는지를 포함합니다.
stdout에 메시지를 출력하는 예시 단계
다음 단계 예시에서:
- 선언은
message
라는 단일 입력을 허용하도록 지정합니다.message
는default:
가 정의되지 않았기 때문에 단계를 실행할 때 제공해야 하는 필수 인수입니다. - 구현 섹션은 단계가
exec
유형임을 지정합니다. 실행될 때 단계는메시지
값과 함께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_FILE
이고 형식은output_name=VALUE
입니다.
예:
spec:
inputs:
message_with_default:
default: "Hello World"
message_that_is_required:
description: "이 설명은 입력이 필수임을 설명합니다. 왜냐하면 기본값이 지정되지 않았기 때문입니다."
type_with_limited_options:
options: [bash, powershell, detect]
type_with_default_and_limited_options:
default: bash
options: [bash, powershell, detect]
description: "옵션이 제공되었기 때문에 default:는 옵션 중 하나여야 합니다."
version_with_matching_regexp:
match: ^v\d+\.\d+$
description: "일치 패턴은 `v1.2`와 같은 값만 허용합니다."
outputs:
code_coverage:
description: "단계의 일환으로 계산된 메트릭된 코드 커버리지"
---
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
(계획 중): 이진 명령을 실행하지만 프로세스 내 통신에 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
에서-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:
값은 단계 정의가 위치한 곳을 설명하는 문자열입니다:
-
로컬: 경로가
./
또는../
로 시작할 때 로컬 소스에서 정의를 검색할 수 있습니다. 경로가 다른 로컬 단계의 위치에 상대적이므로 제한이 없습니다. -
원격: FQDN을 사용하여 원격 소스에서 정의를 검색할 수 있습니다.
@
뒤의 버전을 사용하여 단계를 포함하는 리포지터리 또는 아카이브를 가져옵니다.
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: "루비 ${{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.<단계이름>.status
: 단계의 상태, 예를 들어success
또는failed
등입니다. -
steps.<단계이름>.outputs.<출력이름>
: 단계가 제공한 출력을 가져오기 위해 사용됩니다.
-
컨텍스트 객체는 ${{ <값> }}
형식의 내삽 지원을 가능하게 합니다.
내삽:
- 단계 명세 섹션에서는 금지됩니다. 명세는 런타임 환경에 영향을 받지 않아야 하는 정적 구성입니다.
- 단계 구현 섹션에서 사용할 수 있습니다. 구현은 단계를 실행하는 데 필요한 실행 시점 지시의 집합을 설명합니다.
- 각 데이터 구조의 해시의 각 값을 대상으로 합니다.
- 값의 내삽은 가능합니다 (현재로서). 키의 내삽은 금지됩니다.
- 구성을 로드할 때 한 번이 아닌 실행 및 특정 단계로 제어를 전달할 때 이루어집니다. 이는 출력을 입력에 연결하거나 단계를 선행 단계의 실행에 의존시키도록 합니다.
예를 들어:
# .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"`
}