InfoGrab Docs

CI/CD 컴포넌트 예시

요약

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다. 예를 들어 Code Quality CI/CD 컴포넌트에는 테스트용 코드 샘플이 여러 개 있습니다. 컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다.

컴포넌트 테스트#

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다. 예를 들어 특정 프로그래밍 언어로 소프트웨어를 린트, 빌드 및 테스트하는 컴포넌트에는 실제 소스 코드 샘플이 필요합니다. 동일한 리포지터리에 소스 코드 예시, 구성 파일 등을 포함할 수 있습니다.

예를 들어 Code Quality CI/CD 컴포넌트에는 테스트용 코드 샘플이 여러 개 있습니다.

예시: Rust 언어 CI/CD 컴포넌트 테스트#

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다.

다음 Rust 프로그래밍 언어를 위한 "hello world" 예시는 단순함을 위해 cargo 도구 체인을 사용합니다:

  1. CI/CD 컴포넌트 루트 디렉토리로 이동합니다.

  2. cargo init 명령을 사용하여 새 Rust 프로젝트를 초기화합니다.

    cargo init
    

    이 명령은 src/main.rs "hello world" 예시를 포함한 모든 필수 프로젝트 파일을 생성합니다. 이 단계는 cargo build로 컴포넌트 Job에서 Rust 소스 코드를 빌드하는 데 충분합니다.

    tree
    .
    ├── Cargo.toml
    ├── LICENSE.md
    ├── README.md
    ├── src
    │   └── main.rs
    └── templates
        └── build.yml
    
  3. 컴포넌트에 Rust 소스 코드를 빌드하는 Job이 있는지 확인합니다. 예를 들어 templates/build.yml에:

    spec:
      inputs:
        stage:
          default: build
          description: 'Defines the build stage'
        rust_version:
          default: latest
          description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest'
    ---
    
    "build-$[[ inputs.rust_version ]]":
      stage: $[[ inputs.stage ]]
      image: rust:$[[ inputs.rust_version ]]
      script:
        - cargo build --verbose
    

    이 예시에서:

    • stagerust_version 입력은 기본값에서 수정될 수 있습니다. CI/CD Job은 build- 접두사로 시작하고 rust_version 입력을 기반으로 이름을 동적으로 생성합니다. cargo build --verbose 명령은 Rust 소스 코드를 컴파일합니다.
  4. 프로젝트의 .gitlab-ci.yml 구성 파일에서 컴포넌트의 build 템플릿을 테스트합니다:

    include:
      # include the component located in the current project from the current SHA
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        inputs:
          stage: build
    
    stages: [build, test, release]
    
  5. 테스트 실행 등을 위해 Rust 코드에 추가 함수와 테스트를 추가하고 cargo test를 실행하는 templates/test.yml에 컴포넌트 템플릿과 Job을 추가합니다.

    spec:
      inputs:
        stage:
          default: test
          description: 'Defines the test stage'
        rust_version:
          default: latest
          description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest'
    ---
    
    "test-$[[ inputs.rust_version ]]":
      stage: $[[ inputs.stage ]]
      image: rust:$[[ inputs.rust_version ]]
      script:
        - cargo test --verbose
    
  6. test 컴포넌트 템플릿을 포함하여 파이프라인에서 추가 Job을 테스트합니다:

    include:
      # include the component located in the current project from the current SHA
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        inputs:
          stage: build
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA
        inputs:
          stage: test
    
    stages: [build, test, release]
    

CI/CD 컴포넌트 패턴#

이 섹션은 CI/CD 컴포넌트에서 일반적인 패턴을 구현하는 실용적인 예시를 제공합니다.

부울 입력을 사용하여 Job을 조건부로 구성#

boolean 유형 입력과 extends 기능을 결합하여 두 가지 조건으로 Job을 구성할 수 있습니다.

예를 들어 boolean 입력으로 복잡한 캐싱 동작을 구성하려면:

spec:
  inputs:
    enable_special_caching:
      description: 'If set to `true` configures a complex caching behavior'
      type: boolean
---

.my-component:enable_special_caching:false:
  extends: null

.my-component:enable_special_caching:true:
  cache:
    policy: pull-push
    key: $CI_COMMIT_SHA
    paths: [...]

my-job:
  extends: '.my-component:enable_special_caching:$[[ inputs.enable_special_caching ]]'
  script: ... # run some fancy tooling

이 패턴은 enable_special_caching 입력을 Job의 extends 키워드에 전달하여 작동합니다. enable_special_cachingtrue인지 false인지에 따라 미리 정의된 숨김 Job(.my-component:enable_special_caching:true 또는 .my-component:enable_special_caching:false)에서 적절한 구성이 선택됩니다.

options를 사용하여 Job을 조건부로 구성#

ifelseif 조건과 유사한 동작을 위해 여러 옵션으로 Job을 구성할 수 있습니다. 원하는 수의 조건에 대해 string 유형과 여러 options와 함께 extends를 사용합니다.

예를 들어 3가지 다른 옵션으로 복잡한 캐싱 동작을 구성하려면:

spec:
  inputs:
    cache_mode:
      description: Defines the caching mode to use for this component
      type: string
      options:
        - default
        - aggressive
        - relaxed
---

.my-component:cache_mode:default:
  extends: null

.my-component:cache_mode:aggressive:
  cache:
    policy: push
    key: $CI_COMMIT_SHA
    paths: ['*/**']

.my-component:cache_mode:relaxed:
  cache:
    policy: pull-push
    key: $CI_COMMIT_BRANCH
    paths: ['bin/*']

my-job:
  extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]'
  script: ... # run some fancy tooling

이 예시에서 cache_mode 입력은 default, aggressive, relaxed 옵션을 제공하며 각각 다른 숨김 Job에 해당합니다. extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]'로 컴포넌트 Job을 확장하면 Job이 선택된 옵션을 기반으로 올바른 캐싱 구성을 동적으로 상속합니다.

컴포넌트 컨텍스트를 사용하여 버전화된 리소스 참조#

히스토리
  • GitLab 18.6에서 ci_component_context_interpolation이라는 플래그와 함께 베타도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 18.7에서 일반 사용 가능. 기능 플래그 ci_component_context_interpolation이 제거되었습니다.

컴포넌트 컨텍스트 CI/CD 표현식을 사용하여 버전 및 커밋 SHA와 같은 컴포넌트 메타데이터를 참조합니다. 한 가지 사용 사례는 컴포넌트와 함께 버전화된 리소스(예: Docker 이미지)를 빌드하고 게시하며 컴포넌트가 일치하는 버전을 사용하도록 하는 것입니다.

예를 들어:

  • 컴포넌트 버전과 일치하는 태그로 컴포넌트의 릴리스 파이프라인에서 Docker 이미지를 빌드합니다.
  • 컴포넌트가 동일한 이미지 버전을 참조하도록 합니다.

컴포넌트 프로젝트의 릴리스 파이프라인(.gitlab-ci.yml)에서:

build-image:
  stage: build
  image: docker:latest
  script:
    - docker build -t $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG .
    - docker push $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG

create-release:
  stage: release
  image: registry.gitlab.com/gitlab-org/cli:latest
  script: echo "Creating release $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG
  release:
    tag_name: $CI_COMMIT_TAG
    description: "Release $CI_COMMIT_TAG"

컴포넌트 템플릿(templates/my-component/template.yml)에서:

spec:
  component: [version, reference]
  inputs:
    stage:
      default: test
---

run-tool:
  stage: $[[ inputs.stage ]]
  image: $CI_REGISTRY_IMAGE/my-tool:$[[ component.version ]]
  script:
    - echo "Running tool version $[[ component.version ]]"
    - echo "Component was included using reference: $[[ component.reference ]]"
    - my-tool --version

이 예시에서:

  • @1.0.0으로 컴포넌트를 포함하면 Job은 이미지 my-tool:1.0.0을 사용합니다.
  • @1.0으로 포함하면 최신 1.0.x 버전(예: 1.0.3)으로 확인되어 my-tool:1.0.3을 사용합니다.
  • @~latest로 포함하면 최신 릴리스 버전을 사용합니다.
  • component.reference 필드는 1.0, ~latest 또는 SHA와 같이 지정한 정확한 참조를 표시합니다. 참조는 로깅 또는 디버깅에 유용할 수 있습니다.

CI/CD 컴포넌트 마이그레이션 예시#

이 섹션은 CI/CD 템플릿과 파이프라인 구성을 재사용 가능한 CI/CD 컴포넌트로 마이그레이션하는 실용적인 예시를 보여줍니다.

CI/CD 컴포넌트 마이그레이션 예시: Go#

소프트웨어 개발 수명 주기를 위한 완전한 파이프라인은 여러 Job과 Stage로 구성할 수 있습니다. 프로그래밍 언어용 CI/CD 템플릿은 단일 템플릿 파일에 여러 Job을 제공할 수 있습니다. 실습으로 다음 Go CI/CD 템플릿을 마이그레이션해야 합니다.

default:
  image: golang:latest

stages:
  - test
  - build
  - deploy

format:
  stage: test
  script:
    - go fmt $(go list ./... | grep -v /vendor/)
    - go vet $(go list ./... | grep -v /vendor/)
    - go test -race $(go list ./... | grep -v /vendor/)

compile:
  stage: build
  script:
    - mkdir -p mybinaries
    - go build -o mybinaries ./...
  artifacts:
    paths:
      - mybinaries
Note

보다 점진적인 접근 방식을 위해 한 번에 하나의 Job을 마이그레이션합니다. build Job으로 시작한 다음 formattest Job에 대해 단계를 반복합니다.

CI/CD 템플릿 마이그레이션에는 다음 단계가 포함됩니다:

  1. CI/CD Job과 종속성을 분석하고 마이그레이션 작업을 정의합니다:

    • image 구성은 전역적이며 Job 정의로 이동해야 합니다.
    • format Job은 하나의 Job에서 여러 go 명령을 실행합니다. 파이프라인 효율성을 높이기 위해 go test 명령을 별도의 Job으로 이동해야 합니다.
    • compile Job은 go build를 실행하며 build로 이름을 변경해야 합니다.
  2. 더 나은 파이프라인 효율성을 위한 최적화 전략을 정의합니다.

    • 다른 CI/CD 파이프라인 소비자가 구성을 허용하려면 stage Job 속성을 구성 가능하게 해야 합니다.
    • image 키는 하드코딩된 이미지 태그 latest를 사용합니다. 더 유연하고 재사용 가능한 파이프라인을 위해 기본값이 latest입력으로 golang_version 추가. 입력은 Docker Hub 이미지 태그 값과 일치해야 합니다.
    • compile Job은 하드코딩된 대상 디렉토리 mybinaries에 바이너리를 빌드하는데, 기본값이 mybinaries인 동적 입력으로 향상될 수 있습니다.
  3. 각 Job에 대한 템플릿 하나를 기준으로 새 컴포넌트의 디렉토리 구조를 생성합니다.

    • 템플릿 이름은 go 명령을 따라야 합니다. 예를 들어 format.yml, build.yml, test.yml.
    • 새 프로젝트를 생성하고 Git 리포지터리를 초기화하고 모든 변경 사항을 추가/커밋하고 원격 원본을 설정하고 푸시합니다. CI/CD 컴포넌트 프로젝트 경로에 맞게 URL을 수정합니다.
    • 컴포넌트 작성 가이드에 설명된 추가 파일을 생성합니다: README.md, LICENSE.md, .gitlab-ci.yml, .gitignore. 다음 셸 명령은 Go 컴포넌트 구조를 초기화합니다:
    git init
    
    mkdir templates
    touch templates/{format,build,test}.yml
    
    touch README.md LICENSE.md .gitlab-ci.yml .gitignore
    
    git add -A
    git commit -avm "Initial component structure"
    
    git remote add origin https://gitlab.example.com/components/golang.git
    
    git push
    
  4. CI/CD Job을 템플릿으로 생성합니다. build Job부터 시작합니다.

    • spec 섹션에 stage, golang_version, binary_directory 입력을 정의합니다.

    • inputs.golang_version에 액세스하여 동적 Job 이름 정의를 추가합니다.

    • inputs.golang_version에 액세스하여 동적 Go 이미지 버전에 유사한 패턴을 사용합니다.

    • Stage를 inputs.stage 값에 할당합니다.

    • inputs.binary_directory에서 바이너리 디렉터리를 생성하고 go build에 매개변수로 추가합니다.

    • 아티팩트 경로를 inputs.binary_directory로 정의합니다.

      spec:
        inputs:
          stage:
            default: 'build'
            description: 'Defines the build stage'
          golang_version:
            default: 'latest'
            description: 'Go image version tag'
          binary_directory:
            default: 'mybinaries'
            description: 'Output directory for created binary artifacts'
      ---
      
      "build-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - mkdir -p $[[ inputs.binary_directory ]]
          - go build -o $[[ inputs.binary_directory ]] ./...
        artifacts:
          paths:
            - $[[ inputs.binary_directory ]]
      
    • format Job 템플릿은 동일한 패턴을 따르지만 stagegolang_version 입력만 필요합니다.

      spec:
        inputs:
          stage:
            default: 'format'
            description: 'Defines the format stage'
          golang_version:
            default: 'latest'
            description: 'Golang image version tag'
      ---
      
      "format-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - go fmt $(go list ./... | grep -v /vendor/)
          - go vet $(go list ./... | grep -v /vendor/)
      
    • test Job 템플릿은 동일한 패턴을 따르지만 stagegolang_version 입력만 필요합니다.

      spec:
        inputs:
          stage:
            default: 'test'
            description: 'Defines the format stage'
          golang_version:
            default: 'latest'
            description: 'Golang image version tag'
      ---
      
      "test-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - go test -race $(go list ./... | grep -v /vendor/)
      
  5. 컴포넌트를 테스트하려면 .gitlab-ci.yml 구성 파일을 수정하고 테스트를 추가합니다.

    • build Job에 대한 입력으로 golang_version에 다른 값을 지정합니다.

    • CI/CD 컴포넌트 경로에 맞게 URL을 수정합니다.

      stages: [format, build, test]
      
      include:
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/format@$CI_COMMIT_SHA
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
          inputs:
            golang_version: "1.21"
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA
          inputs:
            golang_version: latest
      
  6. CI/CD 컴포넌트를 테스트하기 위한 Go 소스 코드를 추가합니다. go 명령에는 루트 디렉토리에 go.modmain.go가 있는 Go 프로젝트가 필요합니다.

    • Go 모듈을 초기화합니다. CI/CD 컴포넌트 경로에 맞게 URL을 수정합니다.

      go mod init example.gitlab.com/components/golang
      
    • main 함수가 있는 main.go 파일을 생성하고 예를 들어 Hello, CI/CD component를 출력합니다. GitLab Duo Code Suggestions를 사용하여 Go 코드를 생성하기 위해 코드 주석을 사용할 수 있습니다.

      // Specify the package, import required packages
      // Create a main function
      // Inside the main function, print "Hello, CI/CD Component"
      
      package main
      
      import "fmt"
      
      func main() {
        fmt.Println("Hello, CI/CD Component")
      }
      
    • 디렉토리 트리는 다음과 같아야 합니다:

      tree
      .
      ├── LICENSE.md
      ├── README.md
      ├── go.mod
      ├── main.go
      └── templates
          ├── build.yml
          ├── format.yml
          └── test.yml
      

마이그레이션을 완료하려면 CI/CD 템플릿을 컴포넌트로 변환 섹션의 나머지 단계를 따릅니다:

  1. 변경 사항을 커밋하고 푸시하고 CI/CD 파이프라인 결과를 확인합니다.
  2. 컴포넌트 작성 가이드에 따라 README.mdLICENSE.md 파일을 업데이트합니다.
  3. 컴포넌트를 릴리스하고 CI/CD 카탈로그에서 확인합니다.
  4. 스테이징/프로덕션 환경에 CI/CD 컴포넌트를 추가합니다.

GitLab에서 유지 관리하는 Go 컴포넌트는 Go CI/CD 템플릿에서의 성공적인 마이그레이션 예시를 제공하며 입력과 컴포넌트 모범 사례로 향상되었습니다. 더 자세히 알아보려면 Git 히스토리를 검사할 수 있습니다.

CI/CD 컴포넌트 예시

Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다. 예를 들어 Code Quality CI/CD 컴포넌트에는 테스트용 코드 샘플이 여러 개 있습니다. 컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다.

컴포넌트 테스트#

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다. 예를 들어 특정 프로그래밍 언어로 소프트웨어를 린트, 빌드 및 테스트하는 컴포넌트에는 실제 소스 코드 샘플이 필요합니다. 동일한 리포지터리에 소스 코드 예시, 구성 파일 등을 포함할 수 있습니다.

예를 들어 Code Quality CI/CD 컴포넌트에는 테스트용 코드 샘플이 여러 개 있습니다.

예시: Rust 언어 CI/CD 컴포넌트 테스트#

컴포넌트의 기능에 따라 컴포넌트 테스트에는 리포지터리의 추가 파일이 필요할 수 있습니다.

다음 Rust 프로그래밍 언어를 위한 "hello world" 예시는 단순함을 위해 cargo 도구 체인을 사용합니다:

  1. CI/CD 컴포넌트 루트 디렉토리로 이동합니다.

  2. cargo init 명령을 사용하여 새 Rust 프로젝트를 초기화합니다.

    cargo init
    

    이 명령은 src/main.rs "hello world" 예시를 포함한 모든 필수 프로젝트 파일을 생성합니다. 이 단계는 cargo build로 컴포넌트 Job에서 Rust 소스 코드를 빌드하는 데 충분합니다.

    tree
    .
    ├── Cargo.toml
    ├── LICENSE.md
    ├── README.md
    ├── src
    │   └── main.rs
    └── templates
        └── build.yml
    
  3. 컴포넌트에 Rust 소스 코드를 빌드하는 Job이 있는지 확인합니다. 예를 들어 templates/build.yml에:

    spec:
      inputs:
        stage:
          default: build
          description: 'Defines the build stage'
        rust_version:
          default: latest
          description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest'
    ---
    
    "build-$[[ inputs.rust_version ]]":
      stage: $[[ inputs.stage ]]
      image: rust:$[[ inputs.rust_version ]]
      script:
        - cargo build --verbose
    

    이 예시에서:

    • stagerust_version 입력은 기본값에서 수정될 수 있습니다. CI/CD Job은 build- 접두사로 시작하고 rust_version 입력을 기반으로 이름을 동적으로 생성합니다. cargo build --verbose 명령은 Rust 소스 코드를 컴파일합니다.
  4. 프로젝트의 .gitlab-ci.yml 구성 파일에서 컴포넌트의 build 템플릿을 테스트합니다:

    include:
      # include the component located in the current project from the current SHA
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        inputs:
          stage: build
    
    stages: [build, test, release]
    
  5. 테스트 실행 등을 위해 Rust 코드에 추가 함수와 테스트를 추가하고 cargo test를 실행하는 templates/test.yml에 컴포넌트 템플릿과 Job을 추가합니다.

    spec:
      inputs:
        stage:
          default: test
          description: 'Defines the test stage'
        rust_version:
          default: latest
          description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest'
    ---
    
    "test-$[[ inputs.rust_version ]]":
      stage: $[[ inputs.stage ]]
      image: rust:$[[ inputs.rust_version ]]
      script:
        - cargo test --verbose
    
  6. test 컴포넌트 템플릿을 포함하여 파이프라인에서 추가 Job을 테스트합니다:

    include:
      # include the component located in the current project from the current SHA
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        inputs:
          stage: build
      - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA
        inputs:
          stage: test
    
    stages: [build, test, release]
    

CI/CD 컴포넌트 패턴#

이 섹션은 CI/CD 컴포넌트에서 일반적인 패턴을 구현하는 실용적인 예시를 제공합니다.

부울 입력을 사용하여 Job을 조건부로 구성#

boolean 유형 입력과 extends 기능을 결합하여 두 가지 조건으로 Job을 구성할 수 있습니다.

예를 들어 boolean 입력으로 복잡한 캐싱 동작을 구성하려면:

spec:
  inputs:
    enable_special_caching:
      description: 'If set to `true` configures a complex caching behavior'
      type: boolean
---

.my-component:enable_special_caching:false:
  extends: null

.my-component:enable_special_caching:true:
  cache:
    policy: pull-push
    key: $CI_COMMIT_SHA
    paths: [...]

my-job:
  extends: '.my-component:enable_special_caching:$[[ inputs.enable_special_caching ]]'
  script: ... # run some fancy tooling

이 패턴은 enable_special_caching 입력을 Job의 extends 키워드에 전달하여 작동합니다. enable_special_cachingtrue인지 false인지에 따라 미리 정의된 숨김 Job(.my-component:enable_special_caching:true 또는 .my-component:enable_special_caching:false)에서 적절한 구성이 선택됩니다.

options를 사용하여 Job을 조건부로 구성#

ifelseif 조건과 유사한 동작을 위해 여러 옵션으로 Job을 구성할 수 있습니다. 원하는 수의 조건에 대해 string 유형과 여러 options와 함께 extends를 사용합니다.

예를 들어 3가지 다른 옵션으로 복잡한 캐싱 동작을 구성하려면:

spec:
  inputs:
    cache_mode:
      description: Defines the caching mode to use for this component
      type: string
      options:
        - default
        - aggressive
        - relaxed
---

.my-component:cache_mode:default:
  extends: null

.my-component:cache_mode:aggressive:
  cache:
    policy: push
    key: $CI_COMMIT_SHA
    paths: ['*/**']

.my-component:cache_mode:relaxed:
  cache:
    policy: pull-push
    key: $CI_COMMIT_BRANCH
    paths: ['bin/*']

my-job:
  extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]'
  script: ... # run some fancy tooling

이 예시에서 cache_mode 입력은 default, aggressive, relaxed 옵션을 제공하며 각각 다른 숨김 Job에 해당합니다. extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]'로 컴포넌트 Job을 확장하면 Job이 선택된 옵션을 기반으로 올바른 캐싱 구성을 동적으로 상속합니다.

컴포넌트 컨텍스트를 사용하여 버전화된 리소스 참조#

히스토리
  • GitLab 18.6에서 ci_component_context_interpolation이라는 플래그와 함께 베타도입되었습니다. 기본적으로 활성화되어 있습니다.
  • GitLab 18.7에서 일반 사용 가능. 기능 플래그 ci_component_context_interpolation이 제거되었습니다.

컴포넌트 컨텍스트 CI/CD 표현식을 사용하여 버전 및 커밋 SHA와 같은 컴포넌트 메타데이터를 참조합니다. 한 가지 사용 사례는 컴포넌트와 함께 버전화된 리소스(예: Docker 이미지)를 빌드하고 게시하며 컴포넌트가 일치하는 버전을 사용하도록 하는 것입니다.

예를 들어:

  • 컴포넌트 버전과 일치하는 태그로 컴포넌트의 릴리스 파이프라인에서 Docker 이미지를 빌드합니다.
  • 컴포넌트가 동일한 이미지 버전을 참조하도록 합니다.

컴포넌트 프로젝트의 릴리스 파이프라인(.gitlab-ci.yml)에서:

build-image:
  stage: build
  image: docker:latest
  script:
    - docker build -t $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG .
    - docker push $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG

create-release:
  stage: release
  image: registry.gitlab.com/gitlab-org/cli:latest
  script: echo "Creating release $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG
  release:
    tag_name: $CI_COMMIT_TAG
    description: "Release $CI_COMMIT_TAG"

컴포넌트 템플릿(templates/my-component/template.yml)에서:

spec:
  component: [version, reference]
  inputs:
    stage:
      default: test
---

run-tool:
  stage: $[[ inputs.stage ]]
  image: $CI_REGISTRY_IMAGE/my-tool:$[[ component.version ]]
  script:
    - echo "Running tool version $[[ component.version ]]"
    - echo "Component was included using reference: $[[ component.reference ]]"
    - my-tool --version

이 예시에서:

  • @1.0.0으로 컴포넌트를 포함하면 Job은 이미지 my-tool:1.0.0을 사용합니다.
  • @1.0으로 포함하면 최신 1.0.x 버전(예: 1.0.3)으로 확인되어 my-tool:1.0.3을 사용합니다.
  • @~latest로 포함하면 최신 릴리스 버전을 사용합니다.
  • component.reference 필드는 1.0, ~latest 또는 SHA와 같이 지정한 정확한 참조를 표시합니다. 참조는 로깅 또는 디버깅에 유용할 수 있습니다.

CI/CD 컴포넌트 마이그레이션 예시#

이 섹션은 CI/CD 템플릿과 파이프라인 구성을 재사용 가능한 CI/CD 컴포넌트로 마이그레이션하는 실용적인 예시를 보여줍니다.

CI/CD 컴포넌트 마이그레이션 예시: Go#

소프트웨어 개발 수명 주기를 위한 완전한 파이프라인은 여러 Job과 Stage로 구성할 수 있습니다. 프로그래밍 언어용 CI/CD 템플릿은 단일 템플릿 파일에 여러 Job을 제공할 수 있습니다. 실습으로 다음 Go CI/CD 템플릿을 마이그레이션해야 합니다.

default:
  image: golang:latest

stages:
  - test
  - build
  - deploy

format:
  stage: test
  script:
    - go fmt $(go list ./... | grep -v /vendor/)
    - go vet $(go list ./... | grep -v /vendor/)
    - go test -race $(go list ./... | grep -v /vendor/)

compile:
  stage: build
  script:
    - mkdir -p mybinaries
    - go build -o mybinaries ./...
  artifacts:
    paths:
      - mybinaries
Note

보다 점진적인 접근 방식을 위해 한 번에 하나의 Job을 마이그레이션합니다. build Job으로 시작한 다음 formattest Job에 대해 단계를 반복합니다.

CI/CD 템플릿 마이그레이션에는 다음 단계가 포함됩니다:

  1. CI/CD Job과 종속성을 분석하고 마이그레이션 작업을 정의합니다:

    • image 구성은 전역적이며 Job 정의로 이동해야 합니다.
    • format Job은 하나의 Job에서 여러 go 명령을 실행합니다. 파이프라인 효율성을 높이기 위해 go test 명령을 별도의 Job으로 이동해야 합니다.
    • compile Job은 go build를 실행하며 build로 이름을 변경해야 합니다.
  2. 더 나은 파이프라인 효율성을 위한 최적화 전략을 정의합니다.

    • 다른 CI/CD 파이프라인 소비자가 구성을 허용하려면 stage Job 속성을 구성 가능하게 해야 합니다.
    • image 키는 하드코딩된 이미지 태그 latest를 사용합니다. 더 유연하고 재사용 가능한 파이프라인을 위해 기본값이 latest입력으로 golang_version 추가. 입력은 Docker Hub 이미지 태그 값과 일치해야 합니다.
    • compile Job은 하드코딩된 대상 디렉토리 mybinaries에 바이너리를 빌드하는데, 기본값이 mybinaries인 동적 입력으로 향상될 수 있습니다.
  3. 각 Job에 대한 템플릿 하나를 기준으로 새 컴포넌트의 디렉토리 구조를 생성합니다.

    • 템플릿 이름은 go 명령을 따라야 합니다. 예를 들어 format.yml, build.yml, test.yml.
    • 새 프로젝트를 생성하고 Git 리포지터리를 초기화하고 모든 변경 사항을 추가/커밋하고 원격 원본을 설정하고 푸시합니다. CI/CD 컴포넌트 프로젝트 경로에 맞게 URL을 수정합니다.
    • 컴포넌트 작성 가이드에 설명된 추가 파일을 생성합니다: README.md, LICENSE.md, .gitlab-ci.yml, .gitignore. 다음 셸 명령은 Go 컴포넌트 구조를 초기화합니다:
    git init
    
    mkdir templates
    touch templates/{format,build,test}.yml
    
    touch README.md LICENSE.md .gitlab-ci.yml .gitignore
    
    git add -A
    git commit -avm "Initial component structure"
    
    git remote add origin https://gitlab.example.com/components/golang.git
    
    git push
    
  4. CI/CD Job을 템플릿으로 생성합니다. build Job부터 시작합니다.

    • spec 섹션에 stage, golang_version, binary_directory 입력을 정의합니다.

    • inputs.golang_version에 액세스하여 동적 Job 이름 정의를 추가합니다.

    • inputs.golang_version에 액세스하여 동적 Go 이미지 버전에 유사한 패턴을 사용합니다.

    • Stage를 inputs.stage 값에 할당합니다.

    • inputs.binary_directory에서 바이너리 디렉터리를 생성하고 go build에 매개변수로 추가합니다.

    • 아티팩트 경로를 inputs.binary_directory로 정의합니다.

      spec:
        inputs:
          stage:
            default: 'build'
            description: 'Defines the build stage'
          golang_version:
            default: 'latest'
            description: 'Go image version tag'
          binary_directory:
            default: 'mybinaries'
            description: 'Output directory for created binary artifacts'
      ---
      
      "build-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - mkdir -p $[[ inputs.binary_directory ]]
          - go build -o $[[ inputs.binary_directory ]] ./...
        artifacts:
          paths:
            - $[[ inputs.binary_directory ]]
      
    • format Job 템플릿은 동일한 패턴을 따르지만 stagegolang_version 입력만 필요합니다.

      spec:
        inputs:
          stage:
            default: 'format'
            description: 'Defines the format stage'
          golang_version:
            default: 'latest'
            description: 'Golang image version tag'
      ---
      
      "format-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - go fmt $(go list ./... | grep -v /vendor/)
          - go vet $(go list ./... | grep -v /vendor/)
      
    • test Job 템플릿은 동일한 패턴을 따르지만 stagegolang_version 입력만 필요합니다.

      spec:
        inputs:
          stage:
            default: 'test'
            description: 'Defines the format stage'
          golang_version:
            default: 'latest'
            description: 'Golang image version tag'
      ---
      
      "test-$[[ inputs.golang_version ]]":
        image: golang:$[[ inputs.golang_version ]]
        stage: $[[ inputs.stage ]]
        script:
          - go test -race $(go list ./... | grep -v /vendor/)
      
  5. 컴포넌트를 테스트하려면 .gitlab-ci.yml 구성 파일을 수정하고 테스트를 추가합니다.

    • build Job에 대한 입력으로 golang_version에 다른 값을 지정합니다.

    • CI/CD 컴포넌트 경로에 맞게 URL을 수정합니다.

      stages: [format, build, test]
      
      include:
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/format@$CI_COMMIT_SHA
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA
          inputs:
            golang_version: "1.21"
        - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA
          inputs:
            golang_version: latest
      
  6. CI/CD 컴포넌트를 테스트하기 위한 Go 소스 코드를 추가합니다. go 명령에는 루트 디렉토리에 go.modmain.go가 있는 Go 프로젝트가 필요합니다.

    • Go 모듈을 초기화합니다. CI/CD 컴포넌트 경로에 맞게 URL을 수정합니다.

      go mod init example.gitlab.com/components/golang
      
    • main 함수가 있는 main.go 파일을 생성하고 예를 들어 Hello, CI/CD component를 출력합니다. GitLab Duo Code Suggestions를 사용하여 Go 코드를 생성하기 위해 코드 주석을 사용할 수 있습니다.

      // Specify the package, import required packages
      // Create a main function
      // Inside the main function, print "Hello, CI/CD Component"
      
      package main
      
      import "fmt"
      
      func main() {
        fmt.Println("Hello, CI/CD Component")
      }
      
    • 디렉토리 트리는 다음과 같아야 합니다:

      tree
      .
      ├── LICENSE.md
      ├── README.md
      ├── go.mod
      ├── main.go
      └── templates
          ├── build.yml
          ├── format.yml
          └── test.yml
      

마이그레이션을 완료하려면 CI/CD 템플릿을 컴포넌트로 변환 섹션의 나머지 단계를 따릅니다:

  1. 변경 사항을 커밋하고 푸시하고 CI/CD 파이프라인 결과를 확인합니다.
  2. 컴포넌트 작성 가이드에 따라 README.mdLICENSE.md 파일을 업데이트합니다.
  3. 컴포넌트를 릴리스하고 CI/CD 카탈로그에서 확인합니다.
  4. 스테이징/프로덕션 환경에 CI/CD 컴포넌트를 추가합니다.

GitLab에서 유지 관리하는 Go 컴포넌트는 Go CI/CD 템플릿에서의 성공적인 마이그레이션 예시를 제공하며 입력과 컴포넌트 모범 사례로 향상되었습니다. 더 자세히 알아보려면 Git 히스토리를 검사할 수 있습니다.