Build.SourceVersion пуст в VSO vNext Build

Я использую новые функции сборки с поддержкой сценариев в Visual Studio Online (а не определения сборки XAML) и пытаюсь, чтобы номер версии сборки включал последний идентификатор фиксации Git целевого репозитория с использованием формата номера сборки.

Я использую следующий формат номера сборки:

$(MajorVersion).$(MinorVersion).$(BuildId).$(SourceVersion)

Это приводит к сгенерированному номеру версии 1.0.1234., т. е. значение SourceVersion пустое, что вызывает ошибку в VSO при постановке сборки в очередь. Я также попытался квалифицировать переменную, добавив к ней префикс Build. с тем же результатом. Для проверки я изменил номер сборки на следующий формат:

$(MajorVersion).$(MinorVersion).$(BuildId).$(SourceBranch)

Это правильно приводит к значению 1.0.1234.refs_heads_master

Я использовал Предопределенные переменные ссылка, а Build.SourceVersion указан как глобальная переменная.

Я делаю что-то не так, столкнулся с ошибкой или это так задумано и недоступно во время постановки сборки в очередь? Если это задумано, есть ли способ автоматически включить короткий идентификатор Git Commit ID в формат номера сборки?

Здесь я установил формат номера сборки в VSO: Здесь я устанавливаю формат номера сборки в VSO

Это ошибка, которую я вижу, когда явно не указываю Git CommitId:

400: Строка формата номера сборки $(MajorVersion).$(MinorVersion).$(BuildId).$(SourceVersion) сгенерировала номер сборки 0.1.1. который содержит недопустимые символы, слишком длинный или заканчивается на '.'. Максимальная длина номера сборки составляет 255 символов. К недопустимым символам относятся '"', '/', ':', '‹', '>', '\', '|', '?', '@' и '*'.


person GaryJL    schedule 16.09.2015    source источник
comment
Я могу добиться того, что вы описали с помощью $(MajorVersion).$(MinorVersion).$(Build.BuildId).$(Build.SourceVersion). Только что проверили как VSO, так и TFS 2015 в локальной среде. Вывод выглядит так: 1.0.20.41f2983578f720695227a7a8a41ed3d7437efc30. Вы уверены, что это не опечатка, вызывающая такое странное поведение на вашей стороне?   -  person Yan Sklyarenko    schedule 17.09.2015
comment
@YanSklyarenko, я всегда получаю исключение Невозможно развернуть макрос $(Build.SourceVersion), указанный в формате номера сборки (тип InvalidMacroInBuildNumberException), если я использую $(MajorVersion).$(MinorVersion).$(Build.BuildId).$( Build.SourceVersion), чтобы определить формат номера сборки. Кроме того, переменная SourceVersion представляет собой последнее изменение системы управления версиями, включенное в эту сборку. CommitId или номер набора изменений (например, CS1234), который не должен быть чем-то вроде «41f2983578f720695227a7a8a41ed3d7437efc30». Я пропустил что-то важное?   -  person Vicky - MSFT    schedule 18.09.2015
comment
@ Вики, хм, полагаю, это другое дело. Похоже, это исключение (InvalidMacroInBuildNumberException) означает, что формат номера сборки недействителен. Я имею в виду, что он ожидает, что Major.Minor.Build.Revision будут числами, а не этими идентификаторами и хэшами. Макрочасть $(Build.SourceVersion) работает, но вы не можете использовать ее в номере сборки. Другой ваш комментарий: идентификатор фиксации в Git — это длинный хеш, CS1234 — это формат набора изменений TFVC.   -  person Yan Sklyarenko    schedule 18.09.2015
comment
@YanSklyarenko Я пробовал и $(Build.SourceVersion), и только $(SourceVersion), и оба привели к пустому значению, если только я явно не указал полный идентификатор фиксации Git при постановке сборки в очередь. Поскольку это для непрерывной интеграции, мне нужно, чтобы последний идентификатор Git Commit был получен автоматически. В идеале я бы тоже хотел короткий хэш. Я должен уточнить, что это в формате номера сборки в VSO Scriptable Build (vNext), а не в определениях сборки XAML.   -  person GaryJL    schedule 18.09.2015
comment
@GaryJL, теперь я в замешательстве. Возможно, если бы вы сделали скриншот, было бы понятнее...   -  person Yan Sklyarenko    schedule 18.09.2015
comment
@YanSklyarenko Добавил скриншот к вопросу и ошибку, которую я вижу при постановке сборки в очередь.   -  person GaryJL    schedule 18.09.2015
comment
Хорошо, теперь я могу воспроизвести это. Кажется, что набор доступных токенов отличается для формата номера сборки. Я бы сказал, что предложение @Vicky является единственно возможным, если вам нужно придерживаться этого подхода к исходной версии. Кроме того, вы можете пересмотреть свою политику управления версиями, следуя этим рекомендациям вместо этого.   -  person Yan Sklyarenko    schedule 18.09.2015


Ответы (3)


Я смог использовать $(Build.SourceVersion), но только тогда, когда сборки запускались автоматически при фиксации (при непрерывной интеграции). Он оказывается пустым, только если я ставлю его в очередь вручную:

Снимок экрана очереди сборки

Я использую следующий формат номера сборки:

$(BuildDefinitionName)_$(date:yyyyMMdd)_$(Build.BuildId).$(Build.SourceVersion)$(rev:.r)
person neogarrigus    schedule 12.04.2016
comment
@MonDeveloper Да, он автоматически заполняется в сборках, запускаемых CI, когда я использую указанную выше строку формата. Также кажется возможным указать исходную версию при постановке сборок в очередь вручную, подробности см. В ответе Уилла. - person neogarrigus; 01.02.2017

NeoGarRiGus — получается пустым, потому что при запуске ручной сборки приходится вводить поле Source Version, чтобы оно заполнилось. CI вводит это значение автоматически, когда Dev проверяет, но когда вы ставите сборку в очередь вручную, во всплывающем окне появляется пустое поле, которое позволяет вам ввести исходную версию:

Поле исходной версии в VSTS

person Will    schedule 17.08.2016

Боюсь, он не может использовать $(SourceVersion) в формате номера сборки. Однако я думаю, что вы можете использовать PowerShell, чтобы изменить номер сборки на $(SourceVersion), и вам нужно включить PowerShell в процесс сборки. Проверьте эту ссылку для деталей.

И вы можете определить PowerShell, чтобы он был похож на:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
[System.Reflection.Assembly]::LoadWithPartialName("System.Net")

[String] $CollectionUrl = "https://vsoserver.visualstudio.com/defaultcollection"
[String] $BuildUrl = $env:BUILD_BUILDURI 

$netCred = New-Object System.Net.NetworkCredential("username","password")
$basicCred = New-Object Microsoft.TeamFoundation.Client.BasicAuthCredential($netCred)
$tfsCred = New-Object Microsoft.TeamFoundation.Client.TfsClientCredentials($basicCred)


$teamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($CollectionUrl,$tfsCred)

$buildServer = $teamProjectCollection.GetService([type]"Microsoft.TeamFoundation.Build.Client.IBuildServer")

$buildDetail = $buildServer.GetBuild([Uri]$BuildUrl)

$buildDetail.BuildNumber = $Env:BUILD_SOURCEVERSION 

$buildDetail.KeepForever = $true
$buildDetail.Save()
person Vicky - MSFT    schedule 17.09.2015
comment
Это выглядит полезным. Я буду иметь это в виду, если не найду решение с использованием предопределенных переменных. - person GaryJL; 18.09.2015
comment
Я бы сказал, что это единственное возможное решение на данный момент. - person Yan Sklyarenko; 18.09.2015
comment
Привет @Yan, я использую ваше решение, но получаю сообщение об ошибке System.InvalidOperationException: для базовой аутентификации требуется безопасное соединение с сервером. Прямо в этой строке IBuildDetail buildDetail = buildServer.GetBuild(BuildUrl); - person Orn Kristjansson; 17.12.2015
comment
Ну, не совсем мое решение... @vicky-msft, у вас есть предложение? - person Yan Sklyarenko; 17.12.2015