Crossplane 확장 릴리스 프로세스
Crossplane 확장 릴리스 프로세스 (Extensions Release Process)
크로스플레인 확장(extension)을 배포하고 릴리스하는 방법을 설명하는 가이드입니다. 크로스플레인은 리소스를 구성하는 API와 비즈니스 로직으로 크로스플레인 인스턴스를 확장하기 위한 패키징 사양을 제공합니다.
출처: 문서
본문
Crossplane 확장 배포하기 (Distributing Crossplane extensions)
크로스플레인은 리소스를 구성하는 API와 비즈니스 로직으로 크로스플레인 인스턴스를 확장하기 위한 패키징 사양을 제공합니다.
크로스플레인 확장을 빌드한다는 것은 xpkg 형식의 OCI 이미지를 만드는 것을 의미합니다. 크로스플레인 확장의 작성자와 유지보수자는 사용자가 패키지를 참조하고 사용하기 전에 패키지를 OCI 레지스트리에 푸시해야 합니다.
크로스플레인 확장의 릴리스 프로세스는 커뮤니티에서 자연스럽게 성장했으며 자체적인 관례와 공통 구성이 발전했습니다. 확장 작성자는 git 워크플로우의 일부로 패키지를 빌드하고 푸시하는 자동화를 활성화하려면 이 가이드를 따라야 합니다.
이 가이드는 크로스플레인 커뮤니티가 현재 사용하는 주요 레지스트리인 xpkg.crossplane.io에 크로스플레인 확장을 푸시하기 위해 GitHub Actions에서 자동화된 CI 파이프라인을 구성하는 단계별 지침을 제공합니다.
팁 크로스플레인 패키지에 대한 자세한 내용은 xpkg 개념을 검토하세요.
참고 이 가이드는 크로스플레인 확장의 빌드와 릴리스에 초점을 맞춥니다. 핵심 크로스플레인 소프트웨어의 릴리스 프로세스는
crossplane/release저장소에서 확인할 수 있습니다.
일반적인 워크플로우 (Typical workflow)
확장을 빌드하고 릴리스하는 일반적인 GitHub 워크플로우 정의에는 다음 단계가 포함됩니다.
- 소스 저장소 가져오기
- 원격 레지스트리 인증
- 아티팩트 빌드 및 패키징
- 아티팩트 푸시(게시)
경고 원격 레지스트리에 제공된 자격 증명은 레지스트리 업로드 요청이
push인증 범위를 지정하므로 읽기 및 쓰기 접근 권한이 필요합니다.
퀵스타트: xpkg.crossplane.io에 Provider 릴리스하기 (Quickstart)
사전 요구 사항 (Prerequisites)
- GitHub 저장소. 예를 들어 Upjet 템플릿에서 만든 저장소
단계 (Steps)
.github/workflows아래에 새 YAML 파일을 만듭니다. 관례적으로 이 파일을publish-provider-package.yaml이라고 이름 짓습니다.- 다음 워크플로우 정의를 파일에 복사하고 을 레지스트리의 원하는 저장소 이름으로 바꿉니다.
name: Publish Provider Package
on:
workflow_dispatch:
inputs:
version:
description: "Version string to use while publishing the package (e.g. v1.0.0-alpha.1)"
default: ''
required: false
go-version:
description: 'Go version to use if building needs to be done'
default: '1.23'
required: false
jobs:
publish-provider-package:
uses: crossplane-contrib/provider-workflows/.github/workflows/publish-provider-non-family.yml@main
with:
repository:
version: ${{ github.event.inputs.version }}
go-version: ${{ github.event.inputs.go-version }}
cleanup-disk: true
secrets:
GHCR_PAT: ${{ secrets.GITHUB_TOKEN }}
- 워크플로우 파일을 GitHub 저장소의 기본 브랜치에 커밋합니다.
- 이제 워크플로우는 GitHub UI의 Actions 탭에서 트리거할 수 있어야 합니다.
- GitHub UI에서 이름에
release-접두어가 있는 릴리스 브랜치를 만듭니다. 예:release-0.1. - 릴리스 브랜치의 원하는 커밋에 유효한 semver 릴리스 태그를 지정합니다. 예:
v0.1.0. 기본적으로 이것이 레지스트리에 푸시되는 추론된 참조입니다. - GitHub UI에서 5단계의 릴리스 브랜치를 대상으로 워크플로우를 수동으로 실행합니다. 태깅 관행에 대한 자세한 내용과 추론된 git 태그 버전을 선택적으로 덮어쓰는 방법은 branching conventions을 참고하세요.
퀵스타트: xpkg.crossplane.io에 Function 릴리스하기 (Quickstart)
함수의 템플릿 저장소는 추가 구성 없이 xpkg.crossplane.io에 푸시하는 기능적인 GitHub Action YAML 파일을 제공합니다.
새 릴리스를 레지스트리에 빌드하고 푸시하려면:
- GitHub UI에서 이름에
release-접두어가 있는 릴리스 브랜치를 만듭니다. 예:release-0.1. - 릴리스 브랜치의 원하는 커밋에 해당 GitHub Release에 대한 유효한 semver 릴리스 태그를 지정합니다. 예:
v0.1.0. - GitHub UI에서 1단계의 릴리스 브랜치를 대상으로 워크플로우를 수동으로 실행합니다. 워크플로우는 사용자 입력이 제공되지 않으면 기본 버전 문자열을 생성합니다. 태깅 관행에 대한 자세한 내용과 추론된 git 태그 버전을 선택적으로 덮어쓰는 방법은 branching conventions을 참고하세요.
공통 구성 (Common configuration)
퀵스타트 가이드에서 참조한 재사용 가능한 워크플로우는 편의를 위한 것이지만, 사용자는 자신만의 사용자 정의 GitHub Actions를 작성할 수도 있습니다.
이 섹션과 다음 섹션들은 릴리스 프로세스를 구현하기 위한 일반적인 구성 옵션과 관례에 대한 더 자세한 정보를 제공합니다.
모든 워크플로우는 원격 레지스트리의 자격 증명에 대한 참조가 필요합니다. 일반적으로 사용자는 이를 GitHub Actions Secrets로 구성하고, 워크플로우는 docker/login-action 액션을 통해 인증을 수행합니다.
예를 들어, 파이프라인에 다음 단계를 추가하면 워크플로우의 임시 GitHub OIDC 토큰을 사용하여 작업을 ghcr.io에 인증합니다.
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
중요 기본적으로 작업의 OIDC 토큰은
ghcr.io에 패키지를 쓸 권한이 없습니다. 권한은 GitHub 저장소 설정에서 구성하거나 워크플로우 정의 YAML 파일에 명시적으로 선언할 수 있습니다.
패키지 쓰기에는 저장소의 다른 곳에서 구성되지 않았다면 packages: write가 있는 permissions 블록이 필요합니다.
다른 레지스트리의 경우에도 자격 증명을 사용자 정의 Secret 변수로 참조하는 것이 모범 사례입니다. 예를 들어:
- name: Login to Another Registry
uses: docker/login-action@v3
with:
registry: my-registry.io
username: ${{ env.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
브랜칭 관례 (Branching conventions)
크로스플레인 확장의 저장소는 업스트림 크로스플레인과 유사한 브랜칭 관례를 따릅니다. 릴리스 프로세스는 release-* 접두어가 있는 브랜치에서 실행되는 워크플로우를 가정합니다. main도 자주 포함되지만, 일반적인 릴리스 프로세스는 main의 태그에서 빌드하고 푸시하지는 않습니다.
on:
push:
branches:
- main
- release-*
예를 들어 확장의 v0.1.0을 릴리스할 때, 일반적인 프로세스는 빌드 기준이 되는 git 커밋에서 릴리스 브랜치 release-0.1을 만들고 v0.1.0으로 태그를 지정하는 것입니다.
참고 일부 사용자 정의 워크플로우는 git ref에서 추론하는 대신 원격 참조에 대한 명시적 입력을 받을 수 있습니다.
crossplane-contrib/function-python의ci.yml파일이 좋은 예시입니다.
함수 패키지 워크플로우 구성 (Configuring workflows for function packages)
함수 워크플로우 정의는 함수 구현이 사용하는 기본 언어에 따라 다릅니다. 예를 들어 Python 함수는 GitHub Action 러너에 Python 환경이 필요합니다.
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Setup Hatch
run: pipx install hatch==1.7.0
- name: Lint
run: hatch run lint:check
템플릿 저장소가 동작하는 파이프라인 정의를 제공하지만, 사용자는 다른 도구로 환경을 사용자 정의할 수 있습니다.
함수는 또한 핵심 비즈니스 로직의 런타임 이미지가 필요하며, 이를 빌드하여 Function 패키지에 포함시켜야 합니다. 기본 워크플로우 정의는 linux/amd64와 linux/arm64 두 플랫폼으로 빌드합니다.
- name: Build Runtime
id: image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/${{ matrix.arch }}
cache-from: type=gha
cache-to: type=gha,mode=max
target: image
build-args:
PYTHON_VERSION=${{ env.PYTHON_VERSION }}
outputs: type=docker,dest=runtime-${{ matrix.arch }}.tar
프로바이더 패키지 워크플로우 구성 (Configuring workflows for provider packages)
프로바이더는 함수와 달리 크로스플레인 Provider 패키지를 빌드하고 푸시하기 위해 빌드 서브모듈의 사용자 정의 make 타겟을 사용합니다.
특정 레지스트리에 대한 워크플로우 구성은 두 단계를 포함합니다.
- 최상위 Makefile의 레지스트리 변수 업데이트
- 레지스트리에 대한 인증된 자격 증명을 위한 GitHub Actions Secrets 참조
대상 레지스트리 구성 (Configure target registry)
프로바이더 템플릿 저장소에는 최상위 Makefile이 포함되어 있습니다. 대상 레지스트리를 정의하려면 다음 변수를 편집하세요.
XPKG_REG_ORGS— 공백으로 구분된 대상 저장소 목록XPKG_REG_ORGS_NO_PROMOTE— 채널(channel) 태그를 사용하거나 추론하지 않는 레지스트리용
예를 들어 다음은 xpkg.crossplane.io와 index.docker.io에 이중 푸시합니다.
XPKG_REG_ORGS ?= xpkg.crossplane.io/crossplane-contrib index.docker.io/crossplanecontrib
XPKG_REG_ORGS_NO_PROMOTE ?= xpkg.crossplane.io/crossplane-contrib
재사용 가능한 워크플로우 (Reusable workflows)
crossplane-contrib/provider-workflows 저장소는 사용자 정의 CI 파이프라인에서 호출할 수 있는 재사용 가능한 워크플로우 정의를 제공합니다.
예를 들어 다음 스니펫은 provider-kubernetes 패키지를 xpkg.crossplane.io에 빌드하고 푸시하기 위해 호출 가능한 워크플로우를 참조합니다.
jobs:
publish-provider-package:
uses: crossplane-contrib/provider-workflows/.github/workflows/publish-provider-non-family.yml@main
with:
repository: provider-kubernetes
version: ${{ github.event.inputs.version }}
go-version: ${{ github.event.inputs.go-version }}
cleanup-disk: true
secrets:
GHCR_PAT: ${{ secrets.GITHUB_TOKEN }}
팁 여기 참조된 재사용 가능한 워크플로우는 기본적으로
ghcr.io에 게시합니다. 기본 GitHub Actions OIDC 토큰이packages: write권한을 상속하는지 확인하세요.
문제 해결 (Troubleshooting)
워크플로우가 404 오류 코드로 실패하는 이유는 무엇인가요? 대상 저장소가 레지스트리에 존재하는지 확인하세요. 존재하지 않으면 만들어야 합니다.
워크플로우가 401 오류 코드로 실패하는 이유는 무엇인가요?
레지스트리 로그인 단계에서 사용된 자격 증명이 pull 및 push 권한이 있는지, 그리고 {{ secrets.* }} 변수 치환이 GitHub에 구성된 것과 일치하는지 확인하세요.