4
votes

I'm trying to shift an existing ASP.NET MVC web application away from TeamCity and on to Azure DevOps however I can't seem to get my pipeline to find the packages that it restored from the NuGet package restore task.

The solution has multiple projects and they use a large number of NuGet packages. I've created a multi-step pipeline which currently has a NuGet Restore task and a VS Build task.

The solution structure is like this:

\source
..\SolutionFolder
...Solution.sln
..\..\Project1
....Project1.csproj
..\..\Project2
....Project2.csproj
..\..\Packages
azure-pipelines.yaml
NuGet.config

The pipeline YAML looks like this:

trigger:
- PipelineBranch

pool:
  vmImage: 'windows-latest'

stages:

## NuGet Restore ##
- stage: nuget_restore
  displayName: 'Restore nuget packages'
  jobs:
  - job: nuget_package_restore
    steps:
    - task: NuGetCommand@2
      displayName: 'NuGet restore'
      inputs:
        command: 'restore'
        restoreSolution: 'source/SolutionFolder/Solution.sln'
        feedsToUse: 'config'
        nugetConfigPath: 'NuGet.Config'
        restoreDirectory: '$(Build.SourcesDirectory)\source\SolutionFolder\packages'

## Build ##
- stage: build_for_int
  displayName: 'Build to int)'
  jobs:
  - job: run_build
    pool:
      vmImage: 'windows-latest'
    steps:
      - task: VSBuild@1
        displayName: 'Build Solution.sln (int)'
        inputs:
          solution: 'source/SolutionFolder/Solution.sln'
          msbuildArgs: '
          /p:DeployOnBuild=true 
          /p:WebPublishMethod=Package 
          /p:PackageAsSingleFile=true 
          /p:SkipInvalidConfigurations=true 
          /p:PackageLocation="$(Build.ArtifactStagingDirectory)"'
          platform: '$(BuildPlatform)'
          configuration: '$(BuildConfiguration)'

When the pipeline runs the restore task succeeds with the following outputs:

<example package>

Added package 'postal.1.2.2' to folder 'd:\a\1\s\source\SolutionFolder\packages'

<loads more packages>

Installed:
    190 package(s) to packages.config projects

When the build task runs on the solution it fails with the following error on the first project it encounters:

[warning]C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2106,5): 
Warning MSB3245: Could not resolve this reference. Could not locate the assembly "postal, Version=1.2.14706.0, Culture=neutral, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
...
Considered "d:\a\1\s\source\SolutionFolder\packages\postal.1.2.2\lib\postal.dll", but it didn't exist.

The same error occurs for each package dependency. It looks like the package restore task restores packages to here:

d:\a\1\s\source\SolutionFolder\packages\

And according to the build log it is looking for them here in the hierarchical package folder structure e.g:

d:\a\1\s\source\SolutionFolder\packages\<package>\<lib>\<dll>

I've tried a number of things including removing the restoreDirectory parameter from the restore task, running the MSBuild command locally (it works) and stripping out some of the packages however I'm still seeing the same build errors.

Some of the project files also contain hintpaths; for example in the format:

  <ItemGroup>
    <Reference Include="<some package>">
      <HintPath>..\packages\<package>\lib\<dll></HintPath>
    </Reference>

Would anyone have any insights? Thanks.

1

1 Answers

5
votes

You should include tasks VSBuild@1 and NuGetCommand@2 under the one same job.

I tested on my local hosted agent and found the second job which runs vsbuild task will clear the working folder and refetch the source code, which removes the packages folder created by the first job task nugetcommand. This might be the reason that causes the error.

So the pipeline yaml should like this

    trigger:
    - PipelineBranch
    pool:
      vmImage: 'windows-latest'
    stages:
    ## NuGet Restore ##
    - stage: nuget_restore
      displayName: 'Restore nuget packages'
      jobs:
      - job: nuget_package_restore
        steps:
        - task: NuGetCommand@2
          displayName: 'NuGet restore'
          inputs:
            command: 'restore'
            restoreSolution: 'source/SolutionFolder/Solution.sln'
            feedsToUse: 'config'
            nugetConfigPath: 'NuGet.Config'
            restoreDirectory: '$(Build.SourcesDirectory)\source\SolutionFolder\packages'

        - task: VSBuild@1
          displayName: 'Build Solution.sln (int)'
          inputs:
            solution: 'source/SolutionFolder/Solution.sln'
            msbuildArgs: '
            /p:DeployOnBuild=true 
            /p:WebPublishMethod=Package 
            /p:PackageAsSingleFile=true 
            /p:SkipInvalidConfigurations=true 
            /p:PackageLocation="$(Build.ArtifactStagingDirectory)"'
            platform: '$(BuildPlatform)'
            configuration: '$(BuildConfiguration)'