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
- определяет, включать ли job в pipeline, а не просто пропускать ее во время выполнения.
Ручной запуск 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 = один ресурс, который нельзя изменять одновременно.
Artifacts
Пример gitlab-ci.yml:
stages:
- build
- test
build:
stage: build
image: python:3.13
script:
- echo "hello" > result.txt
test:
stage: test
image: python:3.13
script:
- cat result.txt
Сможет ли test прочитать файл result.txt
Не сможет, потому что мы не указали GitLab, что этот файл нужно сохранить как артефакт.
Когда build завершится, созданный внутри него файл автоматически не попадет в контейнер test
Чтобы передать файл, нужно явно указать artifacts
Пример:
stages:
- build
- test
build:
stage: build
image: python:3.13
script:
- echo "hello" > result.txt
artifacts:
paths:
- result.txt
test:
stage: test
image: python:3.13
script:
- cat result.txt
- Runner выполняет
buildи создаетresult.txt - После успешного выполнения Runner загружает указанный артефакт в хранилище GitLab CI/CD
- При запуске
testRunner скачивает артефакт предыдущей стадии - Команда
cat result.txtвыводитhello
Запомни
стадии определяют порядок выполнения, а artifacts позволяют сохранять результаты jpbs и передавать их дальше.
dependecies
Пример:
stages:
- build
- test
build:
stage: build
image: python:3.13
script:
- echo "hello" > result.txt
artifacts:
paths:
- result.txt
test:
stage: test
dependencies: []
script:
- cat result.txt
dependencies: [] означает, что job не будет скачивать артефакты предыдущих jobs.
Есть три варианта:
| Конфигурация | Поведение |
|---|---|
artifacts: path: |
Сохранить файлы после job |
dependencies: [build] |
Скачать артефакты job build |
dependencies: [] |
Не скачивать артефакты |
needs
- возможность запускать jobs, не дожидаясь завершения всей предыдущей стадии.
Разберем разницу
- stages - порядок стадий
По умолчанию GitLab ждет завершения всех jobs стадии build, прежде чем запускать jobs стадии test
- needs - зависимость между конкретными jobs
Здесь test ждет завершения конкретной job build а не всей стадии build
Если в build есть еще пять jobs, test может стартовать, пока они продолжают работать.
- dependencies - получение артефактов
dependencies определяет, из каких предыдущих jobs скачивать артефакты, но не позволяет запускать job раньше, чем это допускает порядок стадий.
Последняя проверка 12.10.2026