Политики Azure DevOps- Branch приводят к запуску нескольких сборок во время запросов на извлечение

#azure-devops #pull-request #azure-devops-server-2019

#azure-devops #запрос на извлечение #azure-devops-server-2019

Вопрос:

В наших репозиториях есть папки, код в папке иногда зависит от кода в других папках, но только в одном направлении. Для объяснения:

C зависит от B

B зависит от A

У нас есть 3 сборки, необходимые для нашей политики запросов на извлечение для master:

У нас есть сборка (BuildC), которая создает ТОЛЬКО папку C

У нас есть сборка (BuildB), которая строит B и C

У нас есть сборка (BuildA), которая строит A, B и C

Политика определяет:

Изменения в папке C требуют BuildC

Изменения в папке B требуют builddb

Изменения в папке A требуют сборки

Желаемый эффект: в зависимости от случая, я хочу, чтобы для запроса на извлечение требовалась ТОЛЬКО ОДНА из трех сборок. Вот такие случаи:

BuildA — должен запускаться при наличии изменений в папке A (даже если есть изменения в другом месте)

BuildB — должна запускаться при наличии изменений в B (и / или C), но НЕ В A. Если в папке A произошли изменения, эта сборка НЕ должна запускаться

BuildC — должен выполняться, когда изменения вносятся только в папку C … если изменения существуют в папках A и / или B в дополнение к C … эта сборка не должна выполняться.

На самом деле происходит то, что если вы что-то измените в папках A и C, запускаются две сборки: BuildA и BuildC … и если изменения в папке C зависят от папки A, сборка BuildC завершается неудачно. В любом случае запуск buildC является пустой тратой времени.

Есть ли способ поставить Azure DevOps в очередь только на 1 сборку… но лучший. Итак, в нашем примере BuildA будет запущена, но не BuildC … но если бы изменения были только в папке C, она запускала бы Build C?

Ответ №1:

Невозможно выполнить то, что вы хотите, с помощью триггеров сборки или политик. Нет никакого «Не создавать, когда есть изменения в папке X». Однако есть несколько вариантов, но они требуют некоторого переосмысления:

Вариант 1: Используйте задания и условия

  • Создайте единый конвейер со стадией сборки и 4 заданиями.
  • В первом задании используется средство командной строки для определения, какие проекты необходимо перестроить, и устанавливается выходная переменная
  • Остальные 3 задания зависят от первого задания, и для них установлено условие, которое запускается только тогда, когда переменная (установленная в первом задании) имеет определенное значение.

Таким образом, вы можете получить полный контроль над порядком сборки всех 3 проектов.

Вариант 2. используйте конвейер оркестровки

Вариант 3. использовать артефакты конвейера

Вместо построения A B C в сборке C загрузите результаты из A B, затем создайте C. Для этого потребуется загружать артефакты конвейера в конце каждого задания и для каждого последующего задания выполнять инкрементную сборку, загружая эти артефакты и, таким образом, пропуская процесс сборки.

Вы даже можете загрузить «последние успешные» результаты на случай, если захотите пропустить создание кода.

Вариант 4. используйте NuGet

Вместо артефактов конвейера используйте пакеты nuget для публикации выходных данных из сборки A и использования их в сборке B. Или даже опубликуйте A в задании A и используйте его из задания B в том же определении сборки.

Вариант 5. полагаться на инкрементные сборки

Если вы работаете с автономным агентом, вы можете отключить опцию «Очистить» для своего конвейера, чтобы убедиться, что тот же агент ранее создавал вашу сборку, if просто повторно использует выходные данные сборки предыдущего запуска, если ни один из входных файлов не изменился (ивы не внесли никаких неправильных настроек msbuild). По сути, будет пропущено построение A, если msbuild сможет вычислить, что строить A.


Преимущество одной сборки с несколькими заданиями заключается в том, что вы можете указать порядок заданий A, B, C и можете контролировать, что происходит в каждом задании. Большим недостатком является то, что каждое задание увеличивает накладные расходы на извлечение источников или загрузку артефактов. Вы можете немного оптимизировать это, четко установив подстановочные знаки для тех фрагментов, которые вы хотите опубликовать и восстановить.

Если вам не нужны исходные тексты на последующих этапах (и вы не используете конвейеры YAML), вы можете использовать мою задачу «Не синхронизировать исходные тексты» (даже с Git), чтобы пропустить шаг синхронизации, что позволит вам точно контролировать, что происходит в каждом задании.

Многие из этих параметров зависят от того, какие проекты содержат измененные файлы с момента последней успешной сборки. Вы можете использовать утилиты командной строки git или tfvc, чтобы сообщить вам, какие файлы были изменены, но создать идеальный сценарий может быть немного сложнее, если у вас включена пакетная сборка, и в этом случае несколько изменений вызовут вашу сборку одновременно, поэтому вы не можете просто полагаться на «последние изменения». В этом случае вам может потребоваться использовать REST API, чтобы запросить у Azure DevOps все идентификаторы коммитов или все номера наборов изменений, связанные с этой сборкой, чтобы выполнить правильное различие для вычисления того, какие проекты содержат изменения.

В долгосрочной перспективе полагаться на единую сборку с несколькими заданиями или пакетами nuget, вероятно, будет проще в обслуживании.

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

1. #jesshouwing…. Спасибо. Это очень полезно. Я думаю, что вариант № 2 нам подходит…. Это позволит нам всегда требовать одну сборку («конвейер оркестровки», который выберет правильную сборку для сборки. Поскольку я никогда не хочу создавать более одной (мы уже 3 и 4 обрабатываем зависимые сборки без необходимости перестраивать библиотеки, от которых они зависят), я не получаю выгоду от «нескольких сборок»