UMGUM.COM (лучше) 

GitLab + Git Workflow ( Простая пошаговая настройка Git-репозитория на сервере хранения "GitLab", ориентированная на некоторые положения методики управления данными. )

20 марта 2019  (обновлено 25 апреля 2019)

Apps: "GitLab Community Edition (Standalone) Server".

Задача: проработать простую пошаговую настройку Git-репозитория на сервере хранения "GitLab", ориентированную на следующие основные положения методики управления данными ("workflow"):

1. Репозиторий используется для хранения любого дерева веток, но подразумевается наличие как минимум трёх: "master", "testing" и "develop";
2. В "develop" и ответвлениях "feature" ведётся разработка - с ними можно делать что угодно;
3. Ветка "testing" по правам доступа аналогична "develop" - но выгрузка в неё запускает автоматизацию процедур тестирования;
4. Выгрузка в "master" напрямую запрещена - только вливание из "testing" с предварительным "pull request"-ом, который должен быть одобрен руководителем - после чего запускаются автоматизированные процедуры публикации.


Создание группы и Git-репозитория в таковой.

В современных web-сервисах, в частности "GitLab CE Server", создание группы репозиториев и Git-репозитория в таковой не представляет сложности и не требует особого описания - пара нажатий на кнопки, заполнение полей именований и описаний, и вот у нас есть место на сервере хранения, куда уже можно загружать данные.

Обращу внимание на неочевидную особенность именований сущностей группы репозиториев:

"group name" - это отображаемое условное наименование (например "Our first group") и его можно безвредно изменить в любой момент;
(элемент) "group path" - это уникальный идентификатор группы (например "group-01") и его крайне нежелательно изменять в последствии, так как только через него возможна идентификация группы репозиториев в процедурах автоматизации.

В дальнейшем URI для доступа к созданному репозиторию в группе таковых будет выглядеть так:

https://gitlab.example.net/group_path/repo.git

Настройки группы репозиториев.

Ограничиваем видимость группы репозиториев, разрешая это только явно заданным далее пользователям, а также отключаем поддержку хранения больших файлов (LFS) отдельно от репозитория (эта функциональность требует отдельного навыка, не всегда имеющегося у разработчиков):

Group -> Group settings:
  Visibility Level: Private
  Large File Storage: false

Задаём разрешения доступа к группе репозиториев (эта политика распространяется на все репозитории группы, но может быть переопределена):

Group -> Members:
  Member: user-one
  Role: Developer
  Expiration date: none

Установка ограничений на запись в "master".

К сожалению, насколько я уловил, в "GitLab Community Edition (Standalone) Server" (в отличие от "BitBucket (Standalone) Server") групповые политики ограничений доступа к веткам наследуемого типа не поддерживаются - приходится устанавливать их точечно.

В настройках репозитория применим ограничивающие правила записи в ветку "master", запретив прямую загрузку (push) в неё кому бы то ни было, и разрешив вливание (merge) из других ветвей только руководителям проекта (по умолчанию "masters" - в терминологии "GitLab"):

Group -> Repository -> Repository Settings -> Protected Branches:
  Branch: master
  Allowed to merge: Masters
  Allowed to push: No one

Если используется платный продукт "GitLab Enterprise Edition (EE)" (documentation, documentation), то в настройках репозитория укажем пользователей, которые в обязательном порядке должны будут проводить "review" кода и одобрение такового для всех поступающих "merge request":

Group -> Repository -> Repository Settings -> General -> Merge request approvals:
  No. approvals required: 2  - минимум два пользователя должны одобрить загрузку,
  Members: teamlead, manager - пользователи, проводящие проверку.

У бесплатного варианта "GitLab Community Edition (CE)" возможности организации процесса разработки существенно скромнее - можно лишь задать в настройках репозитория пользователя (или несколько таковых), исполняющего роль руководителя процесса разработки и обладающего правом вливания (merge) в ветку "master" (обычно по завершению процедуры одобрения поступившего "pull request"):

Group -> Repository -> Members:
  Member: user-one
  Role: Master
  Expiration date: none

В дополнение к вышеуказанным настройкам разрешения на вливание в защищённые ветви потребуем предварительного одобрения вносимых изменений всеми пользователями, проводящими "review" поступающих "pull request" - это снизит вероятность внесения несогласованных изменений:

Group -> Repository -> General Settings -> Merge request settings:
  Merge method:
    Merge commit.
  ....
  Only allow merge requests to be merged if all discussions are resolved: true

Теперь, при попытке сделать выгрузку (push) напрямую в "master" мы получим отказ:

$ git clone --branch master https://gitlab.example.net/group/repo.git
$ cd ./test && vi ./probe.txt && $ git add --all && $ git commit -m "Probe push to master"
$ git push -u origin master

....
remote: GitLab: You are not allowed to push code to protected branches on this project.
To https://gitlab.example.net/group/repo.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://gitlab.example.net/group/repo.git'

Индивидуальные настройки репозитория хранения.

Сразу после загрузки данных в свежий репозиторий есть смысл произвести некоторые настройки для удобства его дальнейшей эксплуатации.

Заранее создаём ветви "testing" и "develop" (предполагая, что первичная загрузка была в "master"):

Group -> Repository -> Branches -> New branch:
  Branch name: testing
  Create from: master

Задаём ветку, в которую пользователь попадает по умолчанию, при обращении к функционалу просмотра содержимого репозитория:

Group -> Repository -> General Settings:
  Default Branch: develop

В настройках репозитория задаём уровень видимости репозитория, деактивируем дополнительный функционал справочной (Wiki), разделения блоков кода (Snippets) и отключаем поддержку хранения больших файлов (LFS) отдельно от репозитория:

Group -> Repository -> Permissions:
  Project visibility: Private
  Wiki: false
  Snippets: false
  Repository -> Git Large File Storage: false

Задаём разрешения доступа к репозиторию или проверяем и переопределяем их при необходимости, если они заданы на уровне группы:

Group -> Repository -> Members:
  Member: user-one
  Role: Developer
  Expiration date: none

Пример очерёдности процедур работы с репозиториями "GitLab".

Запрашиваем из репозитория хранения актуальное содержимое ветви разработки и явно переключаемся в таковую:

$ git clone https://gitlab.example.net/group/repo.git
$ cd ./test
$ git branch
$ git checkout develop

Вносим изменения в файлы, сверяем и фиксируем их в ветви "develop":

$ vi ./probe.txt
$ git status
$ git add --all
$ git commit -m "Probe Commit"
$ git log

Выгружаем в репозиторий хранения наработки ветви "develop", воспользовавшись тем же адресом (web-интерфейс) и протоколом (HTTPS), что и при предыдущей загрузке (обычно эти параметры автоматически фиксируются Git-клиентом в конфигурационном файле ".git/config" локального репозитория):

$ git push -u origin develop

Username for 'https://gitlab.example.net': user-one
Password for 'https://user-one@gitlab.example.net':
....
To https://gitlab.example.net/group/repo.git
   e1f0938..5cf06ed  develop -> develop
Branch 'develop' set up to track remote branch 'develop' from 'origin'.

После успешной фиксации изменений в ветке разработке переходим в ветку "testing" локального репозитория:

$ git fetch https://gitlab.example.net/group/repo.git testing
$ git checkout testing

Вливаем в ветку "testing" отличия, накопившиеся в ветке "develop":

$ git merge develop

Fast-forward
./probe.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

$ git status
$ git diff
$ git log

При желании можно указать явно указать адрес репозитория хранения и протокол (SSH) выгрузки туда данных (учтите, что это работает только с аутентификацией посредством SSH-ключей):

$ git push ssh://git@gitlab.example.net/group/repo.git testing

В соответствии с логикой построения нашей схемы на событие выгрузки в "testing" должны сработать предусмотренные процедуры автоматизированного тестирования (разберём их в отдельной заметке).

Теперь идём в web-интерфейс "GitLab" и создаём запрос "(New) Merge Request" на вливание изменений из ветки "testing" в "master":

Group -> Repository -> Merge Requests -> New merge request:
  Source branch: testing
  Target branch: master

Далее всё просто и очевидно - в версии "GitLab EE" назначенные или произвольно добавленные "Approvers" проверяют и одобряют, в версии "GitLab CE" кто-то из уполномоченных "Masters" проверяет и одобряет, после чего отдаёт команду влить изменения.

В соответствие с логикой построения нашей схемы на событие выгрузки в "master" должна сработать автоматизация публикации, которая будет рассмотрена в отдельной публикации.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )