- PVSM.RU - https://www.pvsm.ru -
Всем привет! Сегодня я расскажу как реализовать автоматическую публикацию 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
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
NPM_TOKEN
- имя ci переменной, в которой хранится npm токен
Более подробно про access tokens в npm можно прочитать в документации [1].
Более подробно ознакомиться с gitlab переменными можно здесь [2]
Для конфигурации 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
Данные команды установят зависимости и соберут наш проект.
Для генерации CHANGELOG файла мы используем библиотеку standard-version [3].
При запуске команды standard-version
происходит следующее:
Вычисляется новая версия npm пакета в соответствие с conventional commit [4] и semver [5]
Обновляется версия пакета в 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
то будет создан новый коммит. Такое поведение связано с тем, что к изменяемому коммиту привязан тег. Чтобы решить эту проблему мы удаляем тег, далее меняем сообщение коммита, а потом создаем тег на измененном коммите.
Для обновления кодовой базы нам требуется внести изменения в 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 токены можно прочитать тут [6])CI_PROJECT_PATH
- предопределенная переменная, в которой хранится path проекта с включенным именем проекта. Более подробно со списком доступных переменных можно ознакомиться в документации [7]
# Публикация в npm
- yarn publish --new-version $version --verbose
При публикации пакета используется переменная $version
, в которой сохранена новая версия пакета. Мы явно указываем с какой версией требуется опубликовать npm пакет.
NPM_TOKEN
- npm токен.
GIT_USER_EMAIL
- email технического пользователя gitlab
GIT_USER_NAME
- username технического пользователя gitlab
GIT_SYNC_USER
- имя пользователя, которое будет указано в коммите
GIT_SYNC_TOKEN
- gitlab токен технического пользователя
CI_PROJECT_PATH
- path проекта с включенным именем проекта
Semver [5]
Автор:
PetePearl
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/370865
Ссылки в тексте:
[1] документации: https://docs.npmjs.com/creating-and-viewing-access-tokens
[2] здесь: https://docs.gitlab.com/ee/ci/variables/#list-all-environment-variables
[3] standard-version: https://www.npmjs.com/package/standard-version
[4] conventional commit: https://www.conventionalcommits.org/en/v1.0.0/
[5] semver: https://semver.org/
[6] тут: https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html
[7] документации: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
[8] Источник: https://habr.com/ru/post/598033/?utm_source=habrahabr&utm_medium=rss&utm_campaign=598033
Нажмите здесь для печати.