4.8 Git на сервере — GitLab
GitWeb довольно-таки прост. Если вам нужен более современный, полнофункциональный Git-сервер, есть несколько решений с открытым исходным кодом, которые можно использовать. Так как GitLab это один из самых популярных, мы рассмотрим его установку и использование в качестве примера. Это немного сложнее, чем GitWeb, и скорее всего потребует больше обслуживания, но и функциональность гораздо богаче.
Установка
GitLab — это веб-приложение на основе базы данных, так что его установка немного сложней, чем у некоторых других серверов Git. К счастью, этот процесс хорошо документирован и поддерживается. GitLab настоятельно рекомендует установить GitLab на ваш сервер через официальный пакет Omnibus GitLab.
Другие варианты установки:
- GitLab Helm chart для использования с Kubernetes.
- Официальные образы GitLab для использования с Docker.
- Из исходных файлов.
- Облачный провайдер, такой как AWS, Google Cloud Platform, Azure, OpenShift или Digital Ocean.
Для получения дополнительной информации прочтите GitLab Community Edition (CE) readme.
Администрирование
Административный интерфейс GitLab доступен через веб. Просто направьте ваш браузер на имя или IP-адрес хоста, где установлен GitLab, и войдите как администратор. Имя пользователя по умолчанию admin@local.host , пароль по умолчанию 5iveL!fe (вас попросят изменить их при входе). Войдя, нажмите иконку «Административная зона» в меню справа и сверху.

Рисунок 50. Пункт «Административная зона» в меню GitLab
Пользователи
Пользователи в GitLab — это учётные записи, соответствующие людям. Пользовательские учётные записи не очень сложны; в основном это набор персональной информации, прикреплённый к имени. У каждого пользователя есть пространство имён, логически группирующее проекты данного пользователя. Если у пользователя jane есть проект project, адрес этого проекта будет http://server/jane/project .

Рисунок 51. Экран управления пользователями GitLab
Удаление пользователя может быть выполнено двумя способами. «Блокирование» («Blocking») пользователя запрещает ему вход в GitLab, но все данные в его пространстве имен сохраняются, и коммиты, подписанные этим пользователем, будут указывать на его профиль.
«Разрушение» («Destroying») пользователя, с другой стороны, полностью удаляет его из базы данных и файловой системы. Все проекты и данные в его пространстве имен удаляются, как и все принадлежащие ему группы. Конечно, этим более постоянным и разрушительным действием пользуются реже.
Группы
Группы GitLab — это коллекция проектов с указанием того, как пользователи получают к ним доступ. Каждая группа имеет пространство имён проектов (так же как и пользователи), так что если в группе training есть проект materials, его адрес будет http://server/training/materials .

Рисунок 52. Экран управления группами GitLab
Каждая группа связана с пользователями, каждый из которых имеет уровень доступа к проектам группы и к самой группе. Он разнится от «Гостя» («Guest», только проблемы и чат) до «Владельца» («Owner», полный контроль над группой, её членами и проектами). Типы разрешений слишком обширны, чтобы перечислять их здесь, но на экране управления GitLab есть полезная ссылка с описанием.
Проекты
Проект GitLab примерно соответствует одному git-репозиторию. Каждый проект принадлежит одному пространству имён, групповому или пользовательскому. Если проект принадлежит пользователю, владелец контролирует, кто имеет доступ к проекту; если проект принадлежит группе, действуют групповые уровни доступа для пользователей.
Каждый проект также имеет уровень видимости, который контролирует, кто имеет доступ на чтение страниц проекта или репозитория. Если проект Приватный (Private), владелец должен явно дать доступ на чтение отдельным пользователям. Внутренний (Internal) проект виден любому вошедшему пользователю GitLab, а Публичный (Public) проект видим всем. Это относится как к доступу git fetch , так и к доступу к проекту через веб-интерфейс.
Хуки
GitLab включает поддержку хуков (перехватчиков, hooks) на уровне проектов и всей системы. В обоих случаях, когда происходит некоторое событие, сервер GitLab выполняет запрос HTTP POST с осмысленным JSON-содержанием. Это отличный способ соединить ваши git-репозитории и инсталляцию GitLab с автоматикой инфраструктуры разработки, такой как сервера непрерывной интеграции, комнаты чатов или инструменты деплоя.
Базовое использование
Первое, чего вы захотите от GitLab, это создать новый проект. Это достигается нажатием иконки «+» на панели инструментов. Будут запрошены имя проекта, пространство имён, которому он должен принадлежать, и уровень видимости. Большинство из этих настроек можно потом изменить через интерфейс настроек. Нажмите «Создать проект» («Create Project»), чтобы закончить.
Когда проект создан, вы, наверное, захотите соединить его с локальным git-репозиторием. Каждый проект может быть доступен через HTTPS или SSH, каждый из которых может быть использован для указания удалённого репозитория. Адреса (URL) видимы наверху домашней страницы проекта. Для существующего локального репозитория, следующая команда создаст удалённый репозиторий с именем gitlab и размещением на сервере:
$ git remote add gitlab https://server/namespace/project.git
Если у вас нет локального репозитория, можно просто сделать его:
$ git clone https://server/namespace/project.git
Веб-интерфейс даёт доступ к нескольким полезным видам самого репозитория. Домашняя страница каждого проекта показывает недавнюю активность, а ссылки наверху ведут на список файлов проекта и журнала коммитов.
Совместная работа
Самый простой метод совместной работы над проектом GitLab — это выдача другому пользователю прямого доступа на запись (push) в git-репозитории. Вы можете добавить пользователя в проект в разделе «Участники» («Members») настроек проекта, указав уровень доступа (уровни доступа кратко обсуждались в Группы). Получая уровень доступа «Разработчик» («Developer») или выше, пользователь может беспрепятственно отсылать свои коммиты и ветки непосредственно в репозиторий.
Другой, более разобщённый способ совместной работы — использование запросов на слияние (merge requests). Эта возможность позволяет любому пользователю, который видит проект, вносить свой вклад подконтрольным способом. Пользователи с прямым доступом могут просто создать ветку, отослать в неё коммиты и открыть запрос на слияние из их ветки обратно в master или любую другую ветку. Пользователи без доступа на запись могут «форкнуть» репозиторий («fork», создать собственную копию), отправить коммиты в эту копию и открыть запрос на слияние из их форка обратно в основной проект. Эта модель позволяет владельцу полностью контролировать, что попадает в репозиторий и когда, принимая помощь от недоверенных пользователей.
Запросы на слияние и проблемы (issues) это основные единицы долгоживущих дискуссий в GitLab. Каждый запрос на слияние допускает построчное обсуждение предлагаемого изменения (поддерживая облегчённое рецензирование кода), равно как и общее обсуждение. И те и другие могут присваиваться пользователям или организовываться в вехи (milestones).
Мы в основном сосредоточились на частях GitLab, связанных с git, но это — довольно зрелая система, и она предоставляет много других возможностей, помогающих вашей команде работать совместно, например вики-страницы для проектов и инструменты поддержки системы. Одно из преимуществ GitLab в том, что, однажды запустив и настроив сервер, вам редко придётся изменять конфигурацию или заходить на него по SSH; большинство административных и пользовательских действий можно выполнять через веб-браузер.
Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
Рассказываем, как работать с CI/CD. Сравнение инструментов и подробный гайд по сборке и развертыванию через Docker на удаленный сервер с помощью Gitlab CI/CD на примере Spring Boot-приложения.

Привет! Меня зовут Николай, я Backend-разработчик в РЕЛЭКС. В статье ты найдешь полезный теоретический материал и сравнение инструментов CI/CD. Покажу, как настроить сервер и поделюсь полезными командами, которые помогут в работе.
- Начнём с теории: коротко о CI/CD — это база.
- Инструменты работы с CI/CD: выбираем свой.
- Как устроен процесс CI/CD: схема работы.
- Переходим к практике: настройка виртуального сервера.
- Настройка конфига .gitlab-ci.yml.
Начнём с теории: коротко о CI/CD — это база
CI/CD (Continuous Integration / Continuous Deployment) — это непрерывная интеграция и развертывание, предназначенные для повышения удобства, частоты и надежности публикации изменений программного обеспечения или продукта, где:
CI — это практика разработки ПО, при которой изменения в коде автоматически собираются, тестируются и интегрируются в целевую ветку репозитория. Основная идея — минимизация разрыва между компонентами проекта и быстрая обратная связь о качестве кода, благодаря автоматической сборке и тестированию.
CD — это продолжение CI, которое позволяет автоматически разворачивать успешно собранный и протестированный код на сервере или другой среде реального применения. Цель — автоматизация процесса разработки и развертывания приложения или программного продукта после всех этапов проверки и тестирования. Развертывание в продакшн должно выполняться после ручного подтверждения деплоя, чтобы предоставить дополнительный уровень контроля и безопасности.
Инструментов работы с CI/CD огромное множество — самыми популярными считаются:

- Gitlab CI/CD — полностью интегрированная в GitLab система для автоматизации сборки, тестирования и развертывания программного кода. GitLab CI/CD использует файл конфигурации YAML в репозитории проекта для определения правил работы на каждом этапе в пайплайне. Поддерживает использование Docker-образов для определения окружения сборки — отсюда большая гибкость и повторное использование кода.
- Jenkins — система с открытым исходным кодом для внедрения CI/CD для автоматизации процесса разработки. Jenkins — самостоятельное приложение, которое требует настройки на сервере, зато предлагает обширный набор плагинов. Это расширяет его функциональность и интеграцию с другими системами и сервисами.
- Azure DevOps — отдельное комплексное решение от Microsoft с набором инструментов разработки. Оно позволяет командам планировать работу, совместно создавать код и доставлять приложения. Для автоматизации сборки, тестирования и развертывания приложений используется инструмент Azure Pipelines.
- TeamCity — сервер непрерывной интеграции от JetBrains. У TeamCity открытая архитектура, которая позволяет разработчикам создавать плагины для расширения функционала. Некоторые функции бесплатны, но для больших команд и проектов может потребоваться покупка коммерческой лицензии, с чем сейчас возникают сложности.
Выбор инструмента зависит от ваших целей, задач и сложности реализации.
Задача — развернуть Spring Boot-приложение, расположенное в Gitlab-репозитории на продакшн стенде. Сделать это надо с помощью удобного и простого инструмента, чтобы начать использовать его функционал сразу, «из коробки» — Gitlab CI/CD отлично подходит. Он полностью интегрирован со средой Gitlab. Не требует дополнительной установки, а также имеет поддержку и подробную документацию.
С выбором инструмента разобрались. Перейдем к главному: как устроен процесс CI/CD. Ниже — схема его работы.
Как устроен процесс CI/CD: схема работы

Алгоритм схемы следующий:
- Разработчик пишет код и заливает его в GitLab-репозиторий проекта.
- GitLab ищет в корне репозитория конфиг .gitlab-ci.yml и, когда находит, запускает пайплайн согласно описанной в конфиге логике.
Пайплайн (pipeline) представляет собой целиковый процесс из этапов или стадий (stage), которые состоят из задач (job). Каждая задача выполняется в изолированном процессе (используется GitLab Runner).
Что за термины мы описали выше?
- Раннер (gitlab runner) — приложение, в рамках которого выполняются задачи и которое можно развернуть на разных типах систем: Linux, macOS, Windows, Docker, Kubernetes и так далее.
- Задачи (jobs) — «кирпичики», из которых строится процесс CI/CD. Это может быть сборка проекта (компиляция, подтягивание зависимостей) или прогон автотестов, или публикация собранного кода в Docker-репозиторий. По умолчанию задачи выполняются изолированно, но их можно связать между собой при помощи артефактов.
- Артефакты (artifacts) — исполняемые файлы или пакеты для передачи результатов выполнения одной задачи на вход другой. Это позволяет управлять жизненным циклом программного продукта. Пример артефактов — скомпилированные бинарные файлы, архивы, образы контейнеров.
- Этапы (stages) — служат для группировки задач и определения порядка их выполнения. Задачи, принадлежащие одному этапу, выполняются параллельно, если доступно достаточное количество раннеров. Этапы будут выполняться в порядке, указанном в конфиге.
- Пайплайн (pipeline) — верхнеуровневый элемент процесса CI/CD, включающий в себя этапы и задачи.
Переходим от теории к практике. Теперь только пайплайны! Только хардкор!

Переходим к практике: настройка виртуального сервера
Переходим к настройке сервера. Процесс займет не одно действие, поэтому пойдем последовательно, шаг за шагом:
Шаг 1: Установка Docker
Официальный сайт руководства по Docker предоставляет удобный скрипт для неинтерактивной установки Docker. Такой вариант, скорее, подходит для рабочего окружения, а не для продакшена.
С помощью curl-команды скачаем sh-файл для запуска и настройки докера.
curl -fsSL https://get.docker.com -o get-docker.sh
Затем запустим его для установки необходимых зависимостей.
sudo sh ./get-docker.sh
Шаг 2: Скачивание и запуск контейнера GitLab Runner в Docker
В официальном руководстве Gitlab есть описание нескольких вариантов GitLab Runner. В этой статье рассмотрим установку через Docker — более простую для развертывания и версионирования. Также меньше нагружает сервер скачиванием дополнительных пакетов. Для наших целей будем использовать облегченный образ GitLab Runner последней версии:
docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:alpine
После установки можно выполнить команду docker-ps и посмотреть, что появился контейнер с GitLab Runner.
Помимо создания собственных раннеров, которые привязаны к конкретному проекту или группе, в GitLab есть так называемые “Shared runners”, которые доступны для всех проектов в пределах организации или всего инстанса GitLab. Такие раннеры обычно настраиваются администраторами и имеют общую конфигурацию, которую нельзя изменить на уровне отдельного проекта.
Облачная версия gitlab.com предоставляет несколько таких раннеров, которые можно использовать для ваших проектов. Они располагаются в блоке “Shared runners”. Проверьте, чтобы был активен чекбокс “Enable shared runners for this project”.

Шаг 3: Регистрация нового GitLab Runner
— — URL GitLab-сервера, с которым должен связаться Runner.
— — токен для установления связи между Runner и сервером.
Если вы используете свою установку GitLab, то в качестве параметра Runner registration URL, указываете ее URL-адрес. Если используется облачная версия, то https://gitlab.com/.
Чтобы узнать параметр Registration token перейдите в репозиторий проекта, в левой панели откройте меню Settings > CI/CD и разверните секцию Runners. В этой секции, в разделе Project runners, нажмите на троеточие справа от кнопки New project runner, где находится токен.
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:alpine register \ --non-interactive \ --url \ --registration-token \ --executor docker \ --description "Brief description for the project" \ --tag-list "docker" \ --docker-image alpine:latest \ --docker-privileged \ --docker-volumes "/certs/client"
Выполнили команду — переходим во вкладку Runners в настройках CI/CD проекта. Там появится зарегистрированный раннер проекта, готовый к работе.

Шаг 4: Использование Container Registry для сохранения образа приложения
У gitlab есть интегрированный реестр докер-контейнеров (Container Registry). Так, у проекта появляется собственное пространство для хранения докер-образов, которые получили на этапе сборки. Перед использованием реестра контейнеров проверьте, что эта функция включена для вашего проекта. Для это откройте вкладку Visibility, project features, permissions в общих настройках проекта и сделаете чекбокс активным.

Чтобы сохранять и отправлять изображения, нужно пройти аутентификацию в реестре контейнеров. Для аутентификации нужно использовать один из представленных типов:
В примере использовали личный токен доступа. Перейдём в настройки профиля, во вкладку Access token, где нужно выбрать Add new token.
Для всех типов токенов требуется минимальные правила:
- read_registry — доступ на чтение (pull).
- write_registry — доступ на запись (push).

Сохраните в буфер обмена получившийся токен и вставьте его в Docker команду для аутентификации в реестре контейнеров, где:
— — ваше реальное имя пользователя.
Команда выполняется на сервере, где ранее установили Docker, чтобы там взаимодействовать с реестром контейнера
docker login registry.example.com -u -p
Шаг 5: Настройка SSH-ключа
SSH-ключ используется GitLab CI/CD для входа на сервер и выполнения процедуры развертывания. Сгенерируем 4096-разрядный SSH-ключ алгоритмом RSA (пара из открытого и закрытого ключей).
Флаг -C добавляет комментарий для идентификации ключа. В качестве комментария можно указать, например, имя пользователя. подтвердите оба вопроса с помощью Enter.
ssh-keygen -t rsa -b 4096 -C
Чтобы авторизовать публичную часть SSH-ключа, осуществляющего развертывание, добавим её к authorized_keys файлу.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Затем сохраним приватный ключ в GitLab как CI/CD переменную, чтобы сделать его доступным в процессе работы раннера. Для этого выведем содержимое приватного ключа.
cat ~/.ssh/id_rsa
Копируем содержимое ключа в буфер обмена, переходим в настройки CI/CD проекта во вкладку Variable и нажимаем Add variable.

Шаг 6: Определяем оставшиеся переменные окружения CI/CD
Добавим оставшиеся переменные для развертывания приложения на сервере:
SERVER_USER — имя пользователя для подключения к удаленному серверу через SSH. Можете использовать действующего пользователя или создать отдельного в системе.
SERVER_HOST — IP-адрес удаленного сервера для подключения через SSH. Для переменной сделать активной опцию Mask variable
ENV_FILE — путь к файлу с переменными окружения, который будет использован при выполнении команд Docker Compose. Для этого поля поменяете тип с variable на file. В поле для ввода переменные указываются через знак равенства с новой строки.

Таким образом в списке должны отображаться четыре переменные окружения.

На этом все подготовка закончилась. Переходим к настройке конфига .gitlab-ci.yml.
Настройка конфига .gitlab-ci.yml
Файл .gitlab-ci.yml располагается в корне репозитория и определяет структуру пайплайна и логику его работы. Gitlab при каждом поддерживаемом событии (например, push-изменений или создание merge request разработчиком) ищет его и проверяет, есть ли в нем описание для обработки наступившего события.
Ниже — файл .gitlab-ci.yml для сборки и развертывания Spring Boot-приложения в docker-контейнере.
stages: - build - deploy build-only-MR: stage: build tags: - docker image: name: gcr.io/kaniko-project/executor:v1.9.2-debug entrypoint: [ "" ] script: - /kaniko/executor --context "$" --dockerfile "$/Dockerfile" --no-push only: - merge_requests build: stage: build tags: - docker image: name: gcr.io/kaniko-project/executor:v1.9.2-debug entrypoint: [ "" ] script: - /kaniko/executor --context "$" --dockerfile "$/Dockerfile" --destination "$:latest" only: - main deploy: stage: deploy image: docker:20.10-git tags: - gitlab-org-docker variables: DOCKER_HOST: "ssh://$@$" before_script: - mkdir -p ~/.ssh - chmod 700 ~/.ssh - eval $(ssh-agent -s) - echo "$" | tr -d '\r' | ssh-add - - '[[ -f /.dockerenv || -d /run/secrets/kubernetes.io/serviceaccount ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker compose --env-file $ENV_FILE pull - docker compose --env-file $ENV_FILE down --timeout=60 --remove-orphans - docker compose --env-file $ENV_FILE up --build --detach - docker image prune -f || true only: - main when: manual
Пайплайн состоит из двух этапов: сборка и развертывание.
Для этапа сборки написаны две задачи: build-only-MR и build. Обе выполняются на gitlab-runner с тегом Docker, который ранее мы зарегистрировали.
Первая — для сборки проекта только при создании merge request-а. При этом получившийся Docker-образ не сохраняется в реестре контейнеров GitLab.
Вторая задача для сборки проекта при вливании кода в ветку main. Получившийся Docker-образ пушится в реестр контейнеров GitLab с тегом latest.
Для сборки Docker-образов из Dockerfile в директории проекта используется образ Kaniko. Это мощный инструмент для сборки образов Docker, который не требует наличия Docker-демона. Например, внутри своего контейнера или кластера Kubernetes. Использование Kaniko считается более быстрым и безопасным подходом, чем Docker-in-Docker.
Этап развертывания включает в себя одну задачу, которая выполняется на общем раннере с тэгом gitlab-org-docker. Это один из Shared runner, которые предоставляет облачная версия gitlab.com.
Задача использует стандартный Docker-образ версии 20.10-git. В переменных задан путь для подключения к Docker на удаленном сервере через SSH. Переменные окружения SERVER_USER и SERVER_HOST определили ранее, как переменные CI/CD.
В блоке before_script выполняется настройка SSH для безопасного взаимодействия со стендом: создание директории, установка прав доступа для хранения SSH-ключа, инициализация SSH-агента, к которому добавляется приватный ключ из переменной окружения. После чего производится настройка параметров SSH. Затем авторизация в реестре контейнеров с использованием логина и пароля, хранящихся в переменных CI_REGISTRY_USER и CI_REGISTRY_PASSWORD — для получения доступа к собранным Docker-образам.
В блоке scripts подтягиваются обновления для образов с реестра. Затем останавливаются и удаляются текущие контейнеры — начинается запуск контейнеров в фоновом режиме с новыми скачанными образами из реестра. Крайняя команда удаляет все неиспользуемые образы.
Эта задача также выполняется только при вливании кода в ветку main и требует ручного подтверждения для запуска (опция when: manual).
Разворачивать будем REST-приложение на Java. Напишем контроллер, в котором будет один GET-запрос для теста, что приложение развернуто на удаленном сервере, и мы можем к нему обратиться.
Ниже — ключевые файлы, которые мы написали.
Тестовый GET-запрос:
@CrossOrigin @RequestMapping("/test") @RestController public class TestController < @GetMapping("/hello") public ResponseEntitygetTest() < return ResponseEntity.ok("Hello world"); >>
Dockerfile
FROM maven:3.8-openjdk-17-slim RUN mkdir -p /home/app WORKDIR /home/app ADD pom.xml /home/app ADD src /home/app/src RUN mvn clean package CMD ["java", "-jar", "/home/app/target/test-0.0.1-SNAPSHOT.jar"]
docker-compose.yml
version: '3.9' services: core: container_name: spring-application image: registry.gitlab.com/my-test-project6/test-cicd-project:latest environment: TEST_SERVICE_PORT: $ OPEN_API_TITLE: $ ports: - "8081:$" logging: driver: 'json-file' options: max-size: '100m' max-file: '3'
Такой момент: мы используем переменные TEST_SERVICE_PORT — порт, на котором будет запущено приложение в Docker-контейнере и OPEN_API_TITLE — заголовок swagger-а. Прописав переменные в docker-compose-файле, мы указали нашему Java-приложению, что ее можно использовать как значение переменной в конфигурационном файле application.yml.
application.yml
server: port: $ servlet: context-path: /api api: title: $ springdoc: api-docs: path: /doc/api-docs swagger-ui: path: /doc/swagger-ui.html
Когда изменения кода зальются в main-ветку, начнется выполнение задачи build. Как только сборка успешно завершилась, можно деплоить на прод, нажав на значок запуска.

Через пару минут увидим, что приложение успешно прошло сборку и развертывание в Docker-контейнере на удаленном сервере.

Приложение доступно на порту 8081. Мы можем обратиться по API /api/test/hello и увидеть заветную надпись «Hello world». Готово!

Краткие выводы
CI/CD — важная практика разработки программного обеспечения для автоматизации процесса интеграции, тестирования и развертывания кода. Благодаря CI/CD команды разработчиков могут улучшать качество ПО и доставлять новые функции эффективнее и в более короткие сроки.
Приятных «разворачиваний»! Не бойтесь сложностей — это только начало!
Руководство по CI/CD в GitLab для (почти) абсолютного новичка
Наверное, у каждого разработчика, имеющего хотя бы один пет-проект, в определённый момент возникает зуд на тему красивых бейджиков со статусами, покрытием кода, версиями пакетов в nuget… И меня этот зуд привёл к написанию этой статьи. В процессе подготовки к её написанию я обзавёлся вот такой красотой в одном из своих проектов:

В статье будет рассмотрена базовая настройка непрерывной интеграции и поставки для проекта библиотеки классов на .Net Core в GitLab, с публикацией документации в GitLab Pages и отправкой собранных пакетов в приватный фид в Azure DevOps.
В качестве среды разработки использовалась VS Code c расширением GitLab Workflow (для валидации файла настроек прямо из среды разработки).
Краткое введение
CD — это когда ты только пушнул, а у клиента уже всё упало?
Что такое CI/CD и зачем нужно — можно легко нагуглить. Полноценную документацию по настройке пайплайнов в GitLab найти также несложно. Здесь я кратко и по возможности без огрехов опишу процесс работы системы с высоты птичьего полёта:
- разработчик отпраляет коммит в репозиторий, создаёт merge request через сайт, или ещё каким-либо образом явно или неявно запускает пайплайн,
- из конфигурации выбираются все задачи, условия которых позволяют их запустить в данном контексте,
- задачи организуются в соответствии со своими этапами,
- этапы по очереди выполняются — т.е. параллельно выполняются все задачи этого этапа,
- если этап завершается неудачей (т.е. завершается неудачей хотя бы одна из задач этапа) — пайплайн останавливается (почти всегда),
- если все этапы завершены успешно, пайплайн считается успешно прошедшим.
Таким образом, имеем:
- пайплайн — набор задач, организованных в этапы, в котором можно собрать, протестировать, упаковать код, развернуть готовую сборку в облачный сервис, и пр.,
- этап (stage) — единица организации пайплайна, содержит 1+ задачу,
- задача (job) — единица работы в пайплайне. Состоит из скрипта (обязательно), условий запуска, настроек публикации/кеширования артефактов и много другого.
Соответственно, задача при настройке CI/CD сводится к тому, чтобы создать набор задач, реализующих все необходимые действия для сборки, тестирования и публикации кода и артефактов.
Перед началом: почему?
Потому, что когда появилась необходимость создать приватные репозитории под пет-проекты, на GitHub’e они были платными, а я — жадным. Репозитории стали бесплатными, но пока это не является для меня поводом достаточным переезжать на GitHub.
- Почему не Azure DevOps Pipelines?
Потому что там настройка элементарная — даже не требуются знания командной строки. Интеграция с внешними провайдерами git — в пару кликов, импорт SSH-ключей для отправки коммитов в репозиторий — тоже, пайплайн легко настраивается даже не из шаблона.
Исходная позиция: что имеется и чего хочется
- автоматическую сборку и тестирование для каждого merge request,
- сборку пакетов для каждого merge request и пуша в мастер при условии наличия в сообщении коммита определённой строки,
- отправку собранных пакетов в приватный фид в Azure DevOps,
- сборку документации и публикацию в GitLab Pages,
- бейджики!11
Описанные требования органично ложатся на следующую модель пайплайна:
- Этап 1 — сборка
- Собираем код, выходные файлы публикуем как артефакты
- Получаем артефакты с этапа сборки, гоняем тесты, собраем данные покрытия кода
- Задача 1 — собираем nuget-пакет и отправляем в Azure DevOps
- Задача 2 — собираем сайт из xmldoc в исходном коде и публикуем в GitLab Pages
Собираем конфигурацию
Готовим аккаунты
- Создаём аккаунт в Microsoft Azure
- Переходим в Azure DevOps
- Создаём новый проект
- Имя — любое
- Видимость — любая

- При нажатии на кнопку Create проект будет создан, и будет совершён переход на его страницу. На этой странице можно отключить ненужные возможности, перейдя в настройки проекты (нижняя ссылка в списке слева -> Overview -> блок Azure DevOps Services)

- Переходим в Atrifacts, жмём Create feed
- Вводим имя источника
- Выбираем видимость
- Снимаем галочку Include packages from common public sources, чтобы источник не превратился в
помойкуклон nuget
- Жмём Connect to feed, выбираем Visual Studio, из блока Machine Setup копируем Source

- Идём в настройки аккаунта, выбираем Personal Access Token

- Создаём новый токен доступа
- Имя — произвольное
- Организация — текущая
- Срок действия — максимум 1 год
- Область действия (scope) — Packaging/Read & Write

- Копируем созданный токен — после закрытия модального окна значение будет недоступно
- Заходим в настройки репозитория в GitLab, выбираем настройки CI/CD

- Раскрываем блок Variables, добавляем новую
- Имя — любое без пробелов (будет доступно в командной оболочке)
- Значение — токен доступа из п. 9
- Выбираем Mask variable

На этом предварительная настройка завершена.
Готовим каркас конфигурации
По умолчанию, для настройки CI/CD в GitLab используется файл .gitlab-ci.yml из корня репозитория. Можно настроить произвольный путь до этого файла в настройках репозитория, но в данном случае это не нужно.
Как видно из расширения, файл содержит конфигурацию в формате YAML . В документации подробно описано, какие ключи могут содержаться на верхнем уровне конфигурации, и в каждом из вложенных уровней.
Сначала добавим в файл конфигурации ссылку на docker-образ, в котором будет происходить выполнение задач. Для этого находим страницу образов .Net Core в Docker Hub. В GitHub есть подробное руководство, какой выбрать образ для разных задач. Нам для сборки подойдёт образ с .Net Core 3.1, поэтому смело добавляем первой строкой в конфигурацию
image: mcr.microsoft.com/dotnet/core/sdk:3.1Теперь при запуске пайплайна с хранилища образов Microsoft будет скачан указанный образ, в котором и будут исполняться все задачи из конфигурации.
Следующий этап — добавить stage‘ы. По умолчанию GitLab определяет 5 этапов:
- .pre — выполняется до всех этапов,
- .post — выполняется после всех этапов,
- build — первый после .pre этап,
- test — второй этап,
- deploy — третий этап.
Ничего не мешает объявить их явно, впрочем. Порядок, в котором указаны этапы, влияет на порядок, в котором они выполняются. Для полноты изложения, добавим в конфигурацию:
stages: - build - test - deployДля отладки имеет смысл получить информацию об окружении, в котором исполняются задачи. Добавим глобальный набор команд, который будет выполняться перед каждой задачей, с помощью before_script :
before_script: - $PSVersionTable.PSVersion - dotnet --version - nuget help | select-string VersionОсталось добавить хотя бы одну задачу, чтобы при отправке коммитов пайплайн запустился. Пока что добавим пустую задачу для демонстрации:
dummy job: script: - echo okЗапускаем валидацию, получаем сообщение, что всё хорошо, коммитим, пушим, смотрим на сайте на результаты… И получаем ошибку скрипта — bash: .PSVersion: command not found . WTF?
Всё логично — по умолчанию runner’ы (отвечающие за исполнение скриптов задач, и предоставляемые GitLab’ом) используют bash для исполнения команд. Можно исправить это дело, явно указав в описании задачи, какие теги должны быть у исполняющего пайплайн раннера:
dummy job on windows: script: - echo ok tags: - windowsОтлично! Теперь пайплайн выполняется.
Внимательный читатель, повторив указанные шаги, заметит, что задача выполнилась в этапе test , хотя мы не указывали этап. Как можно догадаться, test является этапом по умолчанию.
Продолжим создание скелета конфигурации, добавив все задачи, описанные выше:
build job: script: - echo "building. " tags: - windows stage: build test and cover job: script: - echo "running tests and coverage analysis. " tags: - windows stage: test pack and deploy job: script: - echo "packing and pushing to nuget. " tags: - windows stage: deploy pages: script: - echo "creating docs. " tags: - windows stage: deployПолучили не особенно функциональный, но тем не менее корректный пайплайн.
Настройка триггеров
Из-за того, что ни для одной из задач не указаны фильтры срабатывания, пайплайн будет полностью исполняться при каждой отправке коммитов в репозиторий. Так как это не является желаемым поведением в общем случае, мы настроим фильтры срабатывания для задач.
Фильтры могут настраиваться в двух форматах: only/except и rules. Вкратце, only/except позволяет настраивать фильтры по триггерам ( merge_request , например — настраивает задачу на выполнение при каждом создании запроса на слияние и при каждой отправке коммитов в ветку, являющуюся исходной в запросе на слияние) и именам веток (в т.ч. с использованием регулярных выражений); rules позволяет настраивать набор условий и, опционально, изменять условие выполнения задачи в зависимости от успеха предшествующих задач ( when в GitLab CI/CD).
Вспомним набор требований — сборка и тестирование только для merge request, упаковка и отправка в Azure DevOps — для merge request и пушей в мастер, генерация документации — для пушей в мастер.
Для начала настроим задачу сборки кода, добавив правило срабатывания только при merge request:
build job: # snip only: - merge_requestТеперь настроим задачу упаковки на срабатывания на merge request и добавление коммитов в мастер:
pack and deploy job: # snip only: - merge_request - masterКак видно, всё просто и прямолинейно.
Также можно настроить задачу на срабатывание только если создан merge request с определённой целевой или исходной веткой:
rules: - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"В условиях можно использовать перечисленные здесь переменные; правила rules не совместимы с правилами only/except .
Настройка сохранения артефактов
Во время выполнения задачи build job у нас будут созданы артефакты сборки, которые можно переиспользовать в последующих задачах. Для этого нужно в конфигурацию задачи добавить пути, файлы по которым нужно будет сохранить и переиспользовать в следующих задачах, в ключ artifacts :
build job: # snip artifacts: paths: - path/to/build/artifacts - another/path - MyCoolLib.*/bin/Release/*Пути поддерживают wildcards, что определённо упрощает их задание.
Если задача создаёт артефакты, то каждая последующая задача сможет их получить к ним доступ — они будут располагаться по тем же путям относительно корня репозитория, по которым были собраны из исходной задачи. Так же артефакты доступны для скачивания на сайте.
Теперь, когда у нас готов (и проверен) каркас конфигурации, можно переходить собственно к написанию скриптов для задач.
Пишем скрипты
Возможно, когда-то давно, в далёкой-далёкой галактике, собирать проекты (в том числе и на .net) из командной строки было болью. Сейчас же собрать, протестировать и опубликовать проект можно в 3 команды:
dotnet build dotnet test dotnet packЕстественно, есть некоторые нюансы, из-за которых мы несколько усложним команды.
- Мы хотим релизную, а не отладочную сборку, поэтому к каждой команде добавляем -c Release
- При тестировании мы хотим собирать данные о покрытии кода, поэтому потребуется подключить анализатор покрытия в тестовые библиотеки:
- Во все тестовые библиотеки следует добавить пакет coverlet.msbuild : dotnet add package coverlet.msbuild из папки проекта
- В команду запуска тестов добавим /p:CollectCoverage=true
- В конфигурацию задачи тестирования добавим ключ для получения результатов покрытия (см. ниже)
Собираем данные покрытия кода
Coverlet после запуска тестов выводит в консоль статистику по запуску:
Calculating coverage result. Generating report 'C:\Users\xxx\source\repos\my-project\myProject.tests\coverage.json' +-------------+--------+--------+--------+ | Module | Line | Branch | Method | +-------------+--------+--------+--------+ | project 1 | 83,24% | 66,66% | 92,1% | +-------------+--------+--------+--------+ | project 2 | 87,5% | 50% | 100% | +-------------+--------+--------+--------+ | project 3 | 100% | 83,33% | 100% | +-------------+--------+--------+--------+ +---------+--------+--------+--------+ | | Line | Branch | Method | +---------+--------+--------+--------+ | Total | 84,27% | 65,76% | 92,94% | +---------+--------+--------+--------+ | Average | 90,24% | 66,66% | 97,36% | +---------+--------+--------+--------+GitLab позволяет указать регулярное выражение для получения статистики, которую потом можно получить в виде бейджа. Регулярное выражение указывается в настройках задачи с ключом coverage ; в выражении должна присутствовать capture-группа, значение которой и будет передано в бейдж:
test and cover job: # snip coverage: /\|\s*Total\s*\|\s*(\d+[,.]\d+%)/Здесь мы получаем статистику из строки с общим покрытием по линиям.
Публикуем пакеты и документацию
Оба действия у нас назначены на последний этап пайплайна — раз уж сборка и тесты прошли, можно и поделиться с миром наработками.
Для начала рассмотрим публикацию в источник пакетов:
- Если в проекте не присутствует файл конфигурации nuget ( nuget.config ), создадим новый: dotnet new nugetconfig
Зачем: в образе может быть запрещён доступ на запись к глобальным (пользовательской и машинной) конфигурациям. Чтобы не ловить ошибки, просто создадим новую локальную конфигурацию и будем работать с ней. - Добавим в локальную конфигурацию новый источник пакетов: nuget sources add -name -source -username -password -configfile nuget.config -StorePasswordInClearText
- name — локальное имя источника, не приниципиально
- url — URL источника из этапа «Готовим аккаунты», п. 6
- organization — название организации в Azure DevOps
- gitlab variable — имя переменной с токеном доступа, добавленной в GitLab («Готовим аккаунты», п. 11). Естественно, в формате $variableName
- -StorePasswordInClearText — хак для обхода ошибки отказа в доступе (не я первый на эти грабли наступил)
- На случай ошибок может быть полезным добавить -verbosity detailed
- Отправляем все пакеты из текущей директории, поэтому *.nupkg .
- name — из шага выше.
- key — любая строка. В Azure DevOps в окне Connect to feed всегда в качестве примера приводят строку az .
- -skipduplicate — при попытке отправить уже существующий пакет без этого ключа источник вернёт ошибку 409 Conflict ; с ключом отправка будет пропущена.
Теперь настроим создание документации:
- Для начала, в репозитории, в ветке master, инициализируем проект docfx. Для этого из корня надо выполнить команду docfx init и в интерактивном режиме зададим ключевые параметры для сборки документации. Подробное описание минимальной настройки проекта здесь.
- При настройке важно указать выходную директорию ..\public — GitLab по умолчанию берёт содержимое папки public в корне репозитория как источник для Pages. Т.к. проект будет располагаться во вложенной в репозиторий папке — добавляем в путь выход на уровень вверх.
- Скрипт:
- nuget install docfx.console -version 2.51.0 — установит docfx; версия указана для гарантии правильности путей установки пакета.
- .\docfx.console.2.51.0\tools\docfx.exe .\docfx_project\docfx.json — собираем документацию
pages: # snip artifacts: paths: - publicЛирическое отступление про docfx
Раньше при настройке проекта я указывал источник кода для документации как файл решения. Основной минус — документация создаётся и для тестовых проектов. В случае, если это не нужно, можно задать такое значение узлу metadata.src :
< "metadata": [ < "src": [ < "src": "../", "files": [ "**/*.csproj" ], "exclude":[ "*.tests*/**" ] >], // --- snip --- >, // --- snip --- ], // --- snip --- >- metadata.src.src: «../» — выходим на уровень вверх относительно расположения docfx.json , т.к. в паттернах не работает поиск вверх по дереву директорий.
- metadata.src.files: [«**/*.csproj»] — глобальный паттерн, собираем все проекты C# из всех директорий.
- metadata.src.exclude: [«*.tests*/**»] — глобальный паттерн, исключаем всё из папок с .tests в названии
Промежуточный итог
Вот такую простую конфигурацию можно составить буквально за полчаса и пару чашек кофе, которая позволит при каждом запросе слияния и отправке в мастер проверять, что код собирается и тесты проходят, собирать новый пакет, обновлять документацию и радовать глаз красивыми бейджиками в README проекта.
Итоговый .gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:3.1 before_script: - $PSVersionTable.PSVersion - dotnet --version - nuget help | select-string Version stages: - build - test - deploy build job: stage: build script: - dotnet build -c Release tags: - windows only: - merge_requests - master artifacts: paths: - your/path/to/binaries test and cover job: stage: test tags: - windows script: - dotnet test -c Release /p:CollectCoverage=true coverage: /\|\s*Total\s*\|\s*(\d+[,.]\d+%)/ only: - merge_requests - master pack and deploy job: stage: deploy tags: - windows script: - dotnet pack -c Release -o . - dotnet new nugetconfig - nuget sources add -name feedName -source https://pkgs.dev.azure.com/your-organization/_packaging/your-feed/nuget/v3/index.json -username your-organization -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText - nuget push -source feedName -skipduplicate -apikey az *.nupkg only: - master pages: tags: - windows stage: deploy script: - nuget install docfx.console -version 2.51.0 - $env:path = "$env:path;$($(get-location).Path)" - .\docfx.console.2.51.0\tools\docfx.exe .\docfx\docfx.json artifacts: paths: - public only: - masterКстати о бейджиках
Ради них ведь всё и затевалось!
Бейджи со статусами пайплайна и покрытием кода доступны в GitLab в настройках CI/CD в блоке Gtntral pipelines:

Бейдж со ссылкой на документацию я создавал на платформе Shields.io — там всё достаточно прямолинейно, можно создать свой бейдж и получать его с помощью запроса.
Azure DevOps Artifacts также позволяет создавать бейджи для пакетов с указанием актуальной версии. Для этого в источнике на сайте Azure DevOps нужно нажать на Create badge у выбранного пакета и скопировать markdown-разметку:


Добавляем красоты
Выделяем общие фрагменты конфигурации
Во время написания конфигурации и поисков по документации, я наткнулся на интересную возможность YAML — переиспользование фрагментов.
Как видно из настроек задач, все они требуют наличия тега windows у раннера, и срабатывают при отправке в мастер/создании запроса на слияние (кроме документации). Добавим это во фрагмент, который будем переиспользовать:
.common_tags: &common_tags tags: - windows .common_only: &common_only only: - merge_requests - masterИ теперь в описании задачи можем вставить объявленный ранее фрагмент:
build job:Названия фрагментов должны начинаться с точки, чтобы не быть интерпретированными как задача.
Версионирование пакетов
При создании пакета компилятор проверяет ключи командной строки, и в их отсутствие — файлы проектов; найдя узел Version, он берёт его значение как версию собираемого пакета. Выходит, чтобы собрать пакет с новой версией, нужно либо обновить её в файле проекта, либо передать как аргумент командной строки.
Добавим ещё одну хотелку — пусть младшие два номера в версии будут годом и датой сборки пакета, и добавим пререлизные версии. Добавлять эти данные в файл проекта и проверять перед каждой отправкой можно, конечно — но можно ведь это делать и в пайплайне, собирая версию пакета из контекста и передавая через аргумент командной строки.
Условимся, что если в сообщении коммита есть строка вида release (v./ver./version) (rev./revision )? , то мы будем из этой строки брать версию пакета, дополнять её текущей датой и передавать как аргумент команде dotnet pack . В отсутствие строки — просто не будем собирать пакет.
Данную задачу решает следующий скрипт:
# регулярное выражение для поиска строки с версией $rx # ищем строку в сообщении коммита, передаваемом в одной из предопределяемых GitLab'ом переменных $found = $env:CI_COMMIT_MESSAGE -match $rx # совпадений нет - выходим if (!$found) < Write-Output "no release info found, aborting"; exit ># извлекаем мажорную и минорную версии $maj = $matches['maj'] $min = $matches['min'] # если строка содержит номер релиза - используем его, иначе - текущий год if ($matches.ContainsKey('rel')) < $rel = $matches['rel'] >else < $rel = ".$(get-date -format "yyyy")" ># в качестве номера сборки - текущие месяц и день $bld = $(get-date -format "MMdd") # если есть данные по пререлизной версии - включаем их в версию if ($matches.ContainsKey('rev')) < $rev = "-$($matches['rev'])" >else < $rev = '' ># собираем единую строку версии $version = "$maj$min$rel.$bld$rev" # собираем пакеты dotnet pack -c Release -o . /p:Version=$versionДобавляем скрипт в задачу pack and deploy job и наблюдаем сборку пакетов строго при наличии заданной строки в сообщении коммита.
Итого
Потратив примерно полчаса-час времени на написание конфигурации, отладку в локальном powershell и, возможно, пару неудачных запусков, мы получили несложную конфигурацию для автоматизации рутинных задач.
Конечно, GitLab CI/CD гораздо обширнее и многограннее, чем может показаться после прочтения этого руководства — это совершенно не так. Там даже Auto DevOps есть, позволяющий
automatically detect, build, test, deploy, and monitor your applications
Теперь в планах — сконфигурировать пайплайн для развёртывания приложений в Azure, с использованием Pulumi и автоматическим определением целевого окружения, что будет освещено в следующей статье.
Как работать с GitLab

Сегодня поговорим об азах взаимодействия с одной из самых популярных git-систем.
Что такое GitLab
Сейчас почти никто не пишет код в одиночку. Команды инженеров и разработчиков растут, как на дрожжах. Работая в группах, программисты используют системы управления исходным кодом на базе git, специального инструмента, позволяющего хранить данные разрабатываемого проекта в сети и совместно редактировать его с учетом определенных правил и методик взаимодействия. Самый известный подобный сервис – GitHub. А GitLab – это его собрат, выполняющий те же функции, но устроенный несколько иначе.
GitLab позволяет управлять репозиториями с кодом, отслеживать ошибки в разрабатываемых программах, публиковать код и тестировать его. Это незаменимый инструмент для каждого, кто программирует не в одиночку.
Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостейРазница между GitLab и GitHub
Оба сервиса – системы управления репозиториями на базе git. Принципиальных отличий между ними нет. GitHub появился раньше и стал чуть ли не синонимом git, поэтому он популярнее и для многих является единственной системой для управления репозиториями.
Но GitLab есть что предложить с точки зрения функциональности, поэтому все чаще наблюдается переход пользователей с GitHub на GitLab. В частности, это касается разработчиков-новичков, которые пока еще не «приросли» к GitHub.
В связи с растущей популярностью GitLab я и решил познакомить вас с этим сервисом поближе.
Инструкция по использованию GitLab
Перед началом работы с сервисом, нужно создать учетную запись. Процедура эта весьма тривиальна:
- Заходим на официальный сайт GitLab.
- В верхнем левом углу находим кнопку Login и жмем по ней.
- Через пару секунд перед вам откроется форма входа в систему, а под ней будет ссылка на форму регистрации (Register now). Переходим по ней.

- Заполняем данные для регистрации (классические данные: адрес электронной почты, пароль, логин и т.п.). Жмем на кнопку Register.
- В течение пары минут на указанную при регистрации почту «упадет» сообщение со ссылкой для подтверждения создания аккаунта. Переходим по ней.

Учетная запись готова. Теперь можно переходить непосредственно к знакомству с GitLab.
Как создать проект
Проектом в GitLab считается глобальное рабочее пространство, в котором будет размещен репозиторий с файлами ваших сайтов и приложений. А также в нем можно взаимодействовать с коллегами и использовать другие возможности сервиса.

Поэтому при первом входе под своей учетной записью GitLab попросит вас указать род деятельности, наличие или отсутствие команды, имя рабочей группы и название проекта.
После формирования проекта можно переходить непосредственно к созданию репозиториев, загрузке программ в GitLab и т.п.
Как создать репозиторий
Чтобы воспользоваться репозиторием, нужно создать новый проект:
- Кликаем по иконке со значком + в панели управления.

- Выбираем пункт New project/repository.

- Затем кликаем по Create blank project.
- Указываем его имя и другие запрашиваемые параметры (можно указать, публичным будет репо или приватным) и нажимаем на кнопку Create Project.
Вместе с проектом сформируется новый git-репозиторий. Теперь можно с ним взаимодействовать, то есть загружать файлы, делать коммиты, создавать различные ветки для разработки продукта и мерджить их при необходимости.
Как загрузить файлы сайта/приложения в GitLab
Тут есть 3 пути.
Первый – используем веб-интерфейс GitLab
- На главной странице проекта ищем строку The repository for this project is empty, а под ней кнопку Upload File и нажимаем на нее.
- GitLab предложит выбрать файлы проекта для загрузки и последующей работы с ними. Выбираем все файлы, что используем при разработке и выгружаем.
Также можно использовать WebIDE, встроенную в GitLab, чтобы прямо в браузере писать код и создавать файлы для своего приложения/сайта.
Второй – используем командную строку
Тут все сложнее, но на самом GitLab опубликована короткая и доходчивая инструкция по подключению к сервису через командную строку, используя классический git-клиент.

Третий – используем сторонний git-клиент
Существуют приложения в духе Tower и Sublime Merge, позволяющие управлять репозиториями, делать коммиты и пушить изменения в проекты при помощи удобного графического интерфейса. Можно подключиться к GitLab с помощью одной из таких программ.
Как добавить SSH-ключ для подключения к репозиторию
SSH-ключи можно использовать для авторизации в GitLab и для управления репозиториями по протоколу Secure Shell. Чтобы это сделать:
- Генерируем ключ с помощью команды ssh-keygen (вводим ее в терминал).

- Генератор предложит сохранить получившийся ключ. Менять директорию, куда сохраняется ключ, необязательно.

- Затем утилита попросит ввести пароль. Его тоже можно не вводить. Просто жмем на Enter.

- В указанной на втором этапе папке появится файл с ключом в формате .pub. В нем лежит ключ. Нужно скопировать его.
- Возвращаемся на сайте GitLab. Открываем раздел SSH-keys, вставляем ключ в специально отведенное для этого поле и нажимаем на кнопку Add key.

Как работать с ветками
Ветки – это инструмент для создания дополнительных вариаций приложения/сайта, которые позволяют вести разработку новых функций, не затрагивая при этом основное приложение, доступное для пользователей.
По умолчанию в GitLab доступна только одна ветка – master. Но ее чаще используют не для разработки, а для публикации готовых сборок проекта, которые нестрашно превратить в релиз для масс.
Поэтому принято создавать новые ветки для разработки дополнительных функций, а уже потом объединять их с основной.
Как создавать ветки
Ветки – не уникальная для GitLab функция. Это часть git, поэтому, как и в случае с репозиториями, тут можно пойти тремя путями:

- На сайте GitLab в окне управления репозиторием нажать на кнопку + справа от названия ветки, а потом выбрать пункт New branch в выпадающем меню.
- Можно создать новую ветку через git-клиент в терминале с помощью команды git checkout -b [название новой ветки].
- Или воспользоваться аналогичной функций в используем графическом git-клиенте (Tower, Sublime Merge, GitFox и т.п.).
Любой из способов позволит создавать новую ветку, в которую после этого можно будет отправлять коммиты и делать пуши.
Мерджинг веток
Мерджинг (или объединение) веток – это механизм слияния двух наборов функций одной программы, позволяющий переносить функции из дополнительных веток в основную ветку разработки, где лежит приложение. Результат увидят еще и пользователи, а не только разработчики.
Запрос на объединение веток будет появляться на сайте GitLab каждый раз, когда вы будете вносить изменения в код одной или нескольких веток.
Выглядит это следующим образом:

- На сайте появляется большая синяя кнопка Create merge request. Кликаем по ней.
- Затем рассказываем о своем запросе (поясняем, для чего он делается).
- Указываем автор запроса в поле Assignee.
- Указываем человека, который будет проверять запрос в поле Reviewer.
- Потом указываем Milestone (если используете их).
- Ставим теги.
- И нажимаем на Create merge request.
- Если с запросом все ок, то проверяющий нажмет на кнопку Merge, и весь код перекочует в основную ветку проекта (ну или ту, которую указал автор запроса).
Как добавлять пользователей в проект
К разработке своего приложения/сайта всегда можно привлечь людей со стороны:

- Для этого кликаем по кнопке Project information в боковой панели GitLab.
- Выбираем пункт Members.
- В графу GitLab member or Email address вписываем ник GitLab-пользователя или его email-адрес.
- Выбираем для него роль (гость, наблюдатель, разработчик).
- Также указываем время действия приглашения (в указанный день приглашенный будет исключен из проекта).
- А потом кликаем на Invite.
Если выбранный человек согласится присоединиться, то ваша команда расширится.
Как создавать баг-репорты
В git-системах есть инструменты, помогающие оповещать разработчиков об ошибках и обсуждать их как с пользователями, так и с коллегами.
Речь идет о разделе Issues. Если возникла проблема, то нужно сообщить о ней тут. Для этого:
- Открываем раздел Issues в боковой панели управления.
- Затем нажимаем на кнопку New issue.

- Даем имя обнаруженной проблеме, а затем подробно описываем ее в разделе Description.
- Затем назначаем ответственного в пункте Assignee и срок, в течение которого нужно найти решение найденной проблемы.
- А потом нажимаем на кнопку Create issue.

Как удалить проект
- Открываем настройки проекта и переходим во вкладку General.
- Листаем ее до пункта Advanced и справа от него ищем кнопку Expand, которая откроет доступ к дополнительным параметрам.
- Вновь пролистываем появившееся меню до упора вниз, пока не наткнемся на кнопку Delete project.
- Нажимаем на нее и вписываем название проекта, чтобы его удалить.
Вместо заключения
На этом все. Я рассмотрел базовые возможности GitLab и намеренно не затрагивал аналитические инструменты, интеграцию с Kubernetes и дополнительные функции, пытаясь сконцентрироваться на важнейших концептах GitLab и git. Это то, что вам необходимо для старта, независимо от того, пользовались вы ранее другими системами управлениями репозиториями или нет.