Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | devops verify | - |
디자인 및 구현 세부정보
Baseline Step Proto
Step Runner 내부는 Protocol Buffer로 정의된 기준 단계 정의에서 작동합니다. 모든 GitLab CI 단계(및 GitHub Actions과 같은 지원되는 형식)는 기준 단계로 컴파일/폴딩됩니다. .gitlab-ci.yml
의 단계 호출 및 step.yml
파일의 단계 정의 모두 기준 구조로 컴파일됩니다. 이 문서의 나머지 부분에서 “단계”라는 용어는 “기준 단계”를 의미합니다.
각 단계에는 URI 형태의 참조 ref
가 포함됩니다. 검색 방법은 URI의 프로토콜에 따라 결정됩니다.
단계 및 단계 추적은 입력, 출력, 환경 변수, 환경 내보내기 필드를 가지고 있습니다. 단계가 다운로드되고 step.yml
이 구문 분석된 후에는 단계 정의 def
가 추가됩니다. 단계가 여러 추가 단계를 정의하는 경우 추적에는 각 하위 단계에 대한 하위 추적이 포함됩니다.
message Step {
string name = 1;
string step = 2;
map<string,string> env = 3;
map<string,google.protobuf.Value> inputs = 4;
}
message Definition {
DefinitionType type = 1;
Exec exec = 2;
repeated Step steps = 3;
message Exec {
repeated string command = 1;
string work_dir = 2;
}
}
enum DefinitionType {
definition_type_unspecified = 0;
exec = 1;
steps = 2;
}
message Spec {
Content spec = 1;
message Content {
map<string,Input> inputs = 1;
message Input {
InputType type = 1;
google.protobuf.Value default = 2;
}
}
}
enum InputType {
spec_type_unspecified = 0;
string = 1;
number = 2;
bool = 3;
struct = 4;
list = 5;
}
message StepResult {
Step step = 1;
Spec spec = 2;
Definition def = 3;
enum Status {
unspecified = 0;
running = 1;
success = 2;
failure = 3;
}
Status status = 4;
map<string,Output> outputs = 5;
message Output {
string key = 1;
string value = 2;
bool masked = 3;
}
map<string,string> exports = 6;
int32 exit_code = 7;
repeated StepResult children_step_results = 8;
}
단계 캐싱
단계는 location
(URL), version
및 hash
로 구성된 키에 의해 로컬로 캐시됩니다. 이를 통해 정확히 동일한 구성 요소가 여러 번 다운로드되는 것을 방지합니다. 단계를 처음 참조할 때 다운로드되고 (로컬이 아닌 경우) 캐시는 step.yml
을 포함하고 다른 단계 파일이 있는 폴더의 경로를 반환합니다. 동일한 단계가 다시 참조되면 동일한 폴더가 다운로드 없이 반환됩니다.
버전 또는 해시별로 다른 캐시된 단계와 다른 차이가 있는 단계를 참조하면 다른 폴더로 재다운로드되고 별도로 캐시됩니다.
실행 컨텍스트
단계 실행기는 실행 컨텍스트 형식으로 모든 단계에서 상태를 유지합니다. 컨텍스트에는 각 단계의 출력, 환경 변수 및 전체 작업 및 환경 메타데이터가 포함됩니다. 실행 컨텍스트는 워크플로우 작성자가 제공한 GitLab CI 단계에서 표현식에 의해 참조될 수 있습니다.
.gitlab-ci.yml
의 표현식에서 사용 가능한 컨텍스트 예시:
steps:
previous_step:
outputs:
name: "hello world"
env:
EXAMPLE_VAR: "bar"
job:
id: 1234
단계 정의의 표현식에서도 실행 컨텍스트를 참조할 수 있습니다. 그러나 전체 작업 및 환경 메타데이터 및 step.yml
에서 정의된 입력에만 액세스할 수 있습니다. 이전 단계의 출력에 액세스할 수 없습니다. 한 단계의 출력을 다음으로 제공하기 위해 단계 입력 값에는 다른 단계의 출력을 참조하는 표현식이 포함되어야 합니다.
step.yml
의 표현식에서 사용 가능한 컨텍스트 예시:
inputs:
name: "foo"
env:
EXAMPLE_VAR: "bar"
job:
id: 1234
예를 들어, 이는 step.yml
파일에서 허용되지 않습니다. 왜냐하면 단계가 서로 결합해서는 안 되기 때문입니다.
spec:
inputs:
name:
---
type: exec
exec:
command: [echo, hello, ${{ steps.previous_step.outputs.name }}]
이는 허용됩니다. 왜냐하면 GitLab CI 단계 구문이 한 단계에서 다른 단계로 데이터를 전달하기 때문입니다:
spec:
inputs:
name:
---
type: exec
exec:
command: [echo, hello, ${{ inputs.name }}]
steps:
- name: previous_step
...
- name: greeting
inputs:
name: ${{ steps.previous_step.outputs.name }}
따라서 표현식의 평가는 GitLab CI 단계 및 단계 정의의 두 가지 다른 컨텍스트에서 수행됩니다.
단계 입력
단계 입력은 여러 가지 방법으로 제공될 수 있습니다. 이를 수행하는 exec
명령문 내에 직접 포함될 수 있습니다(위 참조). 또는 단계 수행 중에 환경 변수에 대한 표현식으로 포함될 수도 있습니다:
spec:
inputs:
name:
---
type: exec
exec:
command: [greeting.sh]
env:
NAME: ${{ inputs.name }}
입력 유형
입력 값은 문자열로 저장됩니다. 그러나 해당 값에 유형을 연결할 수도 있습니다. 지원되는 유형은 다음과 같습니다:
string
bool
number
object
문자열 유형 값은 어떤 문자열이든 될 수 있습니다. Bool 유형 값은 JSON으로 구문 분석될 때 true
또는 false
이어야 합니다. 숫자 유형 값은 JSON으로 구문 분석될 때 유효한 float64이어야 합니다. 객체 유형은 YAML 입력 구조의 JSON 직렬화가 될 것입니다.
예를 들어, 다음은 유효한 입력입니다:
steps:
- name: my_step
inputs:
foo: bar
baz: true
bam: 1
다음과 같은 단계 정의가 주어졌을 때:
spec:
inputs:
foo:
type: string
baz:
type: bool
bam:
type: number
---
type: exec
exec:
command: [echo, ${{ inputs.foo }}, ${{ inputs.baz }}, ${{ inputs.bam }}]
출력은 bar true 1
이 될 것입니다.
객체 유형의 경우, 다음은 유효한 입력입니다:
steps:
name: my_step
inputs:
foo:
steps:
- name: my_inner_step
inputs:
name: steppy
다음과 같은 단계 정의가 주어졌을 때:
spec:
inputs:
foo:
type: object
---
type: exec
exec:
command: [echo, ${{ inputs.foo }}]
그리고 출력은 {"steps":[{"name":"my_inner_step","inputs":{"name":"steppy"}}]}
이 될 것입니다.
출력
출력 파일은 단계가 자신의 출력 및 환경 변수 내보내기를 작성할 수 있는 파일로 생성됩니다. 파일 위치는 OUTPUT_FILE
및 ENV_FILE
환경 변수에서 제공됩니다.
단계 실행 후, Step Runner는 출력과 환경 변수 파일을 읽고 해당 값으로 추적을 채웁니다. 출력은 실행된 단계의 컨텍스트에 저장될 것이고, 내보낸 환경 변수는 다음 단계에 제공된 환경과 병합될 것입니다.
특정 단계는 steps
유형일 수 있으며, 일련의 GitLab CI 단계로 구성될 수 있습니다. 이들은 순차적으로 컴파일되고 실행됩니다. 중첩된 단계에서 내보낸 환경 변수는 후속 단계에서 사용할 수 있으며, 중첩된 단계가 완료되면 고수준 단계에서도 사용할 수 있을 것입니다. 즉, 중첩된 단계에 진입하는 것은 새로운 “범위” 또는 컨텍스트 객체를 생성하지 않습니다. 환경 변수는 전역적입니다.
컨테이너
단계를 컨테이너에서 실행하는 몇 가지 접근 방법을 시도해보았습니다. 결과적으로 단계를 완전히 컨테이너 내의 단계 실행기에 위임하기로 결정했습니다.
다음은 고려된 옵션입니다:
위임 (선택된 옵션)
단계에 복잡한 구조를 전달할 수 있는 규정이 마련되어 있으며, 이는 이러한 구조를 JSON으로 직렬화하는 것입니다(위의 입력 참조). 이러한 방식으로 실제 실행할 단계는 컨테이너 내에서 단순히 단계 수행에 대한 매개변수일 수 있습니다. 따라서 외부 단계는 docker/run
단계이며, 이 단계의 명령은 단계를 수행하는 step-runner
를 입력 매개변수로 실행하는 것입니다. docker/run
단계는 컨테이너를 실행하고, 그런 다음 출력 파일을 컨테이너에서 추출하여 다시 외부 단계에 재전송할 것입니다.
동일한 기술은 VM에서 단계를 실행하는 데도 작동합니다. Step Runner는 컨테이너화나 단계 격리에 대해 아무것도 알 필요가 없습니다.
특별한 컴파일 (거부된 옵션)
GitLab CI 단계에서 image
키워드를 볼 때 “대상” 단계를 다운로드하고 컴파일하는 것입니다. 그런 다음 컴파일된 exec
명령을 입력으로 사용하여 docker/run
단계를 생성합니다. 그런 다음 docker/run
단계를 컴파일하고 실행할 것입니다.
그러나 이렇게 하려면 Step Runner가 docker/run
단계를 구성하는 방법을 알아야 합니다. 이는 Step Runner를 격리 방법과 결합하여, VM 및 기타 방법에서의 격리를 복잡하게 만듭니다.
네이티브 도커 (거부된 옵션)
기본 단계에는 도커 컨테이너에서 단계를 실행할 수 있는 규정이 포함될 수 있습니다. 예를 들어, 해당 단계에 ref
“대상” 필드 및 image
필드가 포함될 수 있습니다.
그러나 이는 또한 Step Runner를 도커와 결합시키고 Step Runner의 역할을 확대시킵니다. 도커를 Step Runner가 아닌 일반적인 단계로 만드는 것이 바람직합니다.