Как CI строить ветви в VSTS

#git #continuous-integration #azure-devops #pull-request

#git #непрерывная интеграция #azure-devops #запрос на извлечение

Вопрос:

Мы используем репозитории Git в VSTS с моделью ветвей и запросов на извлечение, чтобы разрешить проверку кода.

У нас есть определение сборки CI и следующее за ним определение выпуска для всех коммитов, переданных в master.

И было бы огромным бонусом, если бы мы могли сделать CI и для всех ветвей. Однако определение сборки для репозиториев Git позволяет настроить только одну ветку для отслеживания.

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

Да, есть возможность указать для запуска сборки CI для PRs для освоения на странице политики ветвей. Но с этим связаны 2 проблемы:

  • это приведет к созданию только PR, в то время как мы хотим создавать все отдельные коммиты в ветвях, как только они будут помещены туда

  • Сборка CI для PRs также запустит наш релиз, но мы, очевидно, хотим, чтобы она запускалась только для мастер-сборок. Да, я могу проанализировать $(Build.SourceBranch) или $(Build.SourceBranchName) в определении выпуска и потерпеть неудачу, если он не «мастер», но в любом случае это приведет к неудачному выпуску, чего я просто хочу избежать вообще

Итак … как мы можем создавать CI в VSTS для любой произвольной ветви?


Обновить

Другая идея, связанная с запуском выпуска только для мастер-сборок, — это инициировать выпуск со стороны сборки, например, с помощью API, если $(Build.SourceBranch) равно «master», скажем, с помощью пользовательского скрипта PowerShell.

Я вижу, что есть даже расширение для шага сборки триггера VSTS, но оно будет срабатывать даже для не-основных сборок, хотя Microsoft работает над функцией для условного выполнения шагов.

Ответ №1:

Вы можете добавить задачу сценария powershell в конце определения сборки, чтобы запустить выпуск через Rest API, я создал простой пример кода для вашей справки:

 if ($env:BUILD_SOURCEBRANCHNAME -eq "master")
{
$collectionuri = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$buildid = $env:BUILD_BUILDID
$project = $env:SYSTEM_TEAMPROJECT
$token = $env:SYSTEM_ACCESSTOKEN
$builddef = $env:BUILD_DEFINITIONNAME
$buildnum = $env:BUILD_BUILDID
$releaseid = 2;

#Generate API URL
$account = "";
$reg = "https:// (?<acc>w ?).visualstudio "
if ($collectionuri -match $reg)
{
    $account = $Matches.acc;
}
else
{
    Write-Host "Fail to get the account name from collection url";
}
$url= "https://"   $account   ".vsrm.visualstudio.com/"  $project   "/_apis/release/releases?api-version=3.0-preview.2"

#Generate Auth info
$basicAuth= ("{0}:{1}"-f "anys",$token)
$basicAuth=[System.Text.Encoding]::UTF8.GetBytes($basicAuth)
$basicAuth=[System.Convert]::ToBase64String($basicAuth)
$headers= @{Authorization=("Basic {0}"-f $basicAuth)}

#Generate body content
$instanceRef = @{id = $buildID};
$artif = @{alias = $builddef; instanceReference = @{id = $buildnum}}
$content = @{
    definitionId = $releaseid
    description = "Triggered from CI Build"
    artifacts = @($artif)
    }
$json = $content | ConvertTo-Json -Depth 100

#Call Rest API to start the release
$responseBuild = Invoke-RestMethod -Uri $url -headers $headers -Method Post -Body $json -ContentType "application/json"
}
else
{
    Write-Host "Not master branch, no release triggered"
}
  

Вам необходимо обновить «releaseid» до идентификатора определения выпуска, которое вы хотите запустить, и в конфигурации безопасности этого определения установите для разрешения «Создавать релизы» значение «Разрешить» для учетной записи «Служба сборки коллекции проектов».

Комментарии:

1. Блестящий сценарий и использование переменных env — делает свое дело! Просто небольшой комментарий — в регулярном выражении я заменил w на [w-], поскольку имя нашей учетной записи содержит дефис.

2. Кроме того, чтобы иметь возможность использовать SYSTEM_ACCESSTOKEN, мне пришлось включить опцию «Разрешить скриптам доступ к токену OAuth» для определения сборки. Не имеет большого значения, но все равно нужно настроить его для всех сборок. Итак, интересно, есть ли способ использовать параметр -UsedefaultCredential для Invoke-RestMethod вместо использования токена доступа? Пытался, но не удалось — он возвращает некоторый HTML с жалобами на улучшенную конфигурацию безопасности Internet Explorer вместо JSON

Ответ №2:

Однако определение сборки для репозиториев Git позволяет настроить только одну ветку для отслеживания.

На самом деле это не так. (Вас может смутить тот факт, что Repository вкладка имеет Default branch параметр, который принимает только одну ветвь.)

В определении сборки перейдите на Triggers вкладку. Continuous Integration Установите флажок, если он еще не установлен.

Branch filters Щелкните Add new filter и установите значение * равным . (Вам будет предложено выбрать существующую ветку, но вы можете проигнорировать это и просто нажать Enter.)

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

Комментарии:

1. Привет, Скотт… Да, понял это после того, как я опубликовал вопрос. Однако это нам не помогает — а) нам нужно постоянно обновлять определение сборки для каждой новой ветки (несколько раз в день); б) Релиз все равно будет запускаться с этими сборками, не являющимися основными.

2. @Ivan Что вы подразумеваете под (a)? Для (b) я создал одно определение сборки, которое запускает выпуск, и одно для всех других ветвей (которое не запускает выпуск).

3. Ха, извините, пропустил вашу точку зрения о star (*), протестировал ее сейчас, и да, она работает! Спасибо.

4. Что касается (b), то мы подумали об этом, чтобы иметь 2 определения сборки для каждого репозитория, но это все равно добавляет немного сложности — для поддержания дополнительного определения, например, когда мы его модифицируем, нам нужно будет сделать это дважды, а также количество определений сборки в проекте VSTS будет увеличено.двойной.

5. Кстати, см. Обновление выше, я задал вопрос об идее запуска выпуска со стороны сборки.

Ответ №3:

Очень, очень просто.

  1. Перейдите на Marketplace и установите GitVersion в VSTS / Azure DevOps https://marketplace.visualstudio.com/items?itemName=gittools.gitversion

  2. Как было описано ранее, измените триггер CI, чтобы отслеживать все ветви: введите описание изображения здесь

    Причина, по которой я также добавляю строку # 2 для отслеживания тегов, заключается в том, что я использую теги GitVersion и git для версии артефакта сборки, когда я буду готов выпустить свой продукт. Когда я применяю и нажимаю тег git, сборка не обнаруживает его, если я явно не укажу ему следить за ним. Мой формат для тега git — «v1.2.3», начинающийся со строчной буквы «v». На всякий случай я хочу применить любой другой тег и не запускать сборку.

  3. Наконец, измените формат номера сборки. Вам нужно определить, какая ветвь строится. GitVersion использует семантическое управление версиями, таким образом, это описывает, что строится.

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

  1. Теперь запустите как можно больше сборок из любого количества ветвей и посмотрите, как все они начинаются с одного определения сборки. Установите один раз и забудьте с этого момента! введите описание изображения здесь

Преимущества:

  • Нет сценариев для поддержки
  • Следуйте семантическому управлению версиями
  • Создайте конвейер / определение сборки один раз, и вам больше никогда не придется беспокоиться о ветвях функций.
  • Все равно будет работать для запросов на извлечение.
  • Подробнее о GitVersion читайте на https://gitversion.readthedocs.io

Секретный соус: GitVersion считывает историю Git, поэтому число увеличивается для каждого коммита git ПОСЛЕ того, как он помечен. Он создает переменные сборки из используемой системы CI и делает их доступными. Он выводит эти переменные и создает псевдоним tag or для ветки, которую он создает, в зависимости от mode того, в какой вы используете GitVersion. В приведенном выше примере у меня были некоторые коммиты (не показаны), когда это была версия 0.1.0 , я пометил ее version 1.0.0 и выпустил ее. Следующий коммит предсказывал, что следующая версия будет 1.1.0 , и в ветке было много коммитов (11 из них) develop . Имя сборки использует псевдоним alpha , поскольку артефакты сборки являются альфа-кандидатами. Было еще 4 коммита. После этого была создана ветвь функций, которая разветвлялась от фиксации # 15, сделала 16-ю фиксацию и нажала на нее, и была собрана. Я думаю, вы поняли идею. Все это происходит из одного конвейера сборки и с использованием GitVersion для описания того, какая ветвь строится и создается коммит. Семантическое управление версиями описывает сборку.