gitlab что такое pipeline
GitLab CI для непрерывной интеграции и доставки в production. Часть 1: наш пайплайн
Итак, GitLab CI: что можно ещё рассказать о нём? На хабре уже есть статьи про установку, про настройку раннеров, про командное использование, про GitLab Flow. Пожалуй, не хватает описаний того, как используется GitLab CI в реальном проекте, где задействовано несколько команд. А в современном мире разработки ПО это действительно так: ведь есть (как минимум) разработчики, тестировщики, DevOps- и релиз-инженеры. С подобным разделением на команды мы работаем уже несколько лет. В этой статье я расскажу о том, как мы, используя и улучшая возможности GitLab CI, реализовали и применяем в production для коллектива из нескольких команд процессы непрерывной интеграции (CI) и отчасти доставки приложений (CD).
Наш пайплайн
Если вы сталкивались с CI-системами ранее, то понятие пайплайна вам знакомо — это последовательность выполнения стадий (здесь и далее в статье для термина stage использую перевод «стадия»), каждая из которых включает несколько задач (здесь и далее в статье job — «задача»). От момента внесения изменений в код до выката в production приложение по очереди оказывается в руках разных команд — подобному тому, как это происходит на конвейере. Отсюда и возник термин pipeline («конвейер» — один из вариантов дословного перевода). В нашем случае это выглядит так:
Краткие пояснения по используемым стадиям:
Как это используется?
Начну с рассказа о пайплайне с точки зрения его использования — то, что можно назвать user story. Тут выяснится, что на самом деле пайплайна у нас даже два: укороченный для веток и полноценный для тегов. И вот как выглядят эти последовательности:
Пайплайн и стадии в деталях
Задачи на стадии build собирают приложение. Для этого мы используем свою разработку — Open Source-утилиту dapp (о её основных возможностях читайте и смотрите в этой статье + видео), которая хорошо ускоряет инкрементальную сборку. Поэтому сборка запускается автоматически для веток с префиксами feature_ (код приложения), infra_ (код инфраструктуры) и тегов, а не только для нескольких традиционно «главных» веток (master/develop/production/release).
Обновлено 06 сентября 2019 г.: в настоящее время проект dapp переименован в werf, его код переписан на Go, а документация значительно улучшена.
Следующая стадия — staging — это набор сред для разработчиков, DevOps-инженеров и тестировщиков. Здесь объявлено несколько задач, разворачивающих приложения из веток с префиксами feature_ и infra_ в урезанных средах для быстрого тестирования новой функциональности или инфраструктурных изменений (код сборки приложения хранится в репозитории приложения).
Стадии pre-production и production доступны только для тегов. Обычно тег вешается после того, как релиз-инженеры принимают несколько merge-запросов из протестированных веток. В целом можно сказать, что мы используем GitLab Flow с тем лишь отличием, что нет автоматического развёртывания на production и потому нет отдельных веток, а используются теги.
Стадия approve — это две задачи: approve и not approve. Первая включает возможность развёртывания на production, вторая — выключает. Эти задачи существуют для того, чтобы в случае проблем на production было видно, что развёртывание происходило не просто так, а с согласия релиз-инженера. Однако суть не в лишении кого-то премии, а в том, что непосредственно развёртывание на production проводит зачастую не сам релиз-инженер, а команда DevOps. Релиз-инженер, запуская задачу approve, разрешает тем самым «нажать на кнопку» deploy to production команде DevOps. Можно сказать, что эта стадия выносит на поверхность то, что могло бы остаться в почтовой переписке или в устной форме.
Такая схема взаимодействия хорошо себя показала в работе, однако пришлось потрудиться, чтобы реализовать её. Как оказалось, GitLab CI не поддерживает из коробки некоторые нужные вещи…
Всё довольно просто и скорее всего понятно. Для каждой задачи используются следующие директивы:
Он демонстрирует возможность формата YAML определять общие блоки и подключать их в нужное место на нужном уровне. Подробнее см. в документации.
Таким образом, задачи на стадиях build, testing, staging, pre-production, которые должны быть доступны для веток infra_, feature_ и тегов, принимают следующий вид:
А задачи на стадиях approve и production, которые доступны только для тегов, имеют такой вид:
Что дальше?
Полная реализация задуманного стала возможной только благодаря нескольким патчам к GitLab и использованию артефактов задач. Подробнее об этом читайте в следующей части статьи: «GitLab CI для непрерывной интеграции и доставки в production. Часть 2: преодолевая трудности».
CI/CD pipelines
Pipelines are the top-level component of continuous integration, delivery, and deployment.
Jobs are executed by runners. Multiple jobs in the same stage are executed in parallel, if there are enough concurrent runners.
If all jobs in a stage succeed, the pipeline moves on to the next stage.
If any job in a stage fails, the next stage is not (usually) executed and the pipeline ends early.
In general, pipelines are executed automatically and require no intervention once created. However, there are also times when you can manually interact with a pipeline.
Types of pipelines
Configure a pipeline
For a list of configuration options in the CI pipeline file, see the GitLab CI/CD Pipeline Configuration Reference.
Ref specs for runners
When a runner picks a pipeline job, GitLab provides that job’s metadata. This includes the Git refspecs, which indicate which ref (branch, tag, and so on) and commit (SHA1) are checked out from your project repository.
This table lists the refspecs injected for each pipeline type:
Pipeline type | Refspecs |
---|---|
pipeline for branches | + :refs/pipelines/ and +refs/heads/ :refs/remotes/origin/ |
pipeline for tags | + :refs/pipelines/ and +refs/tags/ :refs/tags/ |
pipeline for merge requests | + :refs/pipelines/ |
The refs refs/heads/ and refs/tags/ exist in your project repository. GitLab generates the special ref refs/pipelines/ during a running pipeline job. This ref can be created even after the associated branch or tag has been deleted. It’s therefore useful in some features such as automatically stopping an environment, and merge trains that might run pipelines after branch deletion.
View pipelines
You can find the current and historical pipeline runs under your project’s CI/CD > Pipelines page. You can also access pipelines for a merge request by navigating to its Pipelines tab.
Click a pipeline to open the Pipeline Details page and show the jobs that were run for that pipeline. From here you can cancel a running pipeline, retry jobs on a failed pipeline, or delete a pipeline.
Starting in GitLab 14.2, you can change the pipeline column to display the pipeline ID or the pipeline IID.
If you use VS Code to edit your GitLab CI/CD configuration, the GitLab Workflow VS Code extension helps you validate your configuration and view your pipeline status.
Run a pipeline manually
Pipelines can be manually executed, with predefined or manually-specified variables.
You might do this if the results of a pipeline (for example, a code build) are required outside the normal operation of the pipeline.
The pipeline now executes the jobs as configured.
Prefill variables in manual pipelines
You can use the value and description keywords to define pipeline-level (global) variables that are prefilled when running a pipeline manually.
The description is displayed next to the variable. It can be used to explain what the variable is used for, what the acceptable values are, and so on:
You cannot set job-level variables to be pre-filled when you run a pipeline manually.
Run a pipeline by using a URL query string
The format of the pipelines/new URL is:
Add manual interaction to your pipeline
Manual jobs, allow you to require manual interaction before moving forward in the pipeline.
You can do this straight from the pipeline graph. Just click the play button to execute that particular job.
For example, your pipeline can start automatically, but require a manual action to deploy to production. In the example below, the production stage has a job with a manual action:
Start multiple manual actions in a stage
Multiple manual actions in a single stage can be started at the same time using the “Play all manual” button. After you click this button, each individual manual action is triggered and refreshed to an updated status.
Skip a pipeline
Alternatively, if you are using Git 2.10 or later, use the ci.skip Git push option. The ci.skip push option does not skip merge request pipelines.
Delete a pipeline
Users with the Owner role in a project can delete a pipeline by clicking on the pipeline in the CI/CD > Pipelines to get to the Pipeline Details page, then using the Delete button.
Pipeline quotas
Each user has a personal pipeline quota that tracks the usage of shared runners in all personal projects. Each group has a usage quota that tracks the usage of shared runners for all projects created within the group.
When a pipeline is triggered, regardless of who triggered it, the pipeline quota for the project owner’s namespace is used. In this case, the namespace can be the user or group that owns the project.
How pipeline duration is calculated
Total running time for a given pipeline excludes retries and pending (queued) time.
Visually, it can be viewed as:
The union of A, B, and C is (1, 4) and (6, 7). Therefore, the total running time is:
How pipeline quota usage is calculated
Pipeline quota usage is calculated as the sum of the duration of each individual job. This is slightly different to how pipeline duration is calculated. Pipeline quota usage doesn’t consider any overlap of jobs running in parallel.
The pipeline quota usage is the sum of each job’s duration. In this example, 8 runner minutes would be used, calculated as: 3 + 3 + 2.
Pipeline security on protected branches
A strict security model is enforced when pipelines are executed on protected branches.
Variables marked as protected are accessible only to jobs that run on protected branches, preventing untrusted users getting unintended access to sensitive information like deployment credentials and tokens.
Runners marked as protected can run jobs only on protected branches, preventing untrusted code from executing on the protected runner and preserving deployment keys and other credentials from being unintentionally accessed. In order to ensure that jobs intended to be executed on protected runners do not use regular runners, they must be tagged accordingly.
Visualize pipelines
Pipelines can be complex structures with many sequential and parallel jobs.
To make it easier to understand the flow of a pipeline, GitLab has pipeline graphs for viewing pipelines and their statuses.
Pipeline graphs can be displayed as a large graph or a miniature representation, depending on the page you access the graph from.
GitLab capitalizes the stages’ names in the pipeline graphs.
View full pipeline graph
The pipeline details page displays the full pipeline graph of all the jobs in the pipeline.
You can group the jobs by:
Stage, which arranges jobs in the same stage together in the same column:
Job dependencies, which arranges jobs based on their needs dependencies.
Multi-project pipeline graphs help you visualize the entire pipeline, including all cross-project inter-dependencies.
View job dependencies in the pipeline graph
You can arrange jobs in the pipeline graph based on their needs dependencies.
Jobs in the leftmost column run first, and jobs that depend on them are grouped in the next columns.
For example, test-job1 depends only on jobs in the first column, so it displays in the second column from the left. deploy-job1 depends on jobs in both the first and second column and displays in the third column:
To add lines that show the needs relationships between jobs, select the Show dependencies toggle. These lines are similar to the needs visualization:
To see the full needs dependency tree for a job, hover over it:
Pipeline mini graphs
Pipeline mini graphs allow you to see all related jobs for a single commit and the net result of each stage of your pipeline. This allows you to quickly see what failed and fix it.
Pipeline mini graphs only display jobs by stage.
Stages in pipeline mini graphs are collapsible. Hover your mouse over them and click to expand their jobs.
Mini graph | Mini graph expanded |
---|---|
Pipeline success and duration charts
Pipeline analytics are available on the CI/CD Analytics page.
Pipeline badges
Pipeline status and test coverage report badges are available and configurable for each project. For information on adding pipeline badges to projects, see Pipeline badges.
Pipelines API
Руководство по CI/CD в GitLab для (почти) абсолютного новичка
Категории
Свежие записи
Наши услуги
Или как обзавестись красивыми бейджиками для своего проекта за один вечер ненапряжного кодинга
Наверное, у каждого разработчика, имеющего хотя бы один пет-проект, в определённый момент возникает зуд на тему красивых бейджиков со статусами, покрытием кода, версиями пакетов в nuget… И меня этот зуд привёл к написанию этой статьи. В процессе подготовки к её написанию я обзавёлся вот такой красотой в одном из своих проектов:
В качестве среды разработки использовалась VS Code c расширением GitLab Workflow (для валидации файла настроек прямо из среды разработки).
Краткое введение
CD — это когда ты только пушнул, а у клиента уже всё упало?
Таким образом, имеем:
Соответственно, задача при настройке CI/CD сводится к тому, чтобы создать набор задач, реализующих все необходимые действия для сборки, тестирования и публикации кода и артефактов.
Перед началом: почему?
Потому, что когда появилась необходимость создать приватные репозитории под пет-проекты, на GitHub’e они были платными, а я — жадным. Репозитории стали бесплатными, но пока это не является для меня поводом достаточным переезжать на GitHub.
Потому что там настройка элементарная — даже не требуются знания командной строки. Интеграция с внешними провайдерами git — в пару кликов, импорт SSH-ключей для отправки коммитов в репозиторий — тоже, пайплайн легко настраивается даже не из шаблона.
Исходная позиция: что имеется и чего хочется
Описанные требования органично ложатся на следующую модель пайплайна:
Собираем конфигурацию
Готовим аккаунты
Создаём новый проект
Переходим в Atrifacts, жмём Create feed
Жмём Connect to feed, выбираем Visual Studio, из блока Machine Setup копируем Source
Идём в настройки аккаунта, выбираем Personal Access Token
Создаём новый токен доступа
Копируем созданный токен — после закрытия модального окна значение будет недоступно
Заходим в настройки репозитория в GitLab, выбираем настройки CI/CD
Раскрываем блок Variables, добавляем новую
На этом предварительная настройка завершена.
Готовим каркас конфигурации
Теперь при запуске пайплайна с хранилища образов Microsoft будет скачан указанный образ, в котором и будут исполняться все задачи из конфигурации.
Следующий этап — добавить stage‘ы. По умолчанию GitLab определяет 5 этапов:
Ничего не мешает объявить их явно, впрочем. Порядок, в котором указаны этапы, влияет на порядок, в котором они выполняются. Для полноты изложения, добавим в конфигурацию:
Для отладки имеет смысл получить информацию об окружении, в котором исполняются задачи. Добавим глобальный набор команд, который будет выполняться перед каждой задачей, с помощью before_script :
Осталось добавить хотя бы одну задачу, чтобы при отправке коммитов пайплайн запустился. Пока что добавим пустую задачу для демонстрации:
Всё логично — по умолчанию runner’ы (отвечающие за исполнение скриптов задач, и предоставляемые GitLab’ом) используют bash для исполнения команд. Можно исправить это дело, явно указав в описании задачи, какие теги должны быть у исполняющего пайплайн раннера:
Отлично! Теперь пайплайн выполняется.
Продолжим создание скелета конфигурации, добавив все задачи, описанные выше:
Получили не особенно функциональный, но тем не менее корректный пайплайн.
Настройка триггеров
Из-за того, что ни для одной из задач не указаны фильтры срабатывания, пайплайн будет полностью исполняться при каждой отправке коммитов в репозиторий. Так как это не является желаемым поведением в общем случае, мы настроим фильтры срабатывания для задач.
Вспомним набор требований — сборка и тестирование только для merge request, упаковка и отправка в Azure DevOps — для merge request и пушей в мастер, генерация документации — для пушей в мастер.
Для начала настроим задачу сборки кода, добавив правило срабатывания только при merge request:
Теперь настроим задачу упаковки на срабатывания на merge request и добавление коммитов в мастер:
Как видно, всё просто и прямолинейно.
Также можно настроить задачу на срабатывание только если создан merge request с определённой целевой или исходной веткой:
Настройка сохранения артефактов
Во время выполнения задачи build job у нас будут созданы артефакты сборки, которые можно переиспользовать в последующих задачах. Для этого нужно в конфигурацию задачи добавить пути, файлы по которым нужно будет сохранить и переиспользовать в следующих задачах, в ключ artifacts :
Пути поддерживают wildcards, что определённо упрощает их задание.
Если задача создаёт артефакты, то каждая последующая задача сможет их получить к ним доступ — они будут располагаться по тем же путям относительно корня репозитория, по которым были собраны из исходной задачи. Так же артефакты доступны для скачивания на сайте.
Теперь, когда у нас готов (и проверен) каркас конфигурации, можно переходить собственно к написанию скриптов для задач.
Пишем скрипты
Естественно, есть некоторые нюансы, из-за которых мы несколько усложним команды.
Собираем данные покрытия кода
Coverlet после запуска тестов выводит в консоль статистику по запуску:
GitLab позволяет указать регулярное выражение для получения статистики, которую потом можно получить в виде бейджа. Регулярное выражение указывается в настройках задачи с ключом coverage ; в выражении должна присутствовать capture-группа, значение которой и будет передано в бейдж:
Здесь мы получаем статистику из строки с общим покрытием по линиям.
Публикуем пакеты и документацию
Оба действия у нас назначены на последний этап пайплайна — раз уж сборка и тесты прошли, можно и поделиться с миром наработками.
Для начала рассмотрим публикацию в источник пакетов:
Если в проекте не присутствует файл конфигурации nuget ( nuget.config ), создадим новый: dotnet new nugetconfig
Зачем: в образе может быть запрещён доступ на запись к глобальным (пользовательской и машинной) конфигурациям. Чтобы не ловить ошибки, просто создадим новую локальную конфигурацию и будем работать с ней.
Теперь настроим создание документации:
Лирическое отступление про docfx
Раньше при настройке проекта я указывал источник кода для документации как файл решения. Основной минус — документация создаётся и для тестовых проектов. В случае, если это не нужно, можно задать такое значение узлу metadata.src :
Промежуточный итог
Вот такую простую конфигурацию можно составить буквально за полчаса и пару чашек кофе, которая позволит при каждом запросе слияния и отправке в мастер проверять, что код собирается и тесты проходят, собирать новый пакет, обновлять документацию и радовать глаз красивыми бейджиками в README проекта.
Кстати о бейджиках
Ради них ведь всё и затевалось!
Бейджи со статусами пайплайна и покрытием кода доступны в GitLab в настройках CI/CD в блоке Gtntral pipelines:
Бейдж со ссылкой на документацию я создавал на платформе Shields.io — там всё достаточно прямолинейно, можно создать свой бейдж и получать его с помощью запроса.
Azure DevOps Artifacts также позволяет создавать бейджи для пакетов с указанием актуальной версии. Для этого в источнике на сайте Azure DevOps нужно нажать на Create badge у выбранного пакета и скопировать markdown-разметку:
Добавляем красоты
Выделяем общие фрагменты конфигурации
Во время написания конфигурации и поисков по документации, я наткнулся на интересную возможность YAML — переиспользование фрагментов.
Как видно из настроек задач, все они требуют наличия тега windows у раннера, и срабатывают при отправке в мастер/создании запроса на слияние (кроме документации). Добавим это во фрагмент, который будем переиспользовать:
И теперь в описании задачи можем вставить объявленный ранее фрагмент:
Названия фрагментов должны начинаться с точки, чтобы не быть интерпретированными как задача.
Версионирование пакетов
При создании пакета компилятор проверяет ключи командной строки, и в их отсутствие — файлы проектов; найдя узел Version, он берёт его значение как версию собираемого пакета. Выходит, чтобы собрать пакет с новой версией, нужно либо обновить её в файле проекта, либо передать как аргумент командной строки.
Добавим ещё одну хотелку — пусть младшие два номера в версии будут годом и датой сборки пакета, и добавим пререлизные версии. Добавлять эти данные в файл проекта и проверять перед каждой отправкой можно, конечно — но можно ведь это делать и в пайплайне, собирая версию пакета из контекста и передавая через аргумент командной строки.
Данную задачу решает следующий скрипт:
Добавляем скрипт в задачу pack and deploy job и наблюдаем сборку пакетов строго при наличии заданной строки в сообщении коммита.
Итого
Потратив примерно полчаса-час времени на написание конфигурации, отладку в локальном powershell и, возможно, пару неудачных запусков, мы получили несложную конфигурацию для автоматизации рутинных задач.
automatically detect, build, test, deploy, and monitor your applications
Теперь в планах — сконфигурировать пайплайн для развёртывания приложений в Azure, с использованием Pulumi и автоматическим определением целевого окружения, что будет освещено в следующей статье.
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.