Построение решения, составленного из разных проектов, расположенных в разных проектах в DevOps - PullRequest
0 голосов
/ 29 марта 2020

Я только начал играть с Azure DevOps, поскольку я хочу перенести все свои личные проекты на него, так как мне действительно нравится использовать его в офисе, но мне никогда не приходилось его настраивать, и я у меня первая проблема и надеюсь, что кто-то может помочь.

Я создал проект в DevOps и вложил свое основное решение в репозиторий. Все хорошо. Это решение имеет библиотеку зависимостей из другого проекта, поэтому я создал другой проект в DevOps и перенес эту библиотеку в репозиторий.

Мое основное решение (.sln), которое включает в себя проект для моего основного проекта, также включает ссылка на библиотеку и локальная компиляция решения работают, как и ожидалось, но когда я пробую это в DevOps, я получаю следующую ошибку:

D:\a\1\s\MyProject.sln.metaproj(0,0): Error MSB3202: The project file  
"D:\a\1\s\..\..\..\Libraries\MyLibrary\MyLibraryAPI\MyLibraryAPI.csproj"
was not found.

, и в результате я получаю кучу других ошибок, похожих на ниже, так как не удалось скомпилировать библиотеку, на которую ссылается решение, но которая находится в совершенно другом проекте в DevOps:

MyProject\Controllers\MembersController.cs(8,7): Error CS0246: The type or namespace name 
'MyLibraryAPI' could not be found (are you missing a using directive or an assembly 
reference?) 

Ясно, что не могу найти проект в DevOps, но как я могу решить эту проблему? Я все еще хочу убедиться, что эта библиотека компилируется каждый раз, когда я компилирую свой основной проект.

Я только немного прочитал YAML, и я предполагаю, что мне, возможно, придется что-то там изменить, но я ' Я не уверен, что быть честным. В любом случае, я буду ждать чьей-то обратной связи и надеюсь, что вышеизложенное имеет смысл, и что кто-то может прояснить, как я могу решить эту проблему.

Спасибо.

ОБНОВЛЕНИЕ-1

Спасибо за подробный отзыв @MerlinLiang. Я следовал инструкциям по ссылке, предоставленной @FrankAlvaro и вашей, и они действительно одинаковы, но я ценю дополнительную информацию, поскольку я столкнулся с этой проблемой, связанной с ошибкой:

The Git repository with name or identifier {repos name}does not exist
or you do not have permissions for the operation you are attempting

Но я до сих пор нет ' т решил проблему. Теперь я получаю следующую ошибку:

 ##[error]d:\a\1\s\MyProject\MyProject.sln.metaproj(0,0): 
 Error MSB3202: The project file "d:\a\1\s\MyProject\..\..\..\Libraries\
 MyLibrary\MyLibraryAPI\MyLibraryAPI.csproj" was not found.

Помните, что MyProject - это мое основное решение, в котором есть ссылка на мою MyLibrary, но странно видеть, что он пытается поместить MyLibrary \ MyLibraryAPI внутри MyProject как локально они находятся в другом месте, так что, хотя я понимаю, что в Azure DevOps все будет по-другому, я бы подумал, что при проверке проекта он попытался бы соблюдать структуру папок, используемую локально, не так ли?

Я не знаю, поможет ли это решить мою проблему, но вот как определяются проекты в моем файле .sln:

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyProject",
"MyProject\MyProject.csproj", "{CD02E7AD-97EE-4831-A18D-A57E2CC92E08}"
EndProject

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibraryAPI", 
"..\..\..\Libraries\MyLibrary\MyLibraryAPI\MyLibraryAPI.csproj", 
"{82A7849D-22EF-4889-A7A6-2AE7D3F98F77}"
EndProject

UPDATE-2

Я попробовал то, что предложил @MerlinLiang, установив путь, но я не уверен, что я делаю правильно, поскольку он все еще не работает, как ожидалось. Вот что я сделал:

  • Установите путь для MyProject
  • Установите путь для переменных MyLibraryAPI

    : решение: '** / * .sln 'buildPlatform:' Any CPU 'buildConfiguration:' Release 'MyProjectCheckoutPath:' Repos \ Work \ Company \ MyProject 'MyLibraryApiCheckoutPath:' Repos \ Libraries \ MyLibrary '

    шаги:

    • checkout: self path: '$ (MyProjectCheckoutPath)'
    • checkout: MyLibrary path: '$ (MyLibraryApiCheckoutPath)'

Примечание: MyLibrary - это мое решение папка, которая содержит 2 папки, одна из которых называется MyLibraryAPI, которая содержит MyLibraryAPI.csproj, а другая - просто консольное приложение, используемое для тестирования библиотеки, но не обязательное. Я не уверен, как конкретно указать, чтобы использовать проект MyLibraryAPI только, поскольку он содержится в репо, который содержит 2 папки. Я надеюсь, что это имеет смысл.

Когда я указываю вышеуказанный путь в YAML и запускаю конвейер, я получаю следующие предупреждения:

Repository is current at 'D:\a\1\s\My Project', move to 
'D:\a\1\Repos\Work\Company\MyProject'.
##[warning]Unable move and reuse existing repository to required location.
Repository will be located at 'D:\a\1\Repos\Work\Company\MyProject'.

Repository is current at 'D:\a\1\s\MyLibrary', move to 
'D:\a\1\Repos\Libraries\MyLibrary'.
##[warning]Unable move and reuse existing repository to required location.
Repository will be located at 'D:\a\1\Repos\Libraries\MyLibrary'.

Как видите, оба дают предупреждение, когда я пытаюсь использовать пути, определенные в моих переменных.

Поскольку это только предупреждение, оно продолжается при сборке, но в итоге я получаю сообщение об ошибке в разделе VSBuild:

##[error]Solution not found using search pattern 'D:\a\1\s\**\*.sln'.

Я пытался изменить переменную решения в моем YAML на MyProject

variables:
   solution: '**/MyProject.sln'

Но я все равно получаю сообщение об ошибке, поскольку путь явно отличается:

##[error]Solution not found using search pattern 
'D:\a\1\s\**\MyProject.sln'.

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

Есть идеи?

ОБНОВЛЕНИЕ-3

На секунду я подумал, что сортировал его, так как VSBuild потребовалось больше времени, чем обычно, чтобы выйти из строя, но безрезультатно. Я изменил путь решения, чтобы использовать полный путь MyProject:

, но в итоге получил следующую ошибку:

"D:\a\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-
affca411ecda\1.166.0\ps_modules\MSBuildHelpers\vswhere.exe" 
-version [16.0,17.0) -latest -format json
"C:\Program Files (x86)\Microsoft Visual 
Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" 
"D:\a\1\s\Repos\Work\Company\MyProject\MyProject.sln" /nologo /nr:false 
/dl:CentralLogger,"D:\a\_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-
affca411ecda\1.166.0\ps_modules\MSBuildHelpers\
Microsoft.TeamFoundation.DistributedTask.
MSBuild.Logger.dll";"RootDetailId=7d46ac00-083a-434d-9729- 
be159b80eea4|SolutionDir=D:\a\1\s\Repos
\Work\Company\MyProject"*ForwardingLogger,"D:\a\_tasks\
VSBuild_71a9a2d3-a98a-4caa-96ab- 
affca411ecda\1.166.0\ps_modules\MSBuildHelpers\
Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll"
/p:DeployOnBuild=true /p:WebPublishMethod=Package 
/p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true 
/p:PackageLocation="D:\a\1\a" /p:platform="Any CPU" 
/p:configuration="Release" /p:VisualStudioVersion="16.0" 
/p:_MSDeployUserAgent="VSTS_aa0b7157-846e-49d9-8668-38efaf1e9745_build_5_0"
MSBUILD : error MSB1009: Project file does not exist.
Switch: D:\a\1\s\Repos\Work\Company\MyProject\MyProject.sln
##[error]Process 'msbuild.exe' exited with code '1'.
Finishing: VSBuild

UPDATE-4:

Я пытался создать каталог через Powerscript, как предложено в

Предупреждение при загрузке дополнительных репозиториев

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

Вот мой полный YAML:

resources:
 repositories:
   - repository: MyLibrary
     type: git 
     name: MyLibrary/MyLibrary

trigger:
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: 'Repos\Work\Company\MyProject\MyProject.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  myLibraryCheckoutPath: 'Repos\Libraries\MyLibrary'
  myProjectCheckoutPath: 'Repos\Work\Company\MyProject'

steps:
- task: PowerShell@2
  displayName:  "Create repository folder $(myProjectCheckoutPath)"
  inputs:
    targetType: inline
    script: |
      New-Item -Path . -Name "$(myProjectCheckoutPath)" -ItemType "directory"
    pwsh: true

- checkout: self
  path: '$(myProjectCheckoutPath)'

- script: dir
  workingDirectory: $(myProjectCheckoutPath)
  displayName: List contents of a folder for MyProject

- task: PowerShell@2
  displayName:  "Create repository folder $(myLibraryCheckoutPath)"
  inputs:
    targetType: inline
    script: |
      New-Item -Path . -Name "$(myLibraryCheckoutPath)" -ItemType "directory"
    pwsh: true

- checkout: MyLibrary
  path: '$(myLibraryCheckoutPath)'

- script: dir
  workingDirectory: $(myLibraryCheckoutPath)
  displayName: List contents of a folder for MyLibrary

- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package 
                  /p:PackageAsSingleFile=true 
                  /p:SkipInvalidConfigurations=true 
                  /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

# - task: VSTest@2
#   inputs:
#     platform: '$(buildPlatform)'
#     configuration: '$(buildConfiguration)'

ОБНОВЛЕНИЕ 5

Я все еще не понимаю, что происходит.

Когда я проверяю 2 проекта, я получаю следующее:

- Directory created: D:\a\1\s\Repos\Work\Company\MyProject
- Directory created: D:\a\1\s\Repos\Libraries\MyLibrary

И в журналах я получаю следующий вывод:

- Repository is current at 
  'D:\a\1\s\MyProject', move to 
  'D:\a\1\s\Repos\Work\Company\MyProject' 
  (##[warning]Unable move and reuse existing repository to required location)

- Repository is current at 
  'D:\a\1\s\MyLibrary', move to 
  'D:\a\1\s\Repos\Libraries\MyLibrary' 
  (##[warning]Unable move and reuse existing repository to required location)

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

Тем не менее, когда я просто извлекаю один репозиторий, т.е. MyProject, в журнал выводится следующее:

Repository is current at 
'D:\a\1\s', move to 'D:\a\1\s\Repos\Work\Company\MyProject'. 
Repository will be located at 
'D:\a\1\s\Repos\Work\Company\MyProject'.

И это работает, как и ожидалось.

В обоих сценариях ios, root равен 'D: \ a \ 1 \ s', но при его извлечении текущий каталог такой же, но при использовании с 2 это root каталог и название проекта. Вы могли бы подумать, что это должно быть в порядке, но это явно не так, поскольку не удается переместить файлы.

Одна вещь, которую я тоже не понимаю, это в соответствии с Проверьте несколько хранилищ в вашем конвейере , есть примечание, в котором говорится:

Если вы используете пути по умолчанию, добавление второго шага проверки хранилища изменяет путь по умолчанию кода для первого хранилища. Например, код для репозитория с именем tools будет извлечен в C: \ agent_work \ 1 \ s, когда tools является единственным репозиторием, но если будет добавлен второй репозиторий, инструменты будут затем извлечены в C : \ agent_work \ 1 \ s \ инструменты. Если у вас есть какие-либо шаги, которые зависят от исходного кода, находящегося в исходном местоположении, эти шаги должны быть обновлены.

Что означает

"Если у вас есть какие-либо шаги, которые зависят от исходного кода, находящегося в исходном расположении, эти шаги должны быть обновлены "

Какие шаги и обновить их до какого ??

Я прочитал так много документации Я часами гуглял и пробовал так много комбинаций YAML, но безрезультатно. Я просто не могу найти решение. Извините, если мне чего-то не хватает, но я просто не понимаю, почему это работает с одним репо и не работает с 2.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

В конце концов я разобрался с недостающим фрагментом!

В то время как документация Microsoft Azure DevOps в целом превосходна, я чувствую, что она полностью не смогла объяснить требования к нескольким проверкам, не говоря уже о явном недостатке в системе.

Примечание. Мой ответ основан на требованиях к пути из моего вопроса.

Короче говоря, при проверке нескольких проектов он просто не создает исходные папки для каждого из них. из проектов, которые извлекаются.

2 Проблемы:

1) Вводящее в заблуждение предупреждающее сообщение:

Repository is current at 'D:\a\1\s\MyProject', move to 
'D:\a\1\s\Repos\Work\Company\MyProject'.
##[warning]Unable move and reuse existing repository to required location.
Repository will be located at 'D:\a\1\s\Repos\Work\Company\MyProject'.

Почему бы не отобразить то, что Фактическая проблема, например,

The folder 'D:\a\1\s\MyProject' not found.

, и вместо создания предупреждения она должна создать ошибку и остановить процесс.

2) Не создает автоматически исходную папку: Возможно, в этом кроется причина, но я не могу придумать, что это может быть, но лично я считаю, что всегда следует создавать исходный каталог, в котором будут проверяться файлы. прежде чем они будут перемещены.

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

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

Мой последний скрипт в итоге выглядел так:

resources:
 repositories:
   - repository: MyProject
     type: git 
     name: My Project/My Project
   - repository: MyLibrary
     type: git 
     name: MyLibrary/MyLibrary

trigger:
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

  myProjectCheckoutSource: 'My Project'
  myProjectCheckoutTarget: 's/Repos/Work/Company/MyProject'
  myProjectCheckoutTargetFolder: '$(Agent.BuildDirectory)\s\Repos\Work\Company\MyProject'

  myLibraryCheckoutSource: 'MyLibrary'
  myLibraryCheckoutTarget: 's/Repos/Libraries/MyLibrary'
  myLibraryCheckoutTargetFolder: '$(Agent.BuildDirectory)\s\Repos\Libraries\MyLibrary'  

steps:

###################
# Pull My Project #
###################

# Create checkout source folder as when using multiple checkouts, 
# it doesn't get created automatically.
- task: PowerShell@2
  displayName: "Create repository folder: $(myProjectCheckoutSource)"
  inputs:
    targetType: inline
    script: |
      New-Item -Path . -Name "$(myProjectCheckoutSource)" -ItemType "directory"
    pwsh: true

# The target checkout folder defined in the 'path' is created automatically
- checkout: self
  displayName: checking out $(myProjectCheckoutSource) to $(myProjectCheckoutTarget)
  path: $(myProjectCheckoutTarget)

##################
# Pull MyLibrary #
##################

# Create checkout source folder as when using multiple checkouts, 
# it doesn't get created automatically.
- task: PowerShell@2
  displayName: "Create repository folder: $(myLibraryCheckoutSource)"
  inputs:
    targetType: inline
    script: |
      New-Item -Path . -Name "$(myLibraryCheckoutSource)" -ItemType "directory"
    pwsh: true

# The target checkout folder defined in the 'path' is created automatically
- checkout: myLibrary
  displayName: checking out $(myLibraryCheckoutSource) to $(myLibraryCheckoutTarget)
  path: $(myLibraryCheckoutTarget)

- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package 
    /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true 
    /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
0 голосов
/ 30 марта 2020

То же предложение с Фрэнком.

В вашем сценарии вы хранили несколько библиотек зависимостей в нескольких проектах. Как и при проектировании по умолчанию, он извлекает текущее репо только в том случае, если в конвейере не было задано никакой конкретной конфигурации c.

Возьмем простой пример: проект A зависит от проекта B в его фактической сборке. И вы сохраняете проект A в Azure devops project A, проект B в Azure devops project B. Когда вы настраиваете конвейер для построения проекта A, наша система будет только извлекать репо A в рабочее пространство. Другими словами, в рабочей области нет репо B, когда A находит B для выполнения сборки.

Почему вы можете скомпилировать решение локально, работает как положено, потому что все проекты существуют в рабочем пространстве. Это отличается от Azure devops work logi c.


Просто следуйте do c, чтобы перенастроить YAML:

resources:
  repositories:
  - repository: {repos name A }
    type: git
    name: {project name A }/{repos name A }
  - repository: {repos name B }
    type: git
    name: {project name B }/{repos name B }

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

steps:
- checkout: self
- checkout: git://{project name A }/{repos name A }
- checkout: git://{project name B }/{repos name B }

Checkout все репо, которые нужны вашему проекту.


Мы сделали четкое объяснение и примеры сценариев в do c, вы можете следовать этому руководству по окончательной sh конфигурации YAML.

Так как вы совсем новичок в Azure devops, здесь я просто расскажу об одной проблеме, с которой вы, скорее всего, столкнетесь, и с которой вы чаще всего будете путать:

remote: TF401019: репозиторий Git с именем или идентификатором {имя репозитория} не существует или у вас нет прав для выполняемой вами операции.

fatal: repository 'https://dev.azure.com/ {org} / {project} / _ git / { repos} / 'not found

Вы можете подумать, что это указывает на неверные настроенные аргументы YAML. На самом деле нет, это другое приглашение на выдачу разрешений: учетная запись службы , используемая текущим конвейером, не имеет прав доступа к целевому проекту.

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

Чтобы решить эту проблему, просто go Project settings => Settings и убедитесь, что Limit job authorization scope to current project отключено:

enter image description here


Обновление включено 3/31/2020 :

Рад, что дополнительное уведомление работает для вас.

Я проверил ваше обновленное содержимое, отличная помощь для определения проблемы! Ошибка, с которой вы столкнулись, ожидается сейчас.

Ранее вы сталкивались с тем, что не найдена ошибка, вызванная отсутствием этих файлов в рабочем каталоге сборки. Теперь они все оформлены в рабочий каталог. Хотя он все еще сказал, что не найден, но он просто представляет путь ссылки не является правильным.

Вы храните их в разных репо и проектах, а не в одном репо. В настоящее время система не может знать, как устроена структура вашего проекта, и она может соблюдать только правило checkout: установить их в папку xxx/xxx/.../s.

странно видеть, что она пытается поместить MyLibrary \ MyLibraryAPI в MyProject

. Вы можете проверить эту заметку :

enter image description here

Боюсь, вы должны указать один аргумент в вашем скрипте YAML: path. Переконфигурируйте расположение кэша, чтобы оно соответствовало вашей фактической структуре проекта. Поскольку я не знал, как выглядит структура вашего проекта, вы можете сделать это самостоятельно.


Обновление от 4/1/2020 :

Все еще в этом do c, мы упоминали, что If a path is specified for a checkout step, that path is used, relative to (Agent.BuildDirectory).

А для (Agent.BuildDirectory) его значение равно /home/vsts/work/1. Это означает, что фактический полный путь оформления заказа для ваших Myproject и Mylibrary равен xxx/1/Repos/Libraries/MyLibrary и xxx/1/Repos/Work/Company/MyProject. Это то, что вы видели в предупреждении, потому что наш исходный путь / путь извлечения по умолчанию должен быть папкой xxx/1/s.

Это не приведет к ошибке, просто сообщите вам путь, измененный здесь. Место, которое фактически вызвало ошибку, было в vsbuild task.

Обратите внимание на одну вещь: azure devops, рабочий каталог большинства задач - Build.SourcesDirectory, фактический путь - xxx/1/s. Другими словами, это сборка с поиском sln / csproj из xxx/1/s.

Теперь, когда возникают проблемы, вы сохраняете их в xxx/1/repos/xxxx, но задача сборки ищет файл решения из xxx/1/s/xxxx. Абсолютно, не удалось ничего не найдено. Это также указано в сообщении об ошибке сборки, пожалуйста, обратите внимание на путь.

...