Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | devops verify | - |
단계 정의
단계는 사용자가 제공하고 step.yml
파일에 정의된 최소 실행 가능 단위입니다.
다음 단계 정의는 지원되는 구문의 최소한을 설명합니다. 구문은 구문 설탕으로 확장됩니다.
단계 정의에는 두 개의 문서로 구성됩니다. 문서 분할의 목적은 선언과 구현을 구분하는 데 있습니다.
-
단계 입력 및 출력 등 단계에 필요한 미래에 필요한 다른 메타데이터(라이센스, 작성자 등)를 설명하는 스펙을 제공합니다. 프로그래밍 언어 용어로는 이는 인수와 반환 값을 가진 함수 선언과 유사합니다.
-
구현:
문서의 구현 부분은 단계의 실행 방법을 설명하며 환경이 어떻게 구성되어야 하는지 또는 조치가 어떻게 구성되어야 하는지 등을 설명합니다.
표준 출력에 메시지를 출력하는 예제 단계
다음 단계 예제에서:
- 선언은
message
라는 단일 입력을 허용한다고 명시합니다.message
는default:
를 정의하지 않았기 때문에 단계를 실행할 때 제공해야 하는 필수 인수입니다. - 구현 섹션은 단계가
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
형식의 특수한 파일의 이름으로$OUTPUT_FILE
을 사용합니다.
예를 들어:
spec:
inputs:
message_with_default:
default: "Hello World"
message_that_is_required:
description: "이 설명은 default를 지정하지 않았기 때문에 입력이 필수임을 설명합니다."
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
유형임을 지정합니다. 실행될 때, 단계는 사용자 명령을-c
인수로 전달하여bash
에서 실행될 것입니다. - 실행될 명령은 일찍이 실패하여 작업 로그에 출력되고 첫 번째 실패 시 종료되도록
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: 10초
- 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: 10초
---
type: steps
env:
HTTP_TIMEOUT: ${{inputs.http_timeout}}
steps:
- step: ./.gitlab/ci/steps/exec-echo.yaml
inputs:
message: "Installing 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
: 단계의 상태. 성공 또는 실패와 같은. -
steps.<name-of-the-step>.outputs.<output-name>
: 단계가 제공한 출력을 가져오기 위해 사용
-
컨텍스트 개체는 ${{ <value> }}
형식의 보간을 지원하기 위해 사용됩니다.
보간:
- 단계 명세 섹션에서 금지됩니다. 명세는 런타임 환경에 영향을 받지 않아야 하는 정적 구성입니다.
- 단계 구현 섹션에서 사용할 수 있습니다. 구현은 단계의 런타임 실행 지침 세트를 설명합니다.
- 해시의 각 데이터 구조의 값 부분에 적용됩니다.
- 키의 보간은 현재 금지됩니다.
- 구성이 로드될 때가 아닌 주어진 단계에 실행되고 제어가 전달될 때 실행됩니다. 이는 출력을 입력으로 연결하거나 단계를 이전 단계의 실행에 의존하게 만드는 등의 작업이 가능하게 합니다.
예를 들어:
# .gitlab/ci/steps/exec-echo.yaml
spec:
inputs:
timeout:
default: 10초
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: "I'm currently building a project: ${{job.project.full_path}}"
- step: gitlab.com/gitlab-org/components/bash/script@v${{inputs.bash_support_version}}
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"`
}