Автоматическая публикация npm пакета из gitlab ci/cd

от автора

Всем привет! Сегодня я расскажу как реализовать автоматическую публикацию npm пакета в cicd gitlab, с помощью каких инструментов мы генерируем CHANGELOG файл и обновляем версию package.json. А так же как публикуем изменения в gitlab репозитории.

Я постараюсь дать вам простую инструкцию, расскажу с какими сложностями мы столкнулись и как их решили.

Задача

  • Настроить ci/cd таким образом, чтобы новая версия npm пакета автоматически публиковалась в реестре пакетов при изменении master ветки в git репозитории.

  • Автоматически определить следующий номер версии npm пакета

  • Сгенерировать CHANGELOG.md файл

  • Опубликовать изменения в gitlab репозитории

  • Опубликовать пакет в реестре npm пакетов

Реализация:

Давайте посмотрим на результат и разберем код более подробно

# .gitlab-ci.yml image: "node:16-slim"  stages: - publish  publish: stage: publish variables:     GIT_STRATEGY: clone before_script: - apt-get update && apt-get install git -y script: # Конфигурация npm - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc      # Конфигурация git - git config --global user.email "${GIT_USER_EMAIL}" - git config --global user.name "${GIT_USER_NAME}"  # Установка зависимостей и сборка проекта - yarn - yarn build  # Определение новой версии npm пакета и генерация CHANGELOG.md файла - yarn standard-version - commitMessage=$(git log -1 --pretty=%B) - tagname=$(git tag --points-at HEAD) - version=${tagname:1}  # Решение проблемы с циклическим вызовом - git tag -d $tagname - git commit --amend -m "[ci skip] ${commitMessage}" --no-verify - git tag -a $tagname -m ''  # Публикация в gitlab - git push <https://${GIT_SYNC_USER}:${GIT_SYNC_TOKEN}@git.nlmk.com/$CI_PROJECT_PATH.git> --follow-tags master:master  # Публикация в npm - yarn publish --new-version $version --verbose  only: - master

Для публикации пакета в npm и для отправки коммита в репозиторий нам требуется настроить конфигурацию для npm и git, а так же установить зависимости проекта.

Опубликовать пакет в npm репозитории можно c помощью авторизованного пользователи, либо с применением accessToken. Использование accessToken в ci/cd более предпочтительный вариант, потому что вам не придется хранить логин и пароль пользователя в переменных gitlab.

Конфигурация npm:

# Конфигурация npm - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc

NPM_TOKEN — имя ci переменной, в которой хранится npm токен

Более подробно про access tokens в npm можно прочитать в документации.
Более подробно ознакомиться с gitlab переменными можно здесь

Конфигурация git:

Для конфигурации git пользователя мы используем технического пользователя, чьё имя и email хранятся в ci переменных:

# Конфигурация git - git config --global user.email "${GIT_USER_EMAIL}" - git config --global user.name "${GIT_USER_NAME}"

GIT_USER_EMAIL GIT_USER_NAME— имя ci переменной, в которой хранится имя и email git пользователя, от которого будет создаваться коммит (В нашем случае это специальный технический пользователь)

Установка зависимостей и сборка проекта

С установкой зависимостей и сборкой проекта все просто:

# Установка зависимостей и сборка проекта - yarn - yarn build

Данные команды установят зависимости и соберут наш проект.

Определение новой версии npm пакета и генерация CHANGELOG.md файла

Для генерации CHANGELOG файла мы используем библиотеку standard-version.

При запуске команды standard-version происходит следующее:

  • Вычисляется новая версия npm пакета в соответствие с conventional commit и semver

  • Обновляется версия пакета в package.json

  • Обновляется CHANGELOG.md файл

  • Создается тег указывающий на новую версию (напримерv1.13.2)

  • Создается коммит с изменениями (текст коммитаchore(release): 1.13.2)

# Определение новой версии npm пакета и генерация CHANGELOG.md файла - yarn standard-version - commitMessage=$(git log -1 --pretty=%B) - tagname=$(git tag --points-at HEAD) - version=${tagname:1}

После выполнения команды standard-version я сохраняю в переменных сообщение созданного коммита commitMessage (chore(release): 1.13.2), имя созданного тега tagname (v1.13.2) и номер новой версии пакета: version (1.13.2) Они понадобятся нам позже

Решение проблемы с циклическим вызовом

После обновления версии пакета нам требуется вылить наши изменения в git, но есть одна маленькая проблема: если мы просто опубликуем новую версию в git и обновим master ветку то запустится новый pipeline и так далее, по бесконеному циклу. чтобы этого не происходило коммит должен начинаться с [ci-skip]. Для того, чтобы решить эту проблему, следует изменить текст созданного коммита, и не забыть про теги.

# Решение проблемы с циклическим вызовом # Удаляем поседний созданный тег - git tag -d $tagname  # Добавляем [ci-skip] в последний коммит git commit --amend -m "[ci skip] ${commitMessage}" --no-verify  # Создаем новый тег на последнем коммите git tag -a $tagname -m ''

Как вы можете заметить я удаляю тег, меняю сообщение коммита и снова добавляю тег.

Если мы просто попытаемся изменить сообщение коммита с помощью команды - git commit --amend то будет создан новый коммит. Такое поведение связано с тем, что к изменяемому коммиту привязан тег. Чтобы решить эту проблему мы удаляем тег, далее меняем сообщение коммита, а потом создаем тег на измененном коммите.

Публикация в gitlab:

Для обновления кодовой базы нам требуется внести изменения в master ветке.

# Публикация в gitlab - git push <https://${GIT_SYNC_USER}:${GIT_SYNC_TOKEN}@git.nlmk.com/$CI_PROJECT_PATH.git> --follow-tags master:master

GIT_SYNC_USER — имя пользователя, которое будет указано в коммите
GIT_SYNC_TOKEN — gitlab токен технического пользователя. Более подробно про gitlab токены можно прочитать тут)
CI_PROJECT_PATH — предопределенная переменная, в которой хранится path проекта с включенным именем проекта. Более подробно со списком доступных переменных можно ознакомиться в документации

Публикация в npm

# Публикация в npm - yarn publish --new-version $version --verbose

При публикации пакета используется переменная $version, в которой сохранена новая версия пакета. Мы явно указываем с какой версией требуется опубликовать npm пакет.

CI/CD переменные

NPM_TOKEN — npm токен.

GIT_USER_EMAIL — email технического пользователя gitlab

GIT_USER_NAME — username технического пользователя gitlab

GIT_SYNC_USER — имя пользователя, которое будет указано в коммите

GIT_SYNC_TOKEN — gitlab токен технического пользователя

CI_PROJECT_PATH — path проекта с включенным именем проекта


Ссылки по теме:

Gitlab CI/CD variables

Gitlab access tokens

Standart-version utility

Semver

Conventional Commits

Predefined Gitlab variables reference


ссылка на оригинал статьи https://habr.com/ru/company/nlmk/blog/598033/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *