После перемещения всего YAML в отдельный репозиторий Git у меня возникла странная проблема: теперь с каждым заданием в конвейере каталоги агентов меняются. Первое задание использует _work\1, второе _work\2 и т. д., что означает, что все задания, кроме первого, завершаются неудачей, поскольку каталоги пусты.
Я использую конвейер для конкретного продукта, который расширяет базовый конвейер (спасибо @rui-jarimba за отличное предложение!).
Немного сокращенный код:
# FOO-pipeline.yml
name: QEC-${{ parameters.productVersion }}-$(Date:yyMMdd)$(Rev:rr)
resources:
repositories:
- repository: FOO
type: git
name: FOO
ref: main
trigger:
branches:
include:
- main
- repository: YAML
type: git
name: YAML-Automation
ref: main
trigger:
- none
extends:
template: /Base-pipeline.yml
parameters:
productName: FOO
Этапы Build_with_anaанализ/Build_without_anaанализ используют _work\1 на обоих агентах, все работает отлично (после того, как я объединил разные задания сборки в одно).
Затем этап Test_All использует _work\2, следующий этап использует _work\3 и т. д.
# Base-pipleine.yml
parameters:
- name: productName
displayName: Name of the product to build
type: string
stages:
- stage: Build_without_analysis
# ======================
displayName: 'Build ${{ parameters.productName }}, no analysis'
pool:
demands: BuildServer
jobs:
- template: /Jobs/jobBuild-All.yml
parameters:
productName: ${{ parameters.productName }}
configuration: Debug
staticAnalysis: false
- stage: Build_with_analysis
# ===================
displayName: 'Build ${{ parameters.productName }}, with analysis'
dependsOn: []
pool:
demands: AnalysisServer
jobs:
- template: /Jobs/jobBuild-All.yml
parameters:
productName: ${{ parameters.productName }}
configuration: Release
staticAnalysis: true
- stage: Test_All
# ========
displayName: 'All tests ${{ parameters.productName }}'
dependsOn: Build_without_analysis
pool:
demands: BuildServer
jobs:
- template: /Jobs/jobTests-All.yml
parameters:
productName: ${{ parameters.productName }}
# jobTests-All.yml
parameters:
- name: productName
type: string
default: FOO
jobs:
- job: Run_all_unit_tests
# ==================
displayName: 'All Unit Tests'
steps:
- checkout: none
- template: /Jobs/${{ parameters.productName }}/jobTests-${{ parameters.productName }}-UnitTests.yml
parameters:
configuration: Debug
В чем может быть причина?
Не удалось найти ничего связанного ни в документации Microsoft, ни где-либо еще в Интернете.
Я не вижу подробностей о ваших заданиях, то есть о том, как вы устанавливаете пути к своим файлам или папкам. По очевидным причинам (см. мой предыдущий комментарий) вы всегда должны использовать пути в сочетании с предопределенными переменными , такими как $(System.DefaultWorkingDirectory)/path/to/my/folder
, вместо жестко закодированных путей, поскольку они могут меняться от агента к агенту. Никогда, никогда не используйте жестко запрограммированные пути, такие как \\\server1\DevOpsAgent\_work\1\b\
.
Вы выполняете несколько этапов и заданий, каждое задание представляет собой новый сеанс для агента. Агент автоматически назначит папку, например _work\1
, _work\2
, в качестве рабочего пространства для ваших различных заданий, вы не можете контролировать назначенную папку. Если вы хотите, чтобы задания использовали одно и то же рабочее пространство, вам следует объединить задачи в одно задание. Или снова оформите заказ/используйте артефакт в новом задании, чтобы получить код. Пожалуйста, проверьте ответ @jessehouwing ниже.
При использовании шаблонов YAML создайте другой репозиторий:
resources
, чтобы указать расположение репозитория шаблонов.@
и имя, которое вы ему дали resources
.Пример:
resources:
repositories:
- repository: mytemplates # <------------- repository name/alias
type: github
name: Contoso/BuildTemplates
jobs:
- template: common.yml@mytemplates # Reference a YAML template in repository mytemplates
Итак, в вашем случае вместо /Base-pipeline.yml
попробуйте использовать /Base-pipeline.yml@YAML
:
resources:
repositories:
# ...
- repository: YAML # <------------- repository name/alias
type: git
name: YAML-Automation
ref: main
trigger:
- none
extends:
template: /Base-pipeline.yml@YAML # Reference a YAML template in repository YAML
parameters:
productName: FOO
Дополнительную информацию см. в Справочнике по использованию шаблонов.
Спасибо! Сделано — заменил каждый .yml на .yml@YAML. К сожалению, проблема все та же.
@HaraldJ подожди, что ты имеешь в виду под каждым .yml
файлом? Это следует делать только в FOO-pipeline.yml
, чтобы ссылаться на шаблоны из других репозиториев. Репозиторий YAML-Automation
— это тот, который содержит общие шаблоны, верно? Или вы также используете шаблоны из других репозиториев?
Только что заметил, что на обоих агентах проверка создает пустой YAML-Automation
файл (name:
репозитория и каталог YAML
(- repository: YAML
) со всеми YML-файлами. Если я правильно понимаю документацию, команда проверки использует имя репо, а не имя репо: поле. Может ли это быть связано с проблемой?
the checkout command uses the repo name
— правильный синтаксис будет checkout: YAML
. Но вам не нужно явно использовать задачу оформления заказа для использования шаблонов YAML, ЕСЛИ вы не используете другие файлы, такие как json, xml и т. д. Попробуйте сначала удалить задачу checkout
.
Рабочие места назначаются агентам без каких-либо предположений. Ваша задача — обеспечить наличие всего необходимого для начала работы. Агентом может быть другая машина, каждый раз это может быть совершенно новая виртуальная машина (как в случае с размещенными агентами), и каждый раз это может быть другая рабочая папка на агенте.
Таким образом, либо ваш рабочий процесс должен загружать и скачивать артефакты конвейера между заданиями, либо проверять репозиторий в начале каждого задания. Если вы хотите убедиться, что все ваши файлы находятся на месте, не разбивайте рабочий процесс на несколько заданий, а просто запустите все, начиная с первого.
В своем конвейере всегда ссылайтесь на предварительно заполненные известные переменные: $(Build.SourcesDirectory)
или $(Pipeline.Workspace)
, они всегда должны указывать на правильный каталог.
Используйте опубликовать: и загрузить:, чтобы опубликовать результаты предыдущего задания и загрузить их снова из более позднего.
Спасибо, @jessehouwing. Весь рабочий процесс со многими заданиями, использующими один и тот же каталог агента, работал отлично, пока я не поместил что-нибудь YAML в отдельный репозиторий Git. Сейчас и $(Build.SourcesDirectory)
, и $(Pipeline.Workspace)
меняются от работы к работе, и я не понимаю почему. Возможно, придется вернуться к использованию YAML в репозиториях кода.
Как упоминал @jessehouwing, Джобса назначают агентам без каких-либо предположений.
Поскольку вы используете On-Prem DevOps server
и имеете разные ресурсы репозитория (FOO, YAML). Проверено на моей стороне: если у вас есть разные проверки репозиториев в разных заданиях в одном агенте, он может использовать другую папку (_work\1, _work\2) в качестве Рабочее пространство.
Если вы хотите получить рабочий каталог с предыдущих работ, one possible workaround
— это set variable
на предыдущем этапе и перейти на следующий этап. Обратите внимание, что это не меняет default working directory
на новом этапе, а переходит в каталог на предыдущем этапе для таких задач, как powershell, задачи bash..
Например, в jobs
на этапе Build_without_analysis
установите переменную:
- powershell: echo "##vso[task.setvariable variable=directory;isOutput=true]$(Build.SourcesDirectory)"
name: setvarStep
На зависимом этапе Test_All
получите переменную:
variables:
myVarfromStageA: $[ stageDependencies.Build_without_analysis.jobBuildAll.outputs['setvarStep.directory'] ]
В заданиях вы можете перейти в этот каталог, чтобы получить код.
Вы можете проверить документ об использовании переменной.
Вот это интересная идея, попробую!!! Но я до сих пор не понимаю, почему все задания используют один и тот же каталог, если весь YAML является частью репозитория продукта.
Поведение контролируется агентом. Когда вы извлекаете разные ресурсы репозитория в разных заданиях, они могут использовать другую папку в качестве рабочей области. Кроме того, когда вы пробуете приведенный выше yaml, убедитесь, что задания выполняются на одном и том же агенте, поскольку вы не уверены, сколько агентов соответствует требованиям BuildServer
в вашем пуле.
Это полезная опция, спасибо! Это работает, но, похоже, между этапами требуется dependsOn:
. Прямо сейчас я подумываю об изменении своего рабочего процесса, сделав модульные тесты и статический анализ кода частью реальных заданий сборки. Тогда у меня будут только артефакты для публикации/загрузки для следующего этапа, и не имеет значения, изменится ли рабочий каталог.
Спасибо @HaraldJ. Рад знать, что это помогает! Да, для передачи переменных требуется зависимость. Если у вас есть какие-либо вопросы, не стесняйтесь поднимать новый билет и всегда рады помочь. Счастливый день! :)
Каждое задание (не этап) может выполняться разными агентами сборки, которые могут использовать разные рабочие папки и запускаться на разных серверах или даже в виде контейнеров Docker. Но я думаю, что ваша проблема не связана с этим. Вероятно, вы неправильно ссылаетесь на шаблоны, хранящиеся в другом репозитории. Смотрите мой ответ и читайте внимательно Справочник по использованию шаблона.