Pipeline
Типы pipeline
Merge request pipelines
Описание
Запускается в момент создания merge requests. Обычно используется для проверяющего merge requests чтобы определить тесты кода прошли успешно или нет
Условия запуска pipeline:
- в CI/CD указан rules CI_PIPELINE_SOURCE == "merge_request_event"
- у вас есть права Developer, Maintainer or Owner роль
.gitlab-ci.yml
stages:
- test
testyrovanie:
stage: test
script:
- echo "test"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
tags:
- shell
Пример с child pipeline
.gitlab-ci.yml
stages:
- test
- build
- trigger
django tests:
image: python:3.9-alpine
stage: test
script:
- pip install -r requirements.txt
- mkdir db
- python manage.py test
tags:
- docker_test
build docker:
stage: build
image: docker:stable
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_TLS_CERTDIR: ""
script:
- docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
- docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} .
- if [[ "${CI_COMMIT_BRANCH}" == "${CI_DEFAULT_BRANCH}" ]] ; then
docker tag ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} ${CI_REGISTRY_IMAGE}:latest;
docker push ${CI_REGISTRY_IMAGE}:latest; fi
- if [[ -z "${CI_COMMIT_TAG}" ]] ; then
docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG};
else
docker tag ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG} ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG};
docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}; fi
needs:
- ["django tests"]
tags:
- docker_test
start cd pipeline:
stage: trigger
trigger:
include:
- local: .gitlab/deploy.yml
strategy: depend
.gitlab/deploy.md
stages:
- deploy
deploy to prod:
stage: deploy
script:
- docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
- docker pull ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
- docker rm -f ${CI_PROJECT_NAME} || true
- docker run --name ${CI_PROJECT_NAME} -d -p 80:8000 -v db:/app/db ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
tags:
- shell
результат
Пример production pipeline
.gitlab-ci.yml
stages:
- build
- deploy
build_image:
image: docker:29.0.1-cli
services:
- docker:29.0.1-dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
stage: build
script:
- echo "$CI_REGISTRY_PASSWORD" |
docker login
--username "$CI_REGISTRY_USER"
--password-stdin
"$CI_REGISTRY"
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
tags:
- docker_test
deploy_compose:
stage: deploy
resource_group: production
needs:
- build_image
variables:
IMAGE_TAG: "$CI_COMMIT_SHA"
before_script:
- docker info
- echo "$CI_REGISTRY_PASSWORD" |
docker login
--username "$CI_REGISTRY_USER"
--password-stdin
"$CI_REGISTRY"
script:
- |
TOKEN=$CI_JOB_TOKEN
ssh "$PROD_USER@$PROD_HOST" \
"docker login \
-u '$CI_REGISTRY_USER' \
-p '$TOKEN' \
'$CI_REGISTRY'"
- |
scp -r * $PROD_USER@$PROD_HOST:/opt/nginx/
ssh "$PROD_USER@$PROD_HOST" "
cd /opt/nginx
cd for_test
docker compose pull
docker compose up -d
"
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
when: manual
tags:
- shell
Rules
Ручной запуск deply на PROD
Пример файла .gitlab-ci.yml
deploy to prod:
stage: deploy
script:
- docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY}
- docker pull ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
- docker rm -f ${CI_PROJECT_NAME} || true
- docker run --name ${CI_PROJECT_NAME} -d -p 80:8000 -v db:/app/db ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
rules:
- when: manual
tags:
- shell
Правила для запуска по определенной ветке
Используется когда вам нужно запускать pipeline при коммите в определенную ветку
Пример 1:
stages:
- primer
rules_on_one_job:
stage: primer
script:
- |
if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
echo "Pipeline run for head branch"
elif [ "$CI_COMMIT_BRANCH" = "devel" ]; then
echo "Pipeline run for branch: devel"
else
echo "Pipeline run for other branch: $CI_COMMIT_BRANCH"
fi
tags:
- shell
Пример 2:
stages:
- primer
- primer_sec
rules_branch:
stage: primer
script:
- echo "run job commit in main branch"
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
tags:
- shell
rules_2_branch:
stage: primer_sec
script:
- echo "run job commit in '$CI_COMMIT_BRANCH' branch"
rules:
- if: '$CI_COMMIT_BRANCH == "devel"'
tags:
- shell
Запуск по тегу
Запускается только когда есть Tag
Пример файла .gitlab-ci.yml
stages:
- debug
rules_on_one_job:
stage: debug
script:
- echo "create tag"
rules:
- if: '$CI_COMMIT_TAG'
tags:
- shell
Resource group
Описание
механизм GitLab, который не позволяет двум job одновременно работать с одним ресурсом.
Используется для операций, изменяющих состояние инфраструктуры (deploy, миграции БД, terraform, обновление серверов, ...).
Не применяется для независимых задач (bild, test, lint, анализ кода, ...), которые могут выполняться безопасно параллельно.
Ресурсом может быть:
- production сервер
- staging сервер
- кастер Kubernetes
- любое окружение которое нельзя одновременно изменять.
Когда используется:
- когда нужно защитить ресурсы от параллельного выполнения одной и той же job.
Пример:
deploy:
stage: deploy
resource_group: production
script:
- docker compose pull
- docker compose up -d
Что получается?
- теперь даже если кто-то одновременно с вами запушит свой код и оба pipeline запустятся одновременно, то ранняя job будет выполняться, а вторая будет ждать пока освободятся ресурсы
в итоге вторая job встает на паузу с сообщением: Waiting for resource
а как же manual?
manual не защищает от одновременного выполнения, так как если вы обе job запустите вручную, без resource_group они будут работать параллельно.
Какие бывают resource_group?
название может быть любое (по желанию разработчика).
Главное правило: один resource_group = один ресурс, который нельзя изменять одновременно.