Установка тега Git из конвейера сборки Azure Devops по завершении

Я пытаюсь установить тег с текущим номером версии, определенным GitVersion в коммите GIT в конце успешной сборки. Похоже, я не могу быть первым, кто сделает это, но я изо всех сил пытаюсь найти что-то, что работает.

В Azure Devops Pipeline есть функция Получение источников для тегов источников в случае успеха. Я установил это и установил переменную, которая задается одной из задач агента, которые у меня есть (GitVersion)

Источники тегов

В журналах отладки я вижу, что эта переменная устанавливается компонентом GitVersion, который я добавил в конвейер.

2019-12-06T20:54:20.2390794Z ##[debug]Processed: ##vso[task.setvariable variable=GitVersion.MajorMinorPatch;]2.98.0

Однако, если я оставлю это так, я получу тег, созданный как v $ (GitVersion.MajorMinorPatch), что означает, что на момент создания тега эта переменная больше не существует.

Во всплывающей подсказке по формату тегов говорится:

Формат тега может представлять собой комбинацию определенных пользователем или предварительно определенных переменных, имеющих область действия Все. Например: '$ (Build.DefinitionName) $ (Build.DefinitionVersion) $ (Build.BuildId) $ (Build.BuildNumber) $ (My.Variable)'

Итак, я предполагаю, что проблема в том, что эта переменная, созданная во время конвейера, не имеет области действия All.

Затем я попытался добавить переменную конвейера в конвейер GitVersion.MajorMinorPatch с надеждой, что это было в правильной области, и надеясь, что при запуске команды task.setvariable это установит значение переменной этой переменной с более высокой областью действия.

введите описание изображения здесь

Однако в этом случае я только что создал тег v.

Так что я немного застрял. Каким-то образом мне нужно иметь возможность динамически создавать или устанавливать переменную в области ВСЕ со значением, которое я хочу отметить здесь.

Буду очень благодарен за любые идеи по этому поводу.


person Brett    schedule 07.12.2019    source источник
comment
Вы пробовали установить $(Build.BuildNumber) на желаемое значение? Затем установите это значение тега? Для установки номера сборки требуется другая команда ведения журнала: build.updatebuildnumber вместо task.setvariable. См .: stackoverflow.com/a/37048559/736079   -  person jessehouwing    schedule 07.12.2019
comment
да, это, вероятно, было бы уловкой, чтобы обойти это   -  person 4c74356b41    schedule 07.12.2019
comment
Это не решение использовать Build.BuildNumber для того, что я хочу здесь сделать. Мне нужно, чтобы BuildNumber был глобально уникальным (например, v2.19.1-b23), и этот тег должен быть проще - просто v2.19.1   -  person Brett    schedule 09.12.2019


Ответы (3)


Если вы делаете конвейер yaml, вы можете добавить следующие шаги

- checkout: self
  persistCredentials: true

## Rest of pipeline ##

- script: |
     git tag $(GitVersion.NugetVersionV2)
     git push origin $(GitVersion.NugetVersionV2)
  workingDirectory: $(Build.SourcesDirectory)

persistCredentials позволяет автоматически передавать токен другим командам git. Обратите внимание на присвоение workingDirectory, в противном случае у меня была ошибка, что местоположение не было репозиторием git.

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

- script: |
     git tag -a <tagname> -m <message>

Чтобы получить против него пользователя / дату, вам необходимо также укажите имя пользователя / адрес электронной почты, например

- script: |
    git config --global user.name "BuildService"
    git config --global user.email "[email protected]"
    git tag -a <tagname> -m <message>

Чтобы это работало, необходимо, чтобы Сервер сборки проекта (а не Учетные записи службы сборки проекта ) получить разрешение на участие в репозиториях

person Paul Hatcher    schedule 21.03.2020
comment
Для тех, кто интересуется, как настроить учетную запись Project Collection Build Server, ее можно найти в разделе Project Settings ›Repos› Repositories. Когда вы нажимаете репо, вы должны найти эту учетную запись в списке пользователей. - person akokskis; 29.03.2020
comment
Вы также можете нажать на Репозитории, чтобы установить его для всех репозиториев в проекте. - person Paul Hatcher; 29.03.2020
comment
Я потратил 5 секунд на чтение и обнаружил, git push --follow-tags это не более уместно? - person sommmen; 18.11.2020
comment
@sommmen Если вы посмотрите на stackoverflow.com/questions / 3745135 / упоминается, что -follow-tags подталкивает только аннотированные теги, а не легковесные, поэтому, поскольку указанный ответ работает для обоих, я не думаю, что он требует изменения - person Paul Hatcher; 18.11.2020
comment
workingDirectory: $(Build.Repository.LocalPath) - это то, что у меня сработало. - person ChaoticCoder; 15.02.2021

Продолжая отличный ответ Пола Хэтчера, я хотел бы добавить, что для меня учетная запись была названа Project Collection Build Service в Azure DevOps Server 2019. Это также похоже на текущую документация Microsoft.

Извините за ответ, моей репутации пока не хватает на комментарий.

person MatthiasSchuchardt    schedule 20.08.2020

В журналах отладки я вижу, что эта переменная устанавливается компонентом GitVersion, который я добавил в конвейер.

Переменная GitVersion.MajorMinorPatch, которую вы видели в журнале, является переменной уровня шага, что означает, что ее жизненный цикл начинается только с текущей GitVersion задачи.

введите описание изображения здесь

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


Фактически, на основе GitVersion task логики компиляции и работы, значение GitVersion.MajorMinorPatch создается и сохраняется как build number текущей сборки:

введите описание изображения здесь

Итак, наиболее удобный способ пометить значение GitVersion.MajorMinorPatch для репозиториев - использовать $ (Build.BuildNumber):

v$(Build.BuildNumber)

введите описание изображения здесь

И вот мой результат:

введите описание изображения здесь


Обновление:

Чтобы добавить GitVersion.MajorMinorPatch, созданный задачей GitVersion, в переменные, примените приведенные ниже сценарии к задаче PowerShell:

$connectionToken="{PAT Token}"
$urlget = "https://dev.azure.com/{org}/{project}/_apis/build/definitions/$(System.DefinitionId)?api-version=5.1"
$base64AuthInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$getdef = Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET -ContentType application/json -Uri $urlget 
Write-Host Pipeline = $($getdef | ConvertTo-Json -Depth 100)
$bvalue=@"
    {
      "value": "$(GitVersion.MajorMinorPatch)"
    }
"@
$getdef.variables | add-member -Name "GitVersion.MajorMinorPatch" -value (Convertfrom-Json $bvalue) -MemberType NoteProperty -Force -PassThru

$getdef = $getdef | ConvertTo-Json -Depth 100
$getdef | clip
$urlput = "https://dev.azure.com/{org}/{project}/_apis/build/definitions/$(System.DefinitionId)?api-version=5.1"
$putdef = Invoke-RestMethod -Uri $urlput -Method PUT -Body $getdef -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

Как я упоминал ранее, я все еще не думаю, что можно указать $(GitVersion.MajorMinorPatch) в Tag format.

По-прежнему настоятельно рекомендую вам, позвонив $(Build.BuildNumber), пометить значение $(GitVersion.MajorMinorPatch).

person Merlin Liang - MSFT    schedule 08.12.2019
comment
Major.Minor.Patch не является глобально уникальным, поэтому он не подходит для номера сборки, есть много коммитов, которые будут иметь одно и то же значение .. GitVersion.MajorMinorPatch доступен для всех будущих шагов в задании, поскольку я могу создать задача PS и вывести текущий $ (GitVersion.MajorMinorPatch). Это просто недоступно. Кажется излишним ограничением формата тега, что вы вообще не можете использовать какие-либо пользовательские переменные (это не то, что подразумевает документ)? - person Brett; 09.12.2019
comment
@Brett, (нужно извиниться за мою точку зрения на мой ответ, внес некоторые изменения). Да, "Major.Minor.Patch" не является модулем в конвейере, но для конвейера, который использует GitVersion.MajorMinorPatch, его значение уникально для GitVersion.yml. Что касается интересующей вас головоломки: кажется излишним ограничением формата тега, что вы вообще не можете использовать какие-либо пользовательские переменные. НЕТ, мы не устанавливали это ограничение для конвейера, вы можете настроить переменную на вкладке «Переменные» и установить для нее значение. Затем примените эту переменную в пустом теге. - person Merlin Liang - MSFT; 09.12.2019
comment
Вы могли видеть, что значение переменной было помечено в репозиториях. Почему ваша вторая попытка не имеет значения, это потому, что вы не установили значение на вкладке «Переменные». Здесь переменная, которая может быть помечена для репозиториев, должна быть предварительно определенной переменной, включая настраиваемые переменные, определенные на вкладке «Переменные». Когда вы используете GitVersion, его значение будет иметь приоритет над номером сборки. В этом логика данной задачи. Итак, я предлагаю вам использовать вызов $ (Build.BuildNumber), чтобы пометить репозитории. - person Merlin Liang - MSFT; 09.12.2019
comment
Спасибо за обновления. Нет ли способа создать переменную с областью ВСЕ во время выполнения или создать заранее и изменить значение этой переменной во время выполнения? Если бы я мог это сделать, я мог бы решить эту проблему, и на самом деле, если я не могу этого сделать, то возможность использовать определяемую пользователем переменную ограничена, поскольку вам нужен человек, чтобы установить значение перед выполнением, что означает, что трудно автоматизировать ? Это не решение использовать Build.BuildNumber для того, что я хочу здесь сделать. Мне нужно, чтобы BuildNumber был глобально уникальным (например, v2.19.1-b23), и этот тег должен быть проще - просто v2.19.1 - person Brett; 09.12.2019
comment
@Brett Конечно, есть такой способ, но вам нужно вызвать один api, чтобы создать эту переменную, которая будет доступна для всех. Вы знаете, что если вы создадите или переопределите значение существующего, оно будет ограничиваться только заданием агента. Мы назвали эту переменную времени выполнения. Чтобы изменить существующее значение переменной или создать новое, нам нужно использовать Api для этого. Вам это подходит? Если да, я поделюсь с вами примером того, как этого добиться с помощью PowerShell. - person Merlin Liang - MSFT; 09.12.2019
comment
Да, пожалуйста, Мерлин, мне было бы интересно, как я могу создавать / управлять этими переменными с более широким охватом. Жаль, что у set-variable нет такой возможности. - person Brett; 09.12.2019
comment
@Brett, извините за задержку ответа на личную занятую работу. Смотрите мои обновленные скрипты. Но, как я уже упоминал, я все еще не думаю, что указание $(GitVersion.MajorMinorPatch) будет доступно в теге. - person Merlin Liang - MSFT; 12.12.2019