Azure Devops Pipelines - connect "VS Build" step to "Archive Files" step - visual-studio

I'm trying to get into using Azure Devops Pipelines, and my first pet project is a simple .NET command line app I'm trying to get to be built.
I picked the "VS Build .NET Desktop" task template, and the build per se works fine - the bits are compiled without trouble
YAML:
- task: VSBuild#1
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
Log:
##[section]Starting: VSBuild
==============================================================================
Task : Visual Studio build
Description : Build with MSBuild and set the Visual Studio version property
Version : 1.151.2
Author : Microsoft Corporation
Help : https://learn.microsoft.com/azure/devops/pipelines/tasks/build/visual-studio-build
==============================================================================
##[command]"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe" "d:\a\1\s\AzureDevopsTaskCreator.sln"
...(lots of lines omitted)
CopyFilesToOutputDirectory:
Copying file from "d:\a\1\s\obj\Release\AZTaskCreator.exe" to "d:\a\1\s\bin\Release\AZTaskCreator.exe".
AZTaskCreator -> d:\a\1\s\bin\Release\AZTaskCreator.exe
Copying file from "d:\a\1\s\obj\Release\AZTaskCreator.pdb" to "d:\a\1\s\bin\Release\AZTaskCreator.pdb".
But now I wanted to somehow publish the output from this build so I could download it (or deploy it somewhere). But I've been struggling with getting these things hooked up.
So I tried to first zip the build output into an archive (which could then be published):
YAML
- task: ArchiveFiles#2
inputs:
rootFolderOrFile: '$(Build.BinariesDirectory)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/AZCreateTasks$(Build.BuildId).zip'
replaceExistingArchive: true
verbose: true
Log:
##[section]Starting: ArchiveFiles
##[command]d:\a\_tasks\ArchiveFiles_d8b84976-e99a-4b86-b885-4849694435b0\2.151.2\7zip\7z.exe a -tzip -bb3 d:\a\1\a\AZCreateTasks8.zip #d:\a\_temp\yat6561e8redmiomp7bbuik9
My problem is: HOW can I tell the "Archive Files" step to use the output directory of the previous build? I was assuming that the default $(Build.BinariesDirectory) would do that - but obviously, it doesn't:
Output from VS Build goes to the d:\a\1\s\bin\Release\ directory
Archive files step zips up files in d:\a\_temp\yat6561e8redmiomp7bbuik9 directory
How can I "connect" these two steps so that the "Archive Files" step actually respects and uses the output directory of the VS Build step??
I'm having a terribly hard time finding any useful documentation on what kind of "system pre-defined" magic variables are in play here, and how to influence these .....

According to the log, the build output is in d:\a\1\s\... the s folder it the sources directory, to access this folder there is pre-defined varaible: Build.SourcesDirectory.
So instead of using $(Build.BinariesDirectory) use the above variable:
rootFolderOrFile: '$(Build.SourcesDirectory)'
But now you will get a zip with the sources files including the dll's, so consider to append the path until the folder/s you want.
For example:
rootFolderOrFile: '$(Build.SourcesDirectory)/obj/Release'

Related

Is it possible to run a postbuildevent in an Azure Devops .yaml pipeline build event containing macros such as $(TargetPath)?

I'm trying to automatically rename the .dll resulting from VSBuild so it includes the version number. In order to do this I've tried to create a postbuild event in DevOps.
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:PostBuildEvent="rename $(TargetPath) $(TargetDir)$(TargetName).$(buildNumber)$(TargetExt)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
This post build event works fine when I put it in Visual Studio and run it locally. However, I don't want users to be able to change it, so I don't want to define it in Visual Studio but in the pipeline(.yaml) itself. On DevOps I get the following result:
PostBuildEvent:
rename $(TargetPath) $(TargetDir)$(TargetName).20221003.8$(TargetExt)
The system cannot find the file specified.
##[error]C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(5707,5): Error MSB3073: The command "rename $(TargetPath) $(TargetDir)$(TargetName).20221003.8$(TargetExt)" exited with code 1.
It seems as though the postbuild event macros, such as $(TargetPath), which are recognized in Visual Studio are not recognized when running the post build event through DevOps pipelines. Is this correct? If so, is there any way around it? I'd prefer not to hardcode anything since I want to reuse the pipeline for multiple repos/solutions with a variable number of projects and project names.
Thanks a lot!

Azure Pipelines VisualStudioBuild task ignoring AssemblyInfo.cs

This is being built in an on-prem build agent running version 2.200.2. I've tried using VS 2017-2022 (15.0, 16.0, 17.0).
When I build my code locally, it properly parses the AssemblyInfo.cs files and applies the versioning so that when I check the details in Windows properties, it lists the version set in AssemblyFileVersion (I'm also setting AssemblyVersion and AssemblyInformationalVersion for good measure). For some reason, however, when I run the following tasks, all generated dlls and exes come out with a version of 0.0.0.0 instead of what is listed in the AssemblyInfo.cs. $(RVersion) is defaulted to 1.0.23.0 and I've validated that the AssemblyInfo.cs files are properly being updated. The value currently listed in the AssemblyInfo is 1.0.13.0, so even if it wasn't being set, it's still being ignored. Any help in figuring out why the files are being generated with 0.0.0.0 would be appreciated.
- task: Assembly-Info-NetFramework#3
inputs:
Path: '$(Build.SourcesDirectory)'
FileNames: |
**\AssemblyInfo.cs
InsertAttributes: true
VersionNumber: '$(RVersion)'
FileVersionNumber: '$(RVersion)'
InformationalVersion: '$(RVersion)'
Configuration: $(buildConfiguration)
- task: VSBuild#1 displayName: 'Build .NET Solution'
inputs:
solution: '$(solution)'
vsVersion: '17.0'
configuration: 'Release'
platform: $(buildPlatform)
msbuildArgs: '/p:SkipInvalidConfigurations=true /p:OutDir=$(Build.BinariesDirectory)'
clean: true

Set working directory in azure devops with Visual Studio build task

I'm trying to build a project which requires to set the working directory to a path.
On my local machine I could go with Visual Studio 2019 and go to Project - Properties - Debugging - Command Arguments and set it to whatever I want. The problem is that I don't know how to do with Visual Studio build task.
If I do not set this settings, it produces an executable that doesn't launch.
here is my build pipeline: https://dev.azure.com/nathanvalletmarseille/armorpaint/_build?definitionId=5&_a=summary
It's not able to directly set this with build-in visual studio build task.
However, you could do this through a script before you run the build task:
- script: # script path or inline
workingDirectory: #
displayName: #
failOnStderr: #
env: # mapping of environment variables to add
More details take a look at this similar question: Change current working directory in Azure Pipelines

Azure Devops - SSDT DB build error - writing model.xml

I get the following build error for my SSDT project in Azure DevOps:
System.IO.DirectoryNotFoundException: Could not find a part of the path 'd:\a\1\s\SSDTPROJECTNAME\SSDTPROJECTNAMEobj\Release\Model.xml'.
Earlier in the build it attempts to write the Model.xml file to an invalid path:
SqlBuild:
Creating a model to represent the project...
Loading project references...
Loading project files...
Building the project model and resolving object interdependencies...
Validating the project model...
Writing model to SSDTPROJECTNAMEobj\Release\Model.xml...
For some reason it fails to concatenate my project folder name with obj\Release\Model.xml. But when I build locally it writes the model.xml to a valid location. For the project folder I'm using a variable called $(projectDir) set to my project folder name.
I'm using VSBuild#1 with the windows-latest vmImage.
Here's my task:
- task: VSBuild#1
displayName: "Build DB project"
inputs:
solution: "$(projectDir)\SSDTPROJECTNAME.sqlproj"
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:DeleteExistingFiles=True /p:PackageLocation="$(Build.ArtifactStagingDirectory)\\"'
configuration: "$(BuildConfiguration)"
clean: true
The 'projectDir' variable is preserved key word for VS Build. If you change to a different variable should fix the problem.
https://learn.microsoft.com/en-us/cpp/build/reference/common-macros-for-build-commands-and-properties?view=vs-2019

Azure DevOps Build Task: create a zip with contents identical to Visual Studio Publish

In Visual Studio, when we publish to a folder, that folder contains exactly what we need to deploy.
In Azure Pipeline, the Build Solution task produces a a bunch of (to us) unnecessary files plus a zip file (nice!). The zip contains the files we need, but buried in an crazy deep folder path:
\Content\D_C\a\1\s\src\MyProject\obj\Release\Package\PackageTmp\our-files.dll
What we would prefer is:
\our-files.dll
It also modifies connectionStrings in the web.config to support the deploy script it ships with. We don't need that script and that modification is a pain (which we disabled by adding<AutoParameterizationWebConfigConnectionStrings>false</...> to the .csproj file - yuck!)` .
We tried fussing with the parameters in the Build Solution step:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"
Changing DeployOnBuild to false caused the $(build.artifactsstagingdirectory) to be empty (causing the next step to deploy nothing)
Changing WebPublishMethod to FileSystem made no difference (try finding documentation on the allowed values!)
Changing PackageAsSingleFile to false did what one would expect - no zip, but the contents were still buried in that deep folder structure.
Our downstream script could open the manifest file, xpath out the deep path baked into the zip (does the path always start with d_C?), unzip and grab the contents from there - but what a pain and how unnecessary.
Is there a way to publish just a nice clean build - a zip with contents that directly unpacks to the same files as a plain-jane Publish from Visual Studio does?
In the Visual Studio Build step change "MSBuild Arguments" to
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\" /p:UseWPP_CopyWebApplication=true /p:OutDir="$(build.artifactstagingdirectory)"
The key thing is /p:OutDir="$(build.artifactstagingdirectory)" resolves the directory issue and /p:UseWPP_CopyWebApplication=true removes web.config.release and web.config.debug
Then update Publish Build Artifacts step "Path to publish" to
$(build.artifactstagingdirectory)\_PublishedWebsites

Resources