В одном из моих проектов требуется автоматически выгружать код из ветки master в production после выполнения всех тестов.

К сожалению, GitLab CI не позволяет это сделать напрямую из скрипта без дополнительных настроек, так как токен, которым пользуется Runner, позволяет только читать из репозитория, но не писать в него.

Настройки для того чтобы открыть раннеру доступ на запись, в гитлабе нет.

Поэтому выкручиваемся.

Мы обратимся по SSH к гитлабу и выполним слияние веток.

Но в подключении по SSH из пайплайна GitLab есть парочка подводных камней, поэтому я пишу здесь подробно, как это сделать.

1. Создаём пару ключей:

ssh-keygen -t rsa
nex@Pacman3:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/nex/.ssh/id_rsa): gitlab_ci_private_key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in gitlab_ci_private_key
Your public key has been saved in gitlab_ci_private_key.pub
The key fingerprint is:
SHA256:uMe8BGvC4N7ett8Q4BheH1nF9sQieEj4yITVAGxuitQ nex@Pacman3
The key's randomart image is:
+---[RSA 3072]----+
|   ..+o=.o.o..   |
|    + o +oo + o  |
|  .o.oooo. o +   |
| . Eo=o+..    .  |
|...oo + S        |
|...o   * .       |
|  . o + *        |
| . . +.o +       |
|  ..o.ooo .      |
+----[SHA256]-----+

2. Загружаем приватный ключ gitlab_ci_private_key в переменную SSH_PRIVATE_KEY:

GitLab -> My Project -> Settings -> CI / CD -> Variables -> Expand -> Add variable

3. Загружаем публичный ключ gitlab_ci_private_key.pub в настройки репозитория.

GitLab -> My Project -> Settings -> Repository -> Deploy Keys -> Expand -> Add key

4. Используем следующие команды в .gitlab-ci.yml:

Отмечу, что контейнер каждый раз создаётся “чистый”, и по SSH к незнакомому хосту просто так не подключится.

Поэтому заранее записываем хост гитлаба в файл known_hosts.

    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts

...

    - git remote show origin
    - git remote set-url --push origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH
    - git remote show origin
    - git checkout master-test-ci
    - git pull
    - git checkout production-test-ci
    - git pull
    - git merge master-test-ci
    - git push --follow-tags origin HEAD:$CI_COMMIT_REF_NAME

Итог

Наш пайплайн обращается к гитлабу, выполняет тесты, делает слияние веток.