В настоящее время мой конвейер DevOps использует два сервера для параллельной работы:
jobBuildAll на сервере 1:
jobBuildAll на сервере 2:
Это большой проект Windows C++, каждый сервер занят более 8 часов: отладочная сборка занимает около 2 часов, юнит-тесты — 6 часов, релизная сборка — 4 часа и еще 4 часа на статический анализ кода.
Еще мне нужно провести функциональные тесты на выделенном третьем сервере, они занимают около 6 часов.
Я хотел бы сделать следующее:
Насколько я знаю, не существует «официального» способа, есть ли какой-нибудь, хотя и неофициальный, способ добиться этого?
Справедливо, @rui-jarimba, отредактировал вопрос соответствующим образом.
Где находятся артефакты, необходимые для создания функциональных тестов? В части отладочной сборки?
Да, артефакты, необходимые для функциональных тестов, — это исполняемые файлы и библиотеки DLL, созданные во время отладочной сборки.
Артефакты, необходимые для функциональных тестов, — это исполняемые файлы и библиотеки DLL, созданные во время отладочной сборки.
Отладочная сборка занимает около 2 часов, но артефакты, необходимые для функциональных тестов, создаются за 1 час, что меньше.
Следовательно, если вы хотите публиковать артефакты и запускать задание функционального тестирования сразу после их создания, вы можете рассмотреть следующие варианты:
Если возможно, разделите задачу сборки отладки на два или более заданий. Если ваши артефакты генерируются в задании1, то задание функционального тестирования — это задание1. Как только после завершения задания 1 будут созданы артефакты, начнется задание функционального тестирования.
Другой вариант — вы можете поместить функциональные тесты в dependsOn
. Поскольку вы используете локальный агент, вы можете создавать артефакты в новой папке, которую контролирует новый конвейер; это изменение запустит конвейер функционального тестирования.
Как и в случае с вариантом 2, вы можете сгенерировать артефакт на определенном этапе в 1-й сборке, а в новом конвейере использовать триггер завершения конвейера ресурсов для мониторинга new pipeline
, после его завершения запустить конвейер функционального тестирования.
Спасибо, @wade-zhou-msft, особенно варианты 2 и 3 звучат очень многообещающе. Если я использую новый конвейер для функциональных тестов, могу ли я затем получить результат (конвейер прошел успешно или нет) в качестве входных данных в основной конвейер? Только если и модульные, и функциональные тесты (выполняющиеся на разных серверах/агентах) прошли успешно, я хочу перейти к развертыванию.
Поскольку вы используете локальные агенты, вы можете поместить результат в файл в конце конвейера. Добавьте шаг для чтения содержимого файла, чтобы определить, запускать развертывание или нет.
Чтобы ответить на мой собственный вопрос, поскольку это может помочь кому-то с подобной проблемой:
На Azure DevOps Server я создаю большой проект. Отладочная сборка и модульные тесты выполняются на одном сервере1, сборка выпуска и статический анализ кода — на сервере2. Каждый сервер занят часами, фактические сборки занимают примерно половину времени на каждом сервере. После завершения отладочной сборки на сервере1 и до начала модульных тестов я хочу запустить функциональные тесты на сервере3, они также выполняются часами. Конечно, я мог бы разделить задания, чтобы знать, когда сборка завершится, но тогда модульные тесты могли бы находиться в другом каталоге агента, и мне пришлось бы публиковать и загружать огромное количество файлов.
Итак, задача заключалась в том, чтобы начать работу изнутри другой работы. Моё решение не идеальное, но работающее: Задание FunctionalTests запускается параллельно с двумя заданиями сборки. Когда фактическая сборка на сервере1 завершена, он публикует артефакты, записывает файл триггера на сервер3 и запускает все модульные тесты. Задание на сервере3 просто ждет, пока не будет найден файл триггера, затем загружает артефакты сборки и запускает функциональные тесты с новыми файлами.
stages:
- stage: stageBuildWithoutAnalysis
# =========================
displayName: 'Build, no analysis'
pool:
demands: server1
jobs:
- template: /Jobs/jobBuild-All.yml
parameters:
configuration: Debug
staticAnalysis: false
- stage: stageBuildWithAnalysis
# ===================
displayName: 'Build with static analysis'
dependsOn: []
pool:
demands: server2
jobs:
- template: /Jobs/jobBuild-All.yml
parameters:
configuration: Release
staticAnalysis: true
- stage: stageFunctionalTests
# ====================
displayName: 'Functional Tests (after build)'
dependsOn: []
pool:
demands: server3
condition: ${{ parameters.runFunctionalTests }}
jobs:
- job: jobFunctionalTests
steps:
- checkout: none
- script: del C:\trigger.txt
- task: PowerShell@2
displayName: 'Wait for build to complete'
inputs:
targetType: 'inline'
script: |
While (!(Test-Path C:\trigger.txt -ErrorAction SilentlyContinue))
{
Start-Sleep -Seconds 60
# Do until trigger file has been created by build job
}
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
echo Running functional tests!
- stage: stageDeploy
# ===========
displayName: 'Deployment/Reports'
dependsOn:
- stageBuildWithoutAnalysis
- stageBuildWithAnalysis
- stageFunctionalTests
pool:
demands: server1
jobs:
- template: /Stages/stageDeploy.yml
Он работает довольно хорошо, с контролем этапов для ручного запуска:
Просто из любопытства, какой код вы создаете? Java, .NET, ...? Сколько времени занимает каждый компонент — создание артефактов, необходимых для функциональных тестов, построение кода, запуск модульных тестов, анализ кода? Было бы здорово, если бы вы отредактировали свой вопрос, указав эти данные. Возможно, мы сможем вам помочь, если у нас будет немного больше контекста.