TFS not weaving Fody assemblies - tfs

I am trying to use Fody.PropertyChanged on my project, so I have added [ImplementPropertyChanged] to my class.
It all works fine in local, on my dev machine.
However, when decompiling the TFS-generated binaries, I find that they are not weaved: they still have the Fody attributes.
The FodyWeavers.xml has the veaver:
<Weavers>
<PropertyChanged />
</Weavers>
Where do I look, and what do I look at, to find out why my assemblies are not weaved?
Thanks!

I have managed to weave the assemblies this way :
I have copied the contents of packages\Fody.xx\ into Assemblies\Fody\
I then have modified the .csproj to point to the copied .targets file (towards the end of the .csproj) :
<Import Project="$(SolutionDir)\Assemblies\Fody\build\dotnet\Fody.targets" Condition="Exists('$(SolutionDir)\Assemblies\Fody\build\dotnet\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\Assemblies\Fody\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\Assemblies\Fody\build\dotnet\Fody.targets'))" />
</Target>
I suspect that the TFS maintainers are downloading the Nuget packages in another folder (for instance to have only one copy of all the Nuget packages for all projects), which would mean that this kind of package cannot work the regular way.

Related

How to properly configure NuGet Packages for collaboration with DevOps (TFS)

I have read and gone trough the following:
https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#enabling-and-disabling-package-restore
https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore-troubleshooting
Why is there no packages folder in .my NET Core solution's containing folder?
'nuget' is not recognized but other nuget commands working
https://www.skylinetechnologies.com/Blog/Skyline-Blog/July_2016/Relocate_NuGet_Package_Restore_Folder
But i still have issues with the Folder Packages which contains the Packages for my solution, when i check in my code, for my on my side everything works fine, when someone else gets the checked in solution, he has to change the path that is set in the ProjectNameFile.csproj because the path there contains
../../../../NuGetPackages/....
but should be (and only works if changed to)
../Packages
But than when this persons checks in and i get this version, my packages folder is gone ... We have been using TFS on other projects here but this is a first for me ...
I tried all what the links i posted are suggestion but with no luck.
Tools > options > NuGet Package Manager looks like this:
I have a NuGet.Config file on the same level as my projectname.sln file which has following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<!-- I tried each line below seperately and together -->
<add key="globalPackagesFolder" value=".\packages" />
<add key="repositoryPath" value="C:\Development\projectname\Packages" />
</config>
</configuration>
So what i did now is i created a Packages folder on the projectname.sln level and when i build my solution, this works but hey, i can't do that each (X) time and i am sure there is a way of achieving this but don't know how.
Thank you in advance for any feedback.
How to properly configure NuGet Packages for collaboration with DevOps (TFS)
I suppose you are using the packages.config as nuget package management, because you said " he has to change the path that is set in the ProjectNameFile.csproj because the path there contains ../../../../NuGetPackages/....".
So, if you are using packages.config, you should use relative paths for the repositoryPath in your nuget.config file when you build the project with Azure DevOps.
As we know, when we build the project in the Azure DevOps, Azure DevOps always copy the project to the path like D:\a\1\s\xx, which is different with the path in your local. And NuGet always use the relative paths (..\packages or ../../../../NuGetPackages/...)in the ProjectNameFile.csproj like:
<Reference Include="packagename, Version=3.0.0.0, xxx">
<Private>True</Private>
<HintPath>..\packages\xxx\lib\net45\xxx.dll</HintPath>
</Reference>
In this case, when we build the project, nuget will still restore the nuget packages to absolute path C:\Development\projectname\Packages, but since the location of the project has changed to the D:\a\1\s\xx, so the relative paths for the HintPath in the .csproj file should also be changed accordingly, otherwise nuget can't find the corresponding dll file.
So, we should set the repositoryPath as relative paths in the nuget.config file, like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value=".\packages" />
</config>
</configuration>
With this setting, the path of the packages folder are based on the file nuget.config. As long as you have not modified the location of the nuget.config file, the HintPath does not need to be modified.
Note:
globalPackagesFolder is uesed for another nuget management type packagereference.
If you are working with someone else to develop a project, you need to unify the location of the nuget package, rather than continually modifying the HintPath manually. Otherwise it will cause confusion in your development.
Hope this helps.

sfproj - outpath Build error

Iam trying to build the sfproj using msbuild on my build machine , This is what Iam doing.
<target ="package">
<foreach item="File" property="sfproj">
<in>
<items refid="servicefabric.files.sfproj" />
</in>
<do>
<exec program="${msbuild14.exe}">
<arg value="${sfproj}" />
<arg value="/p:Configuration=${config}" />
<arg value="/p:Platform=x64" />
<arg value="/target:Package" />
</exec>
</do>
</foreach>
</target>
The error Iam getting on the build machine is
(_CheckForInvalidConfigurationAndPlatform target) ->
10:25:10 [exec] C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(724,5): error : The OutputPath property is not set for project 'App.sfproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Debug' Platform='x64'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project.
It appears that the Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.1.0 Nuget package contains an MSBuild target that skips building of the sfproj itself (that or makes certain options present in order for it to succeed).
In my case I had accidentally checked in some Nuget package folders into source control that were incomplete. Visual Studio saw the presence of the folder so it didn't try to redownload it. You need to make sure that the build folder is present and it contains an MSBuild target file. Your best bet is just to delete the packages folder entirely to ensure you're starting off with a fresh start.
https://ijustwrite.software/2016/07/20/ouputpath-property-not-set/
I ran into a problem with the same symptoms. It happened to me after upgrading the Azure SDK, but it seems to me that it could easily happen in a few ways. The trouble is that there are two paths in the sfproj file that lead into the directory where nuget packages are stored, oddly enough on the first and last line of the file. This causes problems because you may have overridden where nuget packages are stored (this is not at all uncommon). Since these are relative paths, it's easy for nuget to get the packages to where you have specified, but for the lines in the project to point to "..\packages" instead, which makes Visual Studio want to restore the packages, but to never think they have been restored as it's looking for them in the wrong place.
To fix it all you need to do is modify the paths in the sfproj file to point to wherever you have your nuget packages set to download (this setting is in the nuget.config file, which can be in any directory above your project directory).
These are the two broken lines in my sfproj file:
<Import Project="..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props" Condition="Exists('..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" />
<Import Project="..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets" Condition="Exists('..\packages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" />
Since I have the value ThirdPartyLibraries\NuGetPackages in my nuget.config file (which is two directories above my project file), these lines had to be modified to be the following in order to work again :
<Import Project="..\..\ThirdPartyLibraries\NuGetPackages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props" Condition="Exists('..\..\ThirdPartyLibraries\NuGetPackages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.props')" />
<Import Project="..\..\ThirdPartyLibraries\NuGetPackages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets" Condition="Exists('..\..\ThirdPartyLibraries\NuGetPackages\Microsoft.VisualStudio.Azure.Fabric.MSBuild.1.3.0\build\Microsoft.VisualStudio.Azure.Fabric.Application.targets')" />
And that fixes it right up. I was lucky: I had two sfproj files, one with this issue, and one without, so all I had to do was diff to see the trouble.

Including files outside of the project in MSBuild

I have found other posts here on StackOverflow that deal with my issue I am experiencing, for example:
MSBuild: Deploying files that are not included in the project as well as Include Files in MSBuild that are not a part of the project
I wanted to share the code that I was able to create after reading these posts and ask for some help as to why it might not be working?
To elaborate on what exactly is not wrong and what I intend to do. I am using Visual Studio 2012, and TFS 2012.
I have a batch file called CreateMyFiles.bat, and what I would like to do is execute this and then take the files it outputs (it outputs them to my Includes/Javascript/Bundled folder) and include them in part of the build in MSBuild (so that they are deployed to the target IIS server).
When I edited my local .csproj in my local Visual Studio and added the code below to the bottom of the file and reloaded, I was able to right click on my web projbect, select 'publish', and then select my local file-based publishing profile which did indeed deploy my files to the correct location. It worked!
I then checked in my code to TFS, and went to 'builds' on TFS, and queued a new build. Sure enough, I was able to see the files output to the same directory on the build server. Now, i'm not 100% sure about MSBuild but I noticed that just like when I hit publish locally, it created a _publishedWebsite folder on the build server as well (a directory above the source). The thing is, within this publishedwebsite folder, my manually created files were not present. Furthermore, going to the target web server after the build was done unfortunately did not have the files I wanted.
So it seems like if I were to manually select publish, the code below works, but if I were to queue a build with TFS, it does not work. Does MSBuild use publish? Could that be the reason it does not work below?
Here is the code I've placed in my .csproj file:
<Target Name="CustomCollectFiles">
<Exec Command="CreateMyFiles.bat" /> <!-- Generate Files -->
<ItemGroup>
<!-- Create an identity called _CustomFiles, and associate it to the files I created -->
<_CustomFiles Include="Includes\JavaScript\Bundled\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Includes\JavaScript\Bundled\*%(Filename)%(Extension) </DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<!-- Hook into the pipeline responsible for gathering files and tell it to add my files -->
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
I'm really stuck on this and wanted to ask for some help as to why the files might not be going. I suspect MSBuild doesn't use publish and that's why it works locally (because i'm selecting publish)?
Thanks so much for your help
UPDATE
Tried this as per comments below, but this time the files didn't even appear (so it seemed to not even run the tasks now). Any idea why? Did I type this right?
<Target Name="CustomCollectFiles">
<Exec Command="CreateMyFiles.bat" />
<!-- Generate Files -->
<ItemGroup>
<!-- Create an identity called _CustomFiles, and associate it to the files I created -->
<_CustomFiles Include="Includes\JavaScript\Bundled\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Includes\JavaScript\Bundled\*%(Filename)%(Extension) </DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<!-- Hook into the pipeline responsible for gathering files and tell it to add my files -->
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
CustomCollectFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>
UPDATE 2
When I take the above code, and place it into my pubxml file and then execute an actual publish, it works, but as far as I know our process is to just queue a build from TFS. Is it possible to hook into the above code block when simply queuing a build? Or do I need to publish?
to do a publish from TFS build you need to add the following arguments
/p:DeployOnBuild=true;PublishProfile=Release
obviously using your own PublishProfile name
In VS2012, the target was renamed from:
CopyAllFilesToSingleFolderForPackageDependsOn
to:
CopyAllFilesToSingleFolderForMsdeployDependsOn
Update: looks like the above Targets are not getting called from within VS2012 targets, can you replace it with a call to the Target "PipelineCollectFilesPhaseDependsOn"? That should fix it.
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
CustomCollectFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>

How to include custom folders when publishing a MVC application?

I have an "Uploads" folder with logos within in. I would like the VS2012 one-click publish to include this folder. Currently it is not.
How can I achieve this?
I did this for a web api project (not dot net core) which had Angular 6 as a front end. My visual studio version was 2017.
I had created a wwwroot folder where I was compiling angular files via custom build action & this folder was not included in my project.
I edited the project file & added these lines.
<PropertyGroup>
<PipelineCollectFilesPhaseDependsOn>
CustomCollectFiles;
$(PipelineCollectFilesPhaseDependsOn);
</PipelineCollectFilesPhaseDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<Message Text="Inside of CustomCollectFiles" Importance="high" />
<ItemGroup>
<_CustomFiles Include="wwwroot\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>wwwroot\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
I believe you need to set the folder's "Build Action" to "Content":
What are the various "Build action" settings in Visual Studio project properties and what do they do?
I tried all solutions above, but none of them worked. I'm using VS2017 and wasn't able to folder publish some help files. I edited the project file (.csproj) and added the following lines somewhere in de file.
<ItemGroup>
<Content Include="HelpFiles\**\*" />
</ItemGroup>
When I push the publish button all my help files are copied to the publish directory.
Go to Project Properties > Package / Publish Web
Then select the configuration combo that you want to setup up.
Below you have the Items to deploy. I just tested here with "All files in this project folder" and everything was published.
The only downside is that everything is getting deployed, I don't know if this is what you want.
There is an attribute named CopyToPublishDirectory to publish in vs profiles. You can specify this in .csproj file of the project.
<ItemGroup>
<Content Update="Foo\**\*" CopyToPublishDirectory="Always" />
</ItemGroup>
<ItemGroup>
<Content Include="Foo\**\*" />
</ItemGroup>
VS Publish Profiles
in my case i Created a folder in the bin folder and needed to include that folder in the publish.
and that code is worked for me.
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include=".\bin\Dlls\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\Dlls\%(RecursiveDir)%(Filename)%(Extension)
</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>CustomCollectFiles;
;</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>CustomCollectFiles;
;</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
hope that helps someone.
In visual studio 2019 community, you have to right click on the folder and then click on publish. You can see it is published to the destination i.e. existing publish folder
In visual studio 2022 you can publish a content folder separately by right clicking it and selecting "publish".
While this means an extra step when publishing the whole project, it means that you can just push out new content without having to publish the server again

Specify NuGet sources for build server to use with NuGet Package Restore?

I'm using NuGet Package Restore. I want to specify custom sources during a TFS build server process.
The NuGet.targets file in the hidden '.nuget' folder says that you can either specify sources repositories, or that it will fall back to the NuGet.config in %APPDATA%\NuGet\NuGet.config.
There is however a NuGet.config in the hidden '.nuget' folder as well. I assumed that if you did not specify sources repositories in NuGet.targets that it would fall back to the NuGet.config in the hidden '.nuget' folder. This doesn't seem to be the case.
Any ideas?
With the current version of NuGet it's possible to specify custom repositories in the solution's NuGet.config file and enable package restore during a build.
Having this NuGet.config file allowed us to automatically restore packages from internal repository under a TFS build without any other actions in the build definition:
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<packageSources>
<add key="Internal" value="http://MyInternalRepository/nuget" />
</packageSources>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
</configuration>
Note: TFS2013's default Build Process Templates already implements NuGet Package Restore workflow without any special configuration as stated here: http://docs.nuget.org/docs/reference/package-restore-with-team-build
If you enable package restore, you'll find a NuGet.targets MSBuild file in the $(SolutionDir)\.nuget folder.
You can set the package sources by modifying the <PackageSources>""</PackageSources> element.
Example:
<!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
<PackageSources>"http://packages.nuget.org/api/v2/;http://myget.org/F/myfeed/"</PackageSources>
According to pranavkm, one of the NuGet devs, at the time of this writing NuGet Package Restore will not use the NuGet.config in the hidden '.nuget' folder for sources. It's only used at the moment for a solution specific setting (to ignore source control bindings). He says it is on the radar for the NuGet team to leverage all aspects of NuGet.config but that it keeps getting bumped in priority.
Another option is to add sources to a machine-wide (not user-specific) nuget config on the build server.
https://stackoverflow.com/a/27569020/374837
in tfs build 2017 when you use the NuGet Restore task version 1.* you can select the NuGet.Config file to use during the build.
See image below NuGet Restore Task

Resources