How do I build a VSTS project with an absolute-path reference folder? - azure-devops

I have two projects in TFS, WebSite and Reference, and they follow the structure:
$\
WebSite: Main project to be built
Reference: Repository with many referenceable dlls.
Website.dll uses dlls existing at Reference but, for several reasons, they are not contained in the same solution, and may be mapped to different folders that do not follow the VSTS structure.
So, in order to have the Website project compiling locally, the Reference's.dlls Hintpath at Website.csproj have been manually changed to a specific, absolute path, common to all developers' machine.
Now, we're experiencing with CI/CD, and we're thrilled with the hypothesis of having VSTS doing the dirty, tedious work of building/deploying. Thing is, since Reference.dll is not in the same project as Website, building ends up lacking essential libraries (the aforementioned Reference folder) and fails.
Is there a way of telling VSTS to GET Reference's dlls (which are compiled at this point), copy them to the directory Website.csproj is being built at and let them be used to build the main project?
What I've tried:
First:
Map Website and Reference in the Get Sources step
Using a Copy Files task, set Source FOlder as $\References and Target Folder as $(Agent.BuildDirectory)
Build
Now:
Added all the references in the main project.
In both cases, none of the references are found, and the
The type or namespace name '(namespacehere)' could not be found (are you missing a using directive or an assembly reference?)
errors are thrown.
I've been searching through the vsts help section, but can't seem to find any obvious solutions.
Any help is greatly appreciated.

It’s mainly caused by the Reference's dlls are not added in source control (TFVC repo).
First, please make sure you add the Reference's dlls into the website project. So the project file will contain the reference as below (ClassLibrary1.dll as the reference in below example):
<Reference Include="ClassLibrary1">
<HintPath>..\..\ClassLibrary1\ClassLibrary1\bin\Debug\netstandard2.0\ClassLibrary1.dll</HintPath>
</Reference>
Then you can use any of below options to make the referenced dlls work.
Option 1: add the referenced dlls into source control
If you have added .tfignore file into your TFVC repo, it will ignore files and folders under **\bin, so the reference dlls not checkin to TFVC repo by default. You can follow below options to checkin the reference dlls into TFVC repo:
Exclude the reference dlls in .tfignore
Exclude the dlls you want to refer in .tfignore. The format is:
!**\referencename.dll
Such as !**\ClassLibrary1.dll.
Add the reference dlls into source control
In VS -> Source Control Explorer -> Add items to folder -> selected the dlls.
Checkin and double check the dlls are added into TFVC repo
In VS pending changes window, there will show the dlls and the .tfignore file as Inculded changes, checkin the changes.
And double check the dlls are added into TFVC repo in VSTS web page.
Option 2: build the reference project before building website project
If you do not want to add the dlls into source control, you can also build the reference solution firstly so that the reference dlls will generate before build the website project. Details as below:
Edit build definition -> add VS Build task (specify reference solution) before building website project -> Save and queue the build.
Note: for option 2, the build configuration you specified in the relative path should be consistent with the build configuration in VSTS build definition.
Such as I specified Debug in the relative path ..\..\ClassLibrary1\ClassLibrary1\bin\Debug\netstandard2.0\ClassLibrary1.dll. So in my VSTS build definition, VS build task to build the reference project, the build configuration must be Debug.
Now, no matter which option you are using, VSTS build will not show the error message The type or namespace name '(namespacehere)' could not be found.

The correct way to approach this is to not store references in source control. Turn them into packages, store them in a package management feed, and restore them during build. Developers will automatically restore them on build.

Related

Azure Pipeline generate a .sln/.csproj as part of the pipeline process from a folder

Is there a way to generate a solution and project file out of a folder structure through a azure pipeline .ymal stage?
The way the project has been set up is that there are lots of other .git repos set up inside a master repo and inserted though subtrees. These repos don't have a .sln in themselves but instead when they are added into Unity they get added into the projects .sln and a .csproj is generated for each of the assemblies within the submodule (package)
What I'm looking to do is to have documentation generated for each of these submodules whenever an update is pushed to its master (not the projects it lives in master) as these tend to be more utilities and self contained systems. Problem I'm facing is that I can trigger all the documentation system with docFX but because this module does not contain a .csproj I'm unable to generate the documentation for it. so I'm wondering if its possible to have a step where I can create a project file for all scripts that are within a folder structure, and as such then have a project file for docFX to work of.
I know its not ideal in any sense, but wondering if its a possibility while I investigate further into other solutions.
Is there a way to generate a solution and project file out of a folder
structure through a azure pipeline .ymal stage?
For this issue, I am afraid that azure pipeline is impossible to achieve this.
".csproj" is a Visual Studio .NET C# Project file extension. This file
will have information about the files included in that project,
assemblies used in that project, project GUID and project version etc.
This file is related to your project. It will be automatically
generated when we create
".sln" is a structure for organizing projects in Visual Studio. It
contains the state information for projects in .sln (text-based,
shared) and .suo (binary, user-specific solution options) files. We
can add multiple projects inside one solution.
Azure pipeline cannot generate a solution and project file according to the folder structure.

Can devops agent build projects containing linked items (ie: shared items from other solutions")?

I am attempting to set up a DevOps build definition to build a VS2017 solution on an on-site agent.
After adding the standard Visual Studio Build step to the build pipeline, the build agent reports the error:
"Error MSB3030: Could not copy the file "d:\agent_work..."
This seems to be happening for any LINKED item.
These items were added to the project from other solutions ("add existing item->Add As Link")
The solution/project builds fine locally on developers PCs, but not on agent.
All that is really required is for the build step to copy these files to an output directory to be included in the build artifacts.
Properties for all linked items are set to "content & copy always".
Error MSB3030: Could not copy the file "d:\agent_work..." because it was not found.
Am I missing something basic here?
This is a workspace mapping issue. You have files that aren't part of your build workspace. You will need to update your build to have a workspace that is mapped in a fashion equivalent to your developers' workspaces.
If your developers are referencing files outside their workspaces, this is a problem that you will have to rectify, then update the build accordingly.
Solved the build error : "Error MSB3030: Could not copy the file "d:\agent_work..." because it was not found." by adjusting the mappings in preceding "get sources" step. After looking at the logs of the build it appeared that the agent was looking in "d:\agent" for some items and "d:\agent\s" for other items (and not finding them). Don't know why it was looking in the "s" sub-directoy. But anyway, the work-around was to include the "s" in the local path mappings for "Local path under $(build.sourcesDirectory)" (ie: s/MyLocalPath)

Azure Devops Pipelines not building referenced projects

I am building a .net solution using the Azure Devops 2019 pipeline. The solution I am building is referencing projects in another directory. These projects are located in the source control however during the build I get the following error:
> ##[error]C:\a\_work\9\s\UI\UIProject\UIProject.sln.metaproj(0,0):
> Error MSB3202: The project file
> "C:\a\_work\9\s\Te\..\..\BusinessLogic\MyBLLProject\MyBLLProject.csproj"
> was not found
If I look at the Build server drive the BusinessLogic folder is missing even though the files are located in the source control.
Shouldn´t the build server take care of referenced projects and build them as well?
If you are trying to build/restore a simple project, the restore task will not handle the referenced project.
If you are trying to build/restore solution level .sln, the restore task will handle both projects.
However, according to your error info.
"C:\a_work\9\s\Te....\BusinessLogic\MyBLLProject\MyBLLProject.csproj"
was not found
It's a project not found, not some dlls not found, the issue should not related nuget side.
Just as comment suggest, you should double check your workspace mapping relationship. Make sure the get source steps will also download the referenced projects.
If the referenced project is in a separate repo, then your build will fail. I haven't tried it myself but you can reference other repo: https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops

Should I publish the nuspec file in a repository?

When creating an open source library on GitHub or another public website, should I publish the .nuspec file that describes the corresponding NuGet package?
I've done this a couple of times (since no API key or other sensitive information is included in the .nuspec file) in order to allow myself to easily publish subsequent versions without keeping private file, and to allow other people to fork it and add their own descriptions easily. However, the developers of many top packages don't seem to publish .nuspec files in their repositories (sometimes they publish NuGet.exe along with a .targets file, and so on), so I'm thinking that maybe I'm doing something wrong.
The package authoring should be considered part of the source code since it is a required asset to build the fully usable output.
Some projects use special msbuild-based tooling to create the nuspec file during the build so it seems like there is none in the repository. the new "SDK-based" projects (e.g. .NET Standard libraries) have integrated nuget tooling to be able to create a nupkg file from the csproj without the need to create a nuspec file. This tooling is also being adopted by some popular packages (e.g. Newtonsoft.Json).

TFS automated build + nuget package restore + shared projects in different solutions

I have a solution that contains shared projects with nuget package restore.
I have a second solution that references projects from the first solution.
I am trying to set up TFS to build the second solution, but it doesn't find references for the projects in shared solution because the packages folder for the first solution is in a different location than that of the second solution. I've included the first solution in the build, but now the build configuration doesn't exist in that solution.
First of all, it sounds as if the shared projects could be packaged themselves and as such be shared across these two solutions.
However, if you really don't want to do that, you might try the use the following NuGet commandline parameters and tweak the nuget.targets file in such way that they both point to the same package install directory. (note: you'll have to manually update the project references as well to point to the new packages location)
nuget.exe install -o "d:\some\dir"
You can simply modify the element in the nuget.targets file, or add this element in the csproj file's PropertyGroup with your own custom value.
<PropertyGroup>
<PackageOutputDir>d:\some\dir</PackageOutputDir>
</PropertyGroup>
One last remark: the output location path has to be the same on the client development machine as on the TFS build agents or it won't work.