GitLab CI

В этой статье хочу поделиться интеграцией с GitLab CI, кратко и без воды. Но, возможно инструкция вам не подойдет, потому что процессы у всех разные, а мы в своей компании готовим так:

  • разработчики пишут код в своих ветках и в GitLab-е создают мерж-реквесты
  • когда мерж-реквест получает Approve - тестировщики тестируют ветки (создают сборку, деплоят на тестовый сервер, тестируют UI)
  • когда ветка протестирована - тестировщик мержит ее в ветку master
  • когда все нужные ветки попали в ветку master - тестировщики тестируют ветку master (создают сборку, деплоят на тестовый сервер, тестируют UI)
  • когда ветка master протестирована - тестировщик уже созданную сборку деплоит на production-сервера

Как интегрироваться

В GitLab у вас есть только 1 способ - создать в своем репозитории файл .gitlab-ci.yml

У нас данный файл находится в таком виде:

# отключаю клонирование репозитория средствами gitlab-runner-a
variables:
  GIT_STRATEGY: none

stages:
- build
- test
- deploy
- delete
- deleteButton

building:
  stage: build
  when: manual
  script:
  - /commander.sh projectName=$CI_PROJECT_NAME env=test appVersion=$CI_COMMIT_REF_NAME build=true where=locally

send on testing:
  stage: test
  when: manual
  script:
  - /commander.sh projectName=$CI_PROJECT_NAME env=test appVersion=$CI_COMMIT_REF_NAME configuration=true deploy=true switch=true where=test-server

send to production:
  stage: deploy
  when: manual
  script:
  - /commander.sh projectName=$CI_PROJECT_NAME env=prod appVersion=$CI_COMMIT_REF_NAME configuration=true where=locally
  - /commander.sh projectName=$CI_PROJECT_NAME env=prod appVersion=$CI_COMMIT_REF_NAME deploy=true where=prod-server
  - /commander.sh projectName=$CI_PROJECT_NAME env=prod appVersion=$CI_COMMIT_REF_NAME migrate=true where=locally
  - /commander.sh projectName=$CI_PROJECT_NAME env=prod appVersion=$CI_COMMIT_REF_NAME switch=true where=prod-server

# этап будет запускаться после того, как ветка проекта будет вмержена в мастер-ветку (пайплайн тригерится веб-хуком)
delete build:
  stage: delete
  only:
    variables:
      - $actionName == "deleteBuild"
  script:
    - /commander.sh projectName=$CI_PROJECT_NAME appVersion=$CI_COMMIT_REF_NAME clean=true where=locally,test-server

# бывает нужно вручную удалить сборку (например: мерж-реквест отменен)
delete build button:
  stage: deleteButton
  when: manual
  script:
    - /commander.sh projectName=$CI_PROJECT_NAME appVersion=$CI_COMMIT_REF_NAME clean=true where=locally,test-server

Если Вам не понятны стадии описанные выше - напишите, я опишу тут почему так, а не иначе. Однако, сейчас хочется рассказать про интересный этап - удаление сборок при мерже веток.

Как удалять старые сборки

На этот счет мы поступаем следующим образом:

а. при мерже ветки в мастер - удаляется сборка созданная для этой ветке:

  • удаляется на сервере сборки
  • удаляется на тестовом сервере

б. при успешном деплое новой сборки (ветка master) на продакшен сервер:

  • на продакшен сервере будут удалятся все сборки текущего проекта (все сборки кроме текущей - актуальной)
  • не будет удалена текущая сборка на сервере сборки - для оптимизации следующей сборки
  • не будет удалена текущая сборка на тестовом сервере - в целях тестирования и удобной разработки (основной проект имеет зависимости в виде сервисов, которые должны быть работоспособны)

И если пункт 2 можно легко реализовать в команде:

/commander.sh projectName=$CI_PROJECT_NAME env=prod appVersion=$CI_COMMIT_REF_NAME switch=true where=prod-server

То, пункт 1 нуждается в объяснении нюансов изложенных ниже.

Как тригерить нужный этап пайплайна в GitLab

1. Делаем так, чтобы в момент мержа мерж-реквеста в ветку мастер, GitLab отправлял запрос на адрес Вашего веб-сервера, например http://yapro.ru/gitlab

Для этого в GitLab, на странице проекта, переходим в Settings ➔ Integrations и создаем событие следующим образом:

GitLab CI

Два важных момента:

  • Secret Token будет отправляться на Ваш веб-сервер в хедере X-GITLAB-TOKEN (таким образом вы можете проверять, это запрос из GitLab-a или нет)
  • красной стрелкой справа я указал на кнопку Test, она очень полезна, чтобы тестировать следующий шаг (нажимаете на эту кнопку и выбираете Merge request events)

2. Вы должны сделать так, чтобы вызов адреса http://yapro.ru/gitlab отправлял запрос тригерируя на GitLab-е запуск pipeline, например так:

http://gitlab.yapro.ru/api/v4/projects/32/ref/REF_NAME/trigger/pipeline?token=TOKEN&variables[actionName]=deleteBuild

32 - идентификатор проекта, его можно узнать в GitLab-е ➔ Проект ➔  Settings ➔ General:

GitLab CI

REF_NAME - значение приходит из запроса, который выполняется по факту срабатывания события (выполнен мерж мерж-реквеста в ветку мастер - см. выше пункт 1), у меня это $requestParams['object_attributes']['source_branch']

TOKEN - секретный ключ, который GitLab будет проверять, чтобы идентифицировать Ваш запрос, данный ключ генерируется автоматически, когда Вы создаете триггер в GitLab-е ➔ Проект ➔  Settings ➔ CI /CD ➔ Pipeline triggers

GitLab CI

actionName - имя переменной, которая обрабатывается в файле .gitlab-ci.yml (см. выше), но чтобы передача переменных заработала, данную переменную нужно объявить в GitLab-е ➔ Проект ➔  Settings ➔ CI /CD ➔ Variables

GitLab CI

Итак, процесс настройки завершен, всем удачки.

p.s. запрос шага 2 можно посылать любым удобным способом и даже так:

curl -X POST \
-H "Content-Type: application/json" \
-d '{"token":"token", "ref":"master", "variables": {"ENVIRONMENT": "production", "ACTION": "release"}}' \
https://gitlab.com/api/v4/projects/:id/trigger/pipeline

Источники: 1 - 2 - 3 - 4 - 5


30.11.2018 04:57

Комментарии

Есть возможность показать commander.sh?
Конечно без ваших конфиденциальных функций
Alex | 07.02.2019 12:53
Можете помочь настроить gitLab runner, у меня постоянно пишет - This job is stuck because you don't have any active runners online with any of these tags assigned to them: deploy
Александр | 03.10.2019 15:05