GitLab CI 기술
물론 우리가 이미 대응한 도전에 대해 다른 해결 방안도 있고, 어떤 해결 방안은 우리보다 더 좋을 수도 있다.우리는 이러한 해결 방안을 듣고 우리 자신의 해결 방안을 개선하는 것을 매우 기쁘게 생각한다.
이 글의 코드는 우리의 CI에서 추출되었고 정리되었다.그래서 필요한 샘플이 부족하다.그것은 원래의 상태로 작동하지 않으며, CI에 적응하기 위한 작업이 필요합니다.즉, 해결 방안을 명확하게 열거해야 한다는 것이다.(당신은 그것을 슬라이드로 상상할 수 있다.)
LFS 검사
모든 과도는 흔들릴 수 있다.이진 파일을 일반적인git Blob로 저장하는 것에서 LFS로 저장하는 것까지의 변화는 이런 험난한 변화이다.
LFS와 관련된 모든 파일 및 패턴이 문서에 포함되어 있는지 확인합니다.gitattributes 파일이지만, LFS 환경을 정확하게 설정하는 데 시간이 좀 걸립니다.또한 LFS에서 제출해야 할 파일을 계속해서 가져와 병합 요청에서 일반 파일로 전송했습니다.
이러한 상황을 피하기 위해서, 우리는 모든 관련 파일이 LFS에 저장되어 있는지 확인하기 위해 CI 프로세스를 시작할 때 간단한 검사를 설정했다.
lfs-check:
only:
refs:
- merge_requests
script:
- git lfs install
- git add --renormalize -u
- |
if ! git diff --cached --name-only --exit-code ; then
echo
echo
echo "=============================="
echo "# Please renormalize files #"
echo "=============================="
echo
echo "git add -u --renormalize"
echo "git commit --amend"
exit 1
fi
사람들이 잘못된 방식으로 파일을 전송할 때 CI는 실패하고 정보 오류와 명령이 발생합니다.제출해야 함
일정 시간마다 코드를 변경해서 변경 전의 코드를 실행할 수 없거나 상관없게 합니다.이런 상황이 발생한 원인은 매우 많다.다음은 몇 가지 예입니다.
이 목표를 실현하기 위해서, 우리는 CI에 필요한 제출 메커니즘을 만들었다.CI 작업을 수행하려면 제출이 현재 제출된 선조여야 합니다.그렇지 않으면 CI가 실패하고 설명 오류와 문제 해결에 대한 설명이 나타납니다.
새로운 필수 제출이 있으면, 모든 개발자에게 알리고, CI를 업데이트해서 일치하도록 합니다.이것은 개발자가 슬랙의 통지를 놓치더라도 CI는 그들에게 무엇을 해야 하는지 알게 할 것이다.
솔루션에는 다음과 같은 간단한 CI 작업이 포함됩니다.
required-commit:
only:
refs:
- merge_requests
script:
- apt-get update
- |
if ! git merge-base --is-ancestor ${REQUIRED_COMMIT:-HEAD} HEAD ; then
echo
echo
echo "============================="
echo "# Rebase Required #"
echo "============================="
echo
echo "Your base commit is out of date."
echo "Please update to ${REQUIRED_COMMIT} or later."
echo "The easiest fix is to rebase-onto or merge-from origin/main."
echo
echo
exit 1
fi
CI 설정에 정의된 사용자 정의 변수(참조Create a custom variable in the UI:작업 Docker 이미지를 조건부로 구성
일부 코드는 Docker 이미지를 통해 배치됩니다.따라서 CI가 이러한 이미지를 구축하고 테스트할 수 있기를 바랍니다.일부 테스트는 Docker 용기를 실행하고 통신해야 하지만, 일부 테스트 (특히 단원 테스트와 통합 테스트) 는 상기 용기에서 실행하기 쉽다.후자에 적응하기 위해서, 우리는 Docker 이미지를 CI 테스트 작업의 기초 이미지로 사용합니다.
이것은 CI에서 쉽게 할 수 있다.그러나 우리의 예에서 Docker 이미지를 구축하는 데는 시간이 오래 걸린다.이 시간을 줄이기 위해 구축은 두 부분으로 나뉜다.첫 번째 단계-긴 컴파일 단계로 변경이 적은 코드를 구축한다.둘째, 빠르게 변화하는 파이썬 코드와 모든 관련 의존항을 설치합니다.
우리가 구축한 신속한 변화 부분과 아주 적은 변화 부분 간의 차이를 알아차리고 우리는 이를 둘로 나누어 첫 번째 부분에 실제 변화가 발생할 때만 첫 번째 부분을 구축하기로 결정했다.
그러나 이를 위해서는 상반부에 Docker 이미지를 조건부로 구축하고 하반부에 이전에 존재했던 상반부나 새로 구축된 상반부를 사용해야 한다.
솔루션 - 구축, 에이전트, 프로모션
우리의 해결 방안은 여러 개의 CI 작업으로 구성된 모델을 사용하여 서로 다른 부품을 처리한다.
구축 작업-docker 이미지 구축을 책임진다.조건부로(제1부분) 또는 일치적으로(제2부분).
프록시 작업 - 다음 작업에 Docker 이미지와 관련된 태그
:latest
또는 현재 커밋을 제공하는 구성 작업을 처리하는 조건입니다.홍보 - 새로 만든 이미지를
:latest
에 표시하고 추진하는 것을 책임진다.그들은 맨 마지막에 달렸다.관련 태그를 생성하는 프록시 작업
빠르게 변화하는 코드를 구축하고 설치하는 데 사용되는 Build job
테스트 작업, 새로 생성된 코드 테스트에 사용
업그레이드 작업, 테스트가 통과된 경우
:latest
이를 실현하기 위해 저희는 다음과 같은 .yml
설정을 만들었습니다. 에이전트 업그레이드 모델을 구축하고 include:file
를 사용하여 저희.gitlab-ci.yml
에 도입했습니다.# This file allows creating a prebuild-proxy-(build)-promote workflow with ease.
#
# The idea is that that in the prebuild step we build less-frequently-changed
# docker images than in the build step. This allows us to significantly speed
# up CI times.
#
# Setting Up
# ==========
#
# A basic setup consists of the following:
#
# 1\. Prebuild (extends .bpp:build) - build docker images if relevant files changed
# 2\. Proxy (extends .bpp:proxy) - allows the rest of the CI to know whether Prebuild created new images or not
# 3\. Build [Optional] (extends .bpp:build) - builds extra, more-frequently-changing images.
# This is not a conditional step!
# 4\. Use (custom step) - here we actually use the images we created!
# 5\. Promote (extends .bpp:promote) - if required, pushes the newly built images to the project's repository.
#
# These 5 steps should be in 5 different, consecutive stages for things to work.
# The prebuild step, being conditional, should not have any other step requiring it.
# All other steps (that need the prebuilt images) should require the proxy step instead,
# and use the ${PROXY_TAG} to as a label to the relevant docker images.
.bpp:build:
variables:
# The names of all the docker images we want to pull from our registry
TO_PULL: ""
# The tag to use for pulling the images. This will usually be ${PROXY_TAG}
PULL_TAG: ""
# The name of the image and path of the dockerfile for building docker images.
# The root path for the dockers will be the root of the project
# Format the variable as follows:
#
# >-
# "some_name the/relevant/path/Dockerfile"
# "some_other_name another/relevant/path/Dockerfile"
#
# Note that the quotes are significant!
TO_BUILD: ""
# The names of the images we want to push.
# They will all be pushed with the ${CI_COMMIT_SHA} tag.
TO_PUSH: ""
script:
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY_IMAGE}
- export DOCKER_BUILDKIT=1 # This cannot be in the `variables` field since users overwrite it.
- |
for IMAGE_NAME in ${TO_PULL}
do
echo "***********************************"
echo "Pulling ${IMAGE_NAME}"
echo "-----------------------------------"
echo "docker pull ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${PULL_TAG}"
echo "DOCKER_BUILDKIT=1 docker tag \
${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${PULL_TAG} \
${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest"
echo "***********************************"
docker pull ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${PULL_TAG}
docker tag \
${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${PULL_TAG} \
${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest
done
- |
eval "ARRAY=($TO_BUILD)"
for ITEM in "${ARRAY[@]}"
do
MY_NAME=${ITEM% *}
MY_PATH=${ITEM#* }
echo "***********************************"
echo "Building ${MY_NAME} from ${MY_PATH}"
echo "-----------------------------------"
echo "DOCKER_BUILDKIT=1 docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
-t ${CI_REGISTRY_IMAGE}/${MY_NAME} \
-t ${CI_REGISTRY_IMAGE}/${MY_NAME}:${CI_COMMIT_SHA} \
-f ${MY_PATH} \
--label "commit_sha=${CI_COMMIT_SHA}" \
."
echo "***********************************"
docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
-t ${CI_REGISTRY_IMAGE}/${MY_NAME} \
-t ${CI_REGISTRY_IMAGE}/${MY_NAME}:${CI_COMMIT_SHA} \
-f ${MY_PATH} \
--label "commit_sha=${CI_COMMIT_SHA}" \
.
done
- |
for IMAGE_NAME in $TO_PUSH
do
echo "***********************************"
echo "Pushing ${IMAGE_NAME}"
echo "-----------------------------------"
echo "DOCKER_BUILDKIT=1 docker push ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_COMMIT_SHA}"
echo "***********************************"
docker push ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_COMMIT_SHA}
done
.bpp:proxy:
variables:
# The names of jobs we want to proxy - if any of them succeeded, we proxy.
BUILD_JOBS: ""
script:
- PROXY_TAG=latest
- apt-get -qq update
- apt-get -qq install jq
# Get the successful jobs for the current pipeline
- >-
curl
--header "PRIVATE-TOKEN:${GITLAB_TOKEN}"
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs?scope[]=success"
> jobs.json
# Compare the job names from the pipeline with the provided job names
- EXECUTED=$(comm -12 <(jq -r '.[].name' jobs.json | sort) <(echo ${BUILD_JOBS} | tr ' ' '\n' | sort))
# If a build job was executed, we need to set the proxy tag to the current commit sha.
- |
if [ ! -z "$EXECUTED" ]
then
PROXY_TAG=${CI_COMMIT_SHA}
fi
- echo "PROXY_TAG=${PROXY_TAG}" >> deploy.env
# Print out the proxy tag - for debug purposes
- echo "PROXY_TAG=${PROXY_TAG}"
artifacts:
# To get the proxy tag, you need to get the artifacts from this job.
# The proxy tag will be ${PROXY_TAG}
reports:
dotenv: deploy.env
.bpp:promote:
variables:
# The names of the images you wish to promote.
# They need to have been built & pushed by a previous build step.
TO_PROMOTE: ""
script:
- |
if [ "${PROXY_TAG}" = "latest" ]; then
echo "Nothing to promote."
else
echo "Promoting docker image."
docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY_IMAGE}
for IMAGE in ${TO_PROMOTE} ; do
docker pull ${CI_REGISTRY_IMAGE}/${IMAGE}:${CI_COMMIT_SHA}
docker tag ${CI_REGISTRY_IMAGE}/${IMAGE}:${CI_COMMIT_SHA} ${CI_REGISTRY_IMAGE}/${IMAGE}:latest
docker push ${CI_REGISTRY_IMAGE}/${IMAGE}:latest
done
fi
Reference
이 문제에 관하여(GitLab CI 기술), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tmr232/gitlab-ci-tricks-12cc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)