What is the source directory of the build? - azure-devops

I have the following tasks:
steps:
- task: MSBuild#1
displayName: '$(ProjectName) .Net build | Build solution (No need to build test as well)'
inputs:
solution: '**/$(ProjectName)/*.csproj'
msbuildArchitecture: x64
configuration: Release
msbuildArguments: '/p:OutputPath=$(Build.ArtifactStagingDirectory)'
clean: true
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/$(ProjectName)'
Contents: |
bin/**
Bundles/**
Views/**
appsettings.json
appsettings.Development.json
*.txt
**/wwwroot/favicon-*.png
**/wwwroot/favicon-*.ico
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
For some reason, the copy step fails with:
##[error]Error: Not found SourceFolder: D:\a\1\a\projectname
why is that?
My project output structure following a local VS build is something like this:
The pipeline .Net build step creates directories as follows:
Creating directory "D:\a\1\a\nl".
Creating directory "D:\a\1\a\cs".
Creating directory "D:\a\1\a\de".
...
2022-09-21T02:38:30.3292966Z Creating directory "D:\a\1\a\runtimes\win-arm\native".
2022-09-21T02:38:30.3293353Z Creating directory "D:\a\1\a\runtimes\win\lib\netcoreapp3.1".
2022-09-21T02:38:30.3293727Z Creating directory "D:\a\1\a\runtimes\win-arm64\native".
2022-09-21T02:38:31.1717424Z Creating directory "D:\a\1\a\refs".
2022-09-21T02:38:31.1717862Z Creating directory "D:\a\1\a\refs".
2022-09-21T02:38:31.1718174Z Creating directory "D:\a\1\a\refs".
so i assumed the source would be D:\a\1\a\projectname or SourceFolder: '$(Build.ArtifactStagingDirectory)/$(ProjectName)' but thats not working it seems.
My reasoning for this is before the dev upgraded the project to .NET6, in the older asp.NET model, the output was one wwwroot directory and so it would translate in the build log to something like:
Creating directory "D:\a\1\a\_PublishedWebsites\projectname\Content\...
so my copy task source would be SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/$(ProjectName)' and that normally worked.
but _PublishedWebsitesno longer appears to be part of .NET6 build output, so im not sure what the source would be now

To be sure about how the build is generating the directory structure, you can add the following task and check the output:
steps:
- task: MSBuild#1
displayName: '$(ProjectName) .Net build | Build solution (No need to build test as well)'
inputs:
solution: '**/$(ProjectName)/*.csproj'
msbuildArchitecture: x64
configuration: Release
msbuildArguments: '/p:OutputPath=$(Build.ArtifactStagingDirectory)'
clean: true
- powershell: |
Get-ChildItem $(Build.ArtifactStagingDirectory) -Recurse
displayName: 'Check agent directories'

Related

Retrieving the MSBuild content into an artifact? Directory 'D:\a\1\a' is empty. Nothing will be added to build artifact 'drop'

I try to understand how this MSBuild command is working with Azure DevOps Pipeline in Yaml. I get this error:
Here is my MSBuild instruction in my Azure Pipeline project:
- task: MSBuild#1
inputs:
solution: '**/Beper-EDI.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArguments: # Optional
clean: true
#maximumCpuCount: false # Optional
#restoreNugetPackages: false # Optional
#logProjectEvents: false # Optional
#createLogFile: false # Optional
#logFileVerbosity: 'normal' # Optional. Options: quiet, minimal, normal, detailed,
The build is correct. I can build my project. Then I try to publish my artifact by using:
- task: PublishBuildArtifacts#1
inputs:
ArtifactName: 'drop'
pathToPublish: '$(Build.ArtifactStagingDirectory)'
I can process the pipeline but at the end my artifact is empty.
During my build I can see that the bin/Release folder and obj/Release folder are created and code is compiled.:
Starting: MSBuild
==============================================================================
Task : MSBuild
Description : Build with MSBuild
Version : 1.192.2
Author : Microsoft Corporation
Help : https://learn.microsoft.com/azure/devops/pipelines/tasks/build/msbuild
==============================================================================
"D:\a\_tasks\MSBuild_c6c4c611-aa2e-4a33-b606-5eaba2196824\1.192.2\ps_modules\MSBuildHelpers\vswhere.exe" -version [17.0,18.0) -latest -format json
"D:\a\_tasks\MSBuild_c6c4c611-aa2e-4a33-b606-5eaba2196824\1.192.2\ps_modules\MSBuildHelpers\vswhere.exe" -version [17.0,18.0) -products Microsoft.VisualStudio.Product.BuildTools -latest -format json
"D:\a\_tasks\MSBuild_c6c4c611-aa2e-4a33-b606-5eaba2196824\1.192.2\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\Beper-EDI.sln" /nologo /nr:false /dl:CentralLogger,"D:\a\_tasks\MSBuild_c6c4c611-aa2e-4a33-b606-5eaba2196824\1.192.2\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll";"RootDetailId=|SolutionDir=D:\a\1\s"*ForwardingLogger,"D:\a\_tasks\MSBuild_c6c4c611-aa2e-4a33-b606-5eaba2196824\1.192.2\ps_modules\MSBuildHelpers\Microsoft.TeamFoundation.DistributedTask.MSBuild.Logger.dll" /p:platform="Any CPU" /p:configuration="Release" /p:_MSDeployUserAgent="VSTS_10aa52a5-54c3-4730-90df-e99d0388b1f5_build_50_0"
Building the projects in this solution one at a time. To enable parallel build, please add the "-m" switch.
Build started 12/30/2021 8:07:45 AM.
Project "D:\a\1\s\Beper-EDI.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
Building solution configuration "Release|Any CPU".
Project "D:\a\1\s\Beper-EDI.sln" (1) is building "D:\a\1\s\Nppg.Core.BusinessServices\Nppg.Core.BusinessServices.csproj" (2) on node 1 (default targets).
PrepareForBuild:
Creating directory "bin\Release\".
Creating directory "obj\Release\".
Project "D:\a\1\s\Nppg.Core.BusinessServices\Nppg.Core.BusinessServices.csproj" (2) is building "D:\a\1\s\Nppg.Core.Reports\Nppg.Core.Reports.csproj" (3:2) on node 1 (default targets).
PrepareForBuild:
Creating directory "bin\Release\".
Creating directory "obj\Release\".
Project "D:\a\1\s\Nppg.Core.Reports\Nppg.Core.Reports.csproj" (3:2) is building "D:\a\1\s\Submodules\nppg-core\Nppg.Core\Nppg.Core.csproj" (5:3) on node 1 (default targets).
PrepareForBuild:
Creating directory "bin\Release\".
Creating directory "obj\Release\".
How can I make sure the system let me access my /Release folder?
Retrieving the MSBuild content into an artifact? Directory 'D:\a\1\a' is empty. Nothing will be added to build artifact 'drop'
That because the source of the task PublishBuildArtifacts is $(Build.ArtifactStagingDirectory).
But the MSBuild task not generate the file in the $(Build.ArtifactStagingDirectory) folder, so we need to copy the files from the output folder of the task MSBuild to the folder $(Build.ArtifactStagingDirectory) by the copy task after MSBuild task:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: '**\bin\release\**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'

Why are the Web.*env*.config files not being copied over to the artifact?

I'm finding something strange with the copy task in the build CI pipeline of a .NET app. lets call it JJ.
For some reason, the Web.Dev.config, Web.Test.config, and Web.Prod.config files aren't being copied to the artifact. I have another pipeline for a similarly designed app so the pipeline is setup the same way, and I confirmed that with that other app, let's call it EE, those files are getting copied in the artifact, but with JJ they are not being copied for some reason.
EE app artifact (other app that copy task is working):
JJ app artifact (app in question, only Web.config is copied):
even though there is Dev/Test/Prod configs clearly in the directory
JJ copy task YAML:
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/JJDashboard'
Contents: |
assets/**
bin/**
Bundles/**
Content/**
Scripts/**
Views/**
Web.config
Web.Dev.config
Web.Test.config
Web.Prod.config
ApplicationInsights.config
*.asax
*.ico
*.txt
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
EE copy task YAML (the app that config files are being copied just fine):
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/EEDashboard'
Contents: |
assets/**
bin/**
Bundles/**
Content/**
Scripts/**
Views/**
Web.config
Web.Dev.config
Web.Test.config
Web.Prod.config
ApplicationInsights.config
*.asax
*.ico
*.txt
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
The copy task YAMLs are pretty identical as you can observe, as is the repo structures/file locations. So why is it working for EE but not JJ?
Edit
Comparing JJ .csproj file vs EE .csproj file we observe the web.dev.config, web.test.config, and web.prod.config file references in JJ .csproj file are missing the tag: <content Include>
Enabling this property for the files in the project resolves the issue:
Check that the new web.env.config -files are included in the JJDasboard-project .csproj (or .sln) -file, so they will be published with the build results.
The most apparent problem would be that the builds produce different results, ie. EE app's build copies all the different configs to output directory, where as JJ app's build only copies the web.config (as it does by default).

VSTS YAML Build publishing strange path

I'm publishing build artefacts from $(Build.Repository.LocalPath)/src/cookiecutter.utility.tool.csproj and setting an output path of $(build.artifactstagingdirectory)/dist, however for some reason I can't comprehend it's adding the src element to the output path, rather than just dist.
I've checked the YAML docs and can't see anything that would suggest I've done something wrong.
The YAML section
task: DotNetCoreCLI#2
displayName: Publish
inputs:
command: publish
publishWebProjects: false
zipAfterPublish: false
projects: $(projectDir)/cookiecutter.utility.tool.csproj
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory) --self-contained -r win10-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true
'
View of source repo.
Because you specify the projects in the dotnet publish task.
This .csproj is what you are trying to publish. When you specify the exactly project file value to task parameter projects , at this time, the output path is in project file’s directory rather than the root directory. That's why it keep the path of src in the artifact path.
If you don't want this src displayed, just remove projects: $(projectDir)/cookiecutter.utility.tool.csproj . Then the publish will work with the root directory(all projects) and the src will not displayed any more.
Update:
As I mentioned in my comment, as normal, it will looking for project file automatically under its working directory during dotnet.exe execution. For VSTS, the default working directory is solution folder (root).
So, to work around the Specify a project or solution file error and avoid the strange path added in artifact also, you can configure yourself working directory by using workingDirectory: src.
- task: DotNetCoreCLI#2
displayName: Publish
inputs:
command: publish
publishWebProjects: false
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory) --self-contained -r win10-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true'
zipAfterPublish: false
modifyOutputPath: true
workingDirectory: src
This could let you avoid the src display in artifact structure without error.

DotNetCLI#2 pack seems to be ignoring configuration inputs

The below YAML snippet does not seem to work as expected.
I configured it in a pipeline that runs using the windows-latest image and it attempts to restore all of the projects that are in the repo, instead of looking just to the solution file.
Also, it seems to completely ignore the --no-restore flag
- task: DotNetCoreCLI#2
displayName: Package to Staging directory
inputs:
command: pack
configuration: $(BUILD_CONFIGURATION)
projects: 'support-libs.sln'
packDirectory: $(Build.ArtifactStagingDirectory)
nugetConfigPath: 'sf-solution/nuget.config'
arguments: '--no-restore'
verbosityRestore: Minimal
The command that appears on the step logs is:
"C:\Program Files\dotnet\dotnet.exe" pack
d:\a\1\s\sf-solution\SampleProject\SampleProject.csproj --output
d:\a\1\a /p:Configuration=Debug --verbosity Detailed
The above project is not even included in the support-libs SLN file the snippet has configured.
The above project is not even included in the support-libs SLN file the snippet has configured
Not sure why DotNetCLI task pack the project, which is not included in in the support-libs SLN. Since you did not share your project file structure and the build log in your question, I could not give you the directly reason for this issue.
But as workaround, you could specify the specific project file instead of the solution file. Besides, you can also check this task by classic editor:
It state the path to csproj or nuspec file(s) to pack.
For the ignoring configuration inputs problem, there is an option Do Not build, so, you could add this argument to your pack task instead of the argument --no-restore:
- task: DotNetCoreCLI#2
displayName: 'dotnet pack'
inputs:
command: pack
packagesToPack: YourProjectPath&Name.csproj
nobuild: true
Note: Add a DotNet build task before you use this pack task.
Hope this helps.
I was finally able to do what I wanted and to pack all the libraries inside the solution, however I had to use a custom command instead of the pack one:
- task: DotNetCoreCLI#2
displayName: Package to Staging directory
inputs:
command: custom
custom: 'pack'
arguments: 'support-libs.sln -c=$(BUILD_CONFIGURATION) -o $(Build.ArtifactStagingDirectory)'
verbosityRestore: Minimal
verbosityPack: Minimal
feedsToUse: select
vstsFeed: personalnugetfeed
nuGetFeedType: internal
includeNuGetOrg: true
I was also having authorization issues with the internal feed that was in the Nuget configuration and linking to that file, even from a custom command, had the same issues.
Explicitly stating from which feed the restore should be made worked perfectly and I was able to retrieve all the dependencies removing the need to use the --no-restore flag.

VSTS Yaml vraiables and path contradicting with classic editor

I am facing an issue when setting VSTS classic editor parameters when compare with current yaml file which is working as expected.
Below is working fine (Build pipeline)
- task: CopyFiles#2
displayName: "Copy Files to: $(Build.ArtifactStagingDirectory)"
inputs:
contents: '$(Build.SourcesDirectory)/src/xxx.EndToEnd.Integration.Tests/**'
targetFolder: $(Build.ArtifactStagingDirectory)
- task: DotNetCoreCLI#2
displayName: "dotnet e2e tests"
inputs:
command: publish
publishWebProjects: false
projects: '**/*.csproj'
arguments: --output $(Build.ArtifactStagingDirectory)/src/xxx.EndToEnd.Integration.Tests
zipAfterPublish: false
But same setting as per below find 0 files
2019-04-06T10:02:57.5303667Z found 0 files
2019-04-06T10:02:57.5376614Z ##[section]Finishing: Copy Files to: $(Build.ArtifactStagingDirectory)
I have changed the / to \ as well, but same outcome.
Below is designer pipeline
Same results in dotnet publish task also in Path to project(s) parameter **\**\*.csprojgives below error, but above yaml file works as expected.
2019-04-06T10:02:58.7896707Z ##[error]Project file(s) matching the specified pattern were not found.
In the release pipeline the variables Build.SorucesDirectory and Build.ArtifactSatgingDirectory are not available, these variables are only for build pipelines.
In fact, in the release agent folder there is not "Soruces" folder, but only "Artifact" folder. for example: C:\agent\_work\r1\a, the variable to get the value is: System.ArtifactDirectory or Agent.ReleaseDirectory.
More details about release variables you can find here.