Как увеличить версию пакета npm с помощью конвейера Azure Devops

Конвейер запускается новыми коммитами в masterветвь и публикует пакет.
В настоящее время версия устанавливается вручную, и я буду рад, если она будет установлена ​​автоматически.
Сначала я подумал, что нужно добавить в конвейер следующие задачи:

  1. проверять, выписываться $Build.SourceBranch
  2. пробег version patch --force
  3. git push

Это работает, и версия действительно увеличивается правильно, дело в том, что это запускает еще один запуск конвейера, который снова будет увеличиваться, что... вы понимаете, бесконечный цикл.
Есть ли лучший способ сделать это?

3 ответа

Решение

Я добавил те же задачи, что и в вопросе, с небольшим изменением.
По-видимому, есть способ пропустить запуск конвейера, см. Здесь

Так что npm version задача выглядит так:

version patch -m "Bump version to %s [skip ci]" --force

что предотвращает запуск следующей сборки.

СОВЕТ: не забудьте предоставить права автора (пользователя Azure DevOps) для Bypass policies when pushing если есть.

Вот моя реализация в Powershell, которая представляет собой полный шаг на основе принятого ответа. Обратите внимание, что это также решает некоторые проблемы с git, такие как отсоединенная голова, которая возникает при таком подходе.

steps:
- checkout: self
  persistCredentials: true
.
.
.
    - task: PowerShell@2
      displayName: 'Bump the version'
      inputs:
        targetType: 'inline'
        script: |
          $BranchName = "$(Build.SourceBranch)" -replace "refs/heads/"
          git checkout $BranchName
          git config --global user.email "anymail@anycompany.com"
          git config --global user.name "Your name"
          npm version prerelease -m "Auto increment pre-release version to %s [skip ci]" --force
          git push

Не используйте файлы в исходном репозитории для отслеживания текущей / следующей версии. Я не думаю, что вы легко сможете разорвать петлю, если это так.

Возможно, вам удастся сбежать npm --no-git-tag-version versionчтобы увеличить версию package.json внутри агента сборки без фиксации, чтобы у вас не было изменений, которые вам пришлось бы отправить обратно в источник. Следует просто изменить package.json и оставить его грязным.

Подождите, пока сборка не завершится успешно. Используйте настраиваемую задачу сценария для извлечения версии из package.json, затемgit reset --hard(нет причин хранить что-либо, что было изменено на сервере сборки). Хотя это отменит изменение в package.json, теперь вы можете создать тег в заголовке, содержащий эту версию, а затем выполнитьgit push origin {tag-name} который не должен вводить новую фиксацию в источнике, которая затем повторно запускает ваш конвейер.

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

Последовательность задач в вашем конвейере:

[Учитывая репозиторий исходного кода, в котором вы установили основную и вспомогательную версии в package.json, чтобы отразить текущее состояние кода в соответствии с правилами семантического управления версиями, и оставьте значение патча всегда равным 0, и, если желаемый, используя значения перед знаком * для описания качества основного / второстепенного значения:]

  1. (На самом деле это не задача, а просто описание начала выполнения:) Работа запускается. Код автоматически переносится из исходного репозитория в агент сборки.
  2. Используя задачу командной строки и код или сценарий, который вы пишете, запустите git describe --tagsчтобы найти последнюю метку с тэгом, соответствующим шаблон вы используете (см. ниже) (Я предпочитаю эту последовательность вызовуnpm version from-gitпотому что npm будет просто использовать последний тег, который может не быть номером версии, в зависимости от того, насколько вы контролируете ветку.) Используйте операции со строками или регулярными выражениями для извлечения основного, второстепенного, патча и любого другого значения до * Ты можешь иметь. Это предыдущая версия, которую мы будем использовать для сравнения с тем, что находится в файле package.json. Обратите внимание, что вам, возможно, придется следовать этим инструкциям, чтобы запустить команду git. Сохраните его в переменной конвейера.
  3. Используя задачу командной строки и код или сценарий, который вы пишете, запустите npm versionчтобы получить текущую основную / вспомогательную / предварительную версию из файла package.json и сохранить ее в другой переменной конвейера. Я использую PowerShell Core, поэтому моя команда для создания переменной конвейера currentPackageVersion будет выглядеть примерно так:

    & npm.cmd version | ConvertFrom-Json | Select-Object -ExpandProperty {name-of-your-package} | Set-Variable -Name 'packageVersion' | Write-Output "#vso[task.setvariable variable=currentPackageVersion]$packageVersion"
    
  4. Используя задачу командной строки служебной программы и код или сценарий, который вы пишете, сравните основные, второстепенные и предварительные * значения предыдущей версии, чтобы определить, изменились ли какие-либо из них. Задайте новую переменную конвейера, чтобы отразить, изменилась она или нет. Я буду использовать имя "restartVersionPatchNumber", которое будет истинным, если текущие основные, второстепенные или предварительные * значения отличаются от основных, второстепенных или предварительных * значений предыдущей версии.

  5. Задача npm условно запускает пользовательскую команду:npm --no-git-tag-version version patch, который обновляет package.json в агенте сборки, но не фиксирует изменение, оставляя вашу рабочую область измененной (грязной) (что может вызвать проблемы при последующих сборках, если вы используете свои собственные агенты сборки вместо размещенных агентов). Условие выражение задачи использует пользовательское условие, что имеет значение переменной, что я просто установить на предыдущем шаге ("restartVersionPatchNumber"). Обратите внимание: если эта задача не выполняется, она должна просто использовать значение версии, которая находится в файле package.json (текущая версия, которая теперь находится в переменной конвейера "currentPackageVersion").
  6. Используя задачу командной строки и код или сценарий, который вы пишете, запустите npm versionдля извлечения новой версии, заданной командой npm version. Сохраните его в новую переменную конвейера; Я назову его "newVersionNumber".
  7. Выполняются обычные задачи сборки, создавая артефакты и, возможно, публикуя их.
  8. Используя служебную задачу командной строки, запустите git reset --hard. Вам нужно будет сделать это, даже если вы используете размещенный агент сборки, из-за следующего шага.
  9. Используя служебную задачу командной строки, создайте переменную из сохраненного номера версии ("newVersionNumber"), которая содержит значение тега тега, который вы хотите использовать. Используйте характерный шаблон, например "AzPipelineBuild-PipelineName-PackageVersion-1.0.0", но используя вашу версию вместо 1.0.0.
  10. Используя служебную задачу командной строки, запустите git tag {*tagname*}. Для PowerShell синтаксис будет& git.exe tag $env:newVersionNumber
  11. Используя служебную задачу командной строки, запустите git push origin {*tagname*}
  12. Прибыль

Вы можете (а может быть, должны) объединить шаги командной строки. Я действительно неравнодушен к задаче PowerShell, запускающей PowerShellCore (pwsh), как вы уже догадались.

Пакет, созданный как артефакт задания, будет иметь обновленную версию, которая была создана в сборке, и будет соответствовать тегу, который сейчас находится в вашем исходном репозитории исходного кода.


В качестве альтернативы используйте внешний источник (функцию Azure и т. Д.) Или другое (второе) репозиторий git или даже другую ветку, не привязанную к вашему триггеру CI в вашем проекте, который вы используете только для отслеживания номеров сборок, затем используйте токен задачи замены, чтобы установить версию непосредственно перед началом сборки. Мне эта идея не очень нравится, но это предотвратит повторный запуск новой сборки.


Кроме того, вы надеетесь создать только один пакет с этим репо. Следующее, что нужно сделать, - это опубликовать этот пакет в фиде Azure Artifacts, на npmjs.org или в другом месте. Не полагайтесь на то, что версия встроена в исходный код; все, что зависит от этого пакета, должно извлекать его из канала, в котором вы его опубликовали, а не полагаться на то, что он был собран ранее на этапах сборки с новым номером версии.

Другие вопросы по тегам