Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | devops verify | - |
디자인 및 구현 세부 정보
기준 단계 프로토
스텝 러너의 내부는 프로토콜 버퍼에 정의된 기준 단계 정의를 기반으로 작동합니다. 모든 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
명령의 식에 직접 임베드될 수 있습니다(위에서와 같이). 또는 exec
중에 설정된 환경 변수의 식에 임베드될 수 있습니다:
spec:
inputs:
name:
---
type: exec
exec:
command: [greeting.sh]
env:
NAME: ${{ inputs.name }}
입력 유형
입력 값은 문자열로 저장됩니다. 그러나 해당 유형이 연결될 수도 있습니다. 지원되는 유형은 다음과 같습니다:
string
bool
number
object
문자열 유형 값은 모든 문자열이 될 수 있습니다. Bool 유형 값은 JSON으로 구문 분석될 때 true
또는 false
여야 합니다. 숫자 유형 값은 JSON으로 구문 분석될 때 유효한 float64여야 합니다. Object 유형은 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는 출력 및 환경 변수 파일을 읽고 해당 값으로 추적을 채웁니다. 출력물은 실행된 단계의 컨텍스트에 저장될 것입니다. 내보낸 환경 변수는 다음 단계에서 제공된 환경과 Merge될 것입니다.
일부 단계는 steps
유형이며 GitLab CI 단계의 일련의 순서로 구성될 수 있습니다. 이러한 단계는 순차적으로 컴파일되어 실행됩니다. 중첨된 단계에서 내보낸 환경 변수는 후속 단계에서 사용할 수 있으며 중첩된 단계가 완료된 후 고수준 단계에서도 사용할 수 있습니다. 예를 들어 중첨된 단계로 진입하더라도 “범위”나 컨텍스트 개체를 새로 생성하지 않습니다. 환경 변수는 글로벌입니다.
컨테이너
단계를 컨테이너에서 실행하는 몇 가지 방법을 시도해보았습니다. 결과적으로 우리는 단계를 완전히 컨테이너 내 단계 실행기에 위임하기로 결정했습니다.
고려된 옵션은 다음과 같습니다:
위임 (선택된 옵션)
단계에 복잡한 구조를 전달하는 조치가 취해졌는데, 이는 그것들을 JSON으로 직렬화하는 것입니다(위의 입력 참조). 이 방법으로 단순히 컨테이너 내에서 실행될 실제 단계는 단계 실행기에게 매개변수로 전달될 수 있습니다. 따라서 외부 단계는 docker/run
단계로, step-runner
와 steps
입력 매개변수를 실행하는 명령을 실행하는 단계입니다. docker/run
단계는 컨테이너를 실행한 다음 출력 파일을 컨테이너에서 추출하여 외부 단계로 재전송합니다.
이 같은 기술은 VM에서 단계를 실행하는 데에도 동일하게 작동합니다. 단계 실행기는 컨테이너화하거나 단계를 격리시키는 방법에 대해 알 필요가 없습니다.
특수 컴파일 (거부된 옵션)
GitLab CI 단계에서 image
키워드를 볼 때 “target” 단계를 다운로드하고 컴파일할 것입니다. 그런 다음 컴파일된 exec
명령을 입력으로 사용하여 docker/run
단계를 프로덕션할 것입니다. 그리고 docker/run
단계를 컴파일하고 실행할 것입니다.
그러나 이는 Step Runner가 docker/run
단계를 구성하는 방법을 알 필요가 있다는 것을 요구합니다. 이는 Step Runner을 격리 방법과 결합시키며 VM 등 다른 방법에서의 격리를 더 복잡하게 만듭니다.
네이티브 도커 (거부된 옵션)
기본 단계에는 도커 컨테이너에서 단계를 실행할 수 있는 조항이 포함될 수 있습니다. 예를 들어 단계에는 ref
“target” 필드와 image
필드가 포함될 수 있습니다.
그러나 이 또한 Step Runner를 도커와 결합시키며 Step Runner의 역할을 확장합니다. 도커를 Step Runner가 다른 단계와 마찬가지로 실행하는 외부 단계로 만드는 것이 바람직합니다.