Passing parameters to Web.config transformation in MsBuild script - msbuild

I have transformation file:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<runtime>
<asm:assemblyBinding xmlns:asm="urn:schemas-microsoft-com:asm.v1">
<asm:dependentAssembly xdt:Locator="Condition(asm:assemblyIdentity/#name='Company.Product')">
<asm:codeBase xdt:Transform="SetAttributes(version,href)" version="1.2.3.4" href="FILE://D:/Path/To/Company.Product.dll" />
<asm:bindingRedirect xdt:Transform="SetAttributes(newVersion)" newVersion="1.2.3.4" />
</asm:dependentAssembly>
</asm:assemblyBinding>
</runtime>
</configuration>
It is possible run task TransformXml (or something similar) with version as parameter?
My buildscript must recognize version of some assembly and set this version as attribute in web.config file.

Related

How to install a NuGet package based on major version

We use myget.org as NuGet server and here I upload a package named e.g. mypackage with two different major versions e.g. 6.0.1 and 7.0.1, and there can be several versions for each major version but I always want to have the latest version though the correct specified major version. So in one branch of my code I want to have 6.0.X (X = latest) and from another branch I want to have 7.0.X
Currently I do below in my msbuild, where MyPackage id have major version in the name, but that is not scalable.
<ItemGroup>
<Packages Include="MyPackageX">
<Source>https://xxx.myget.org/myfeed/index.json</Source>
</Packages>
</ItemGroup>
<Exec Command="$(NugetExe) install %(Packages.Identity) -Source %(Source)
-OutputDirectory $(PackagesFolder)\Package -ExcludeVersion -noninteractive
-prerelease -verbosity detail" />
I would perfer to do it from a msbuild script. Is it possible?
Simplified example
Build.msbuild file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="4.6.3" />
</ItemGroup>
<Target Name="Build" />
</Project>
In the same folder I have a nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositorypath" value="packages" />
</config>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
From my developer command I type: msbuild build.msbuild
But no NuGet is installed so it doesn't make much sense to use wildcard before this simple scenario works.

Set web.config transform in Asp.NET Core

I've just came across with problem of web.config transformation in asp.net core.
There are two files: base web.config and web.prod-zone-a.config. My aim is to use transformation inside web.prod-zone-a.config when publishing my project.
I have the following "prod-zone-a" configuration settings in .csproj:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'prod-zone-a|AnyCPU' ">
<IntermediateOutputPath>obj\Debug\netcoreapp1.1</IntermediateOutputPath>
<DebugSymbols>true</DebugSymbols>
<Optimize>false</Optimize>
<DefineConstants>TRACE;DEBUG;NETCOREAPP1_1</DefineConstants>
<Configuration>prod-zone-a</Configuration>
</PropertyGroup>
web.prod-zone-a.config looks like:
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore>
<environmentVariables xdt:Transform="Replace">
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="prod-zone-a" />
</environmentVariables>
</aspNetCore>
</system.webServer>
I tried to run publish by two commands:
dotnet msbuild /t:Publish /p:OutputPath=c:\delivery /p:Configuration=prod-zone-a
and
dotnet publish --configuration prod-zone-a --output c:\delivery
But no transformation applies to web.config on output - just the default value.
Do I miss something in configuration or command executing?
This worked for me:
Add web.release.config file to the project root.
In Visual Studio 2017, Publish using Web Deploy (make sure it is set to Release). Settings will automatically be picked up.
Sample transformation:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="PRODUCTION" xdt:Locator="Match(name)" xdt:Transform="SetAttributes" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
Update: If you want to remove web.config.release file and others on publish, simply edit your .csproj file and add something like this:
<ItemGroup>
<Content Remove="appsettings.Development.json" />
<Content Remove="web.release.config" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.Development.json" />
<None Include="web.release.config" />
</ItemGroup>
There is a well-documented tool on github for xdt-transformations.
Also it doesn't depend on command, both of dotnet publish and dotnet msbuild works fine
With the latest version of dotnet cli (2.1.400 or greater), you can just set this msbuild property $(EnvironmentName) and publish tooling will take care of adding ASPNETCORE_ENVIRONMENT environmentVariable to the web.config with the specified environment name.
Also, XDT support is available starting 2.2.100-preview1.
Sample: https://github.com/vijayrkn/webconfigtransform/blob/master/README.md
IIS Web Deploy ASP.NET Core (2.1) in Visual Studio 2017 (VS2017)
First do this: (ref:https://github.com/nil4/dotnet-transform-xdt#-use-with-msbuildcsproj-tooling)
Install package - dotnet add package DotNet.Xdt --version 2.1.0
Modify .csproj - add package - refer github
Modify .csproj - add transform code (ApplyXdtConfigTransform) at the end - refer github
Add web.DEV_Server.config transfor file by right-clicking on DEV_Server.pubxml
Added following to web.DEV_Server.config
<environmentVariable xdt:Locator="Match(name)" name="ASPNETCORE_ENVIRONMENT" value="Development" xdt:Transform="SetAttributes" />
Modify DEV_Server.pubxml to modify following setting value.
<LastUsedBuildConfiguration>DEV_Server</LastUsedBuildConfiguration>
Validate Connection & Publish
Deploy still uploads other config files, not sure how to stop that.
Following on from user1820686's answer above:
The github page misses out some of the steps required to add this for MSBuild/csproj tooling:
You need to open a command prompt in your project directory and run
dotnet add myProj.csproj package Microsoft.DotNet.Xdt.Tools --version 2.0.0
Then you need to open the csproj file and add
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.Dotnet.Xdt.Tools" Version="2.0.0" />
<!-- ... other package references ... -->
</ItemGroup>
may be i don't clear question. For mine case web.config override all settings in web.Release.config file.
Fix for me, i just add reference for transformation xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" to configuration file.
so, .config file should start:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
After some time, the best solutions is using dotnet-transform-xdt tool
This is now supported by dotnet publish from SDK version 2.2 with a whole bunch of options.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-2.2
I think in the example from the question, it would then work when published as
dotnet publish --configuration prod-zone-a
This worked for me with the 1. & 2. above:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location>
<system.webServer>
<httpErrors existingResponse="PassThrough"
xdt:Locator="Match(existingResponse)"
xdt:Transform="InsertIfMissing" />
</system.webServer>
</location>
</configuration>

MSBuild cannot find a reference - ReactJs.NET

After upgrading Newtonsoft.Json to version 9.0.0 and ReactJS.Net packages to 2.5.0, the TransformBabel.proj stopped working:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="TransformBabel">
<!-- ReactJS.NET - Transpile JavaScript via Babel -->
<UsingTask AssemblyFile="$(OutputPath)\React.MSBuild.dll" TaskName="TransformBabel" />
<Target Name="TransformBabel">
<TransformBabel SourceDir="$(MSBuildProjectDirectory)" />
</Target>
</Project>
Returning the following:
TransformBabel.proj(6, 3): error MSB4018: The "TransformBabel" task failed unexpectedly.
[Exec] TransformBabel.proj(6, 3): error MSB4018: React.TinyIoC.TinyIoCResolutionException: Unable to resolve type: React.IReactSiteConfiguration ---> System.TypeInitializationException: The type initializer for 'React.ReactSiteConfiguration' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
It seems that it cannot load the Newtonsoft 6.0.0.0 version. The web.config has an assembly redirection:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
But I am not sure that, as it is starting a new msbuild process, if it is being ignored. I would like to hint msbuild the location of the assembly, but no success until now.
A bit late to the party here, but hopefully my experience will help to anyone else having the same problem.
I have recently experienced the same issue with React.MSBuild 3.1.0. It seems that it has hardcoded a specific version as I have updated my Newtonsoft.Json to the latest (10.0.3) using NuGet and set redirection correctly, but the build kept failing on the same error as you have mentioned.
What I did is simply uninstall all the React packages (MSBuild and Core) and also Newtonsoft.Json (using -force as there were other dependencies) and then let NuGet install the React.MSBuild again. It has installed it with all dependencies what resulted in obtaining Newtonsoft.Json 9.0.1.
Not sure why do they restrict Newtonsoft.Json library to a specific version, but it is more a question to React developers. Unless you need a latest (or other specific version of it), this should fix the problem.
I know this is an old post...but here is my workaround:
I put Newtonsoft.Json.dll v6.0.0.0 into Tools directory relative to the project directory and let msbuild copy it to $(OutputPath) to satisfy TransformBabel task condition.
My TransformBabel.proj looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="TransformBabel">
<!-- ReactJS.NET - Transpile JavaScript via Babel -->
<UsingTask AssemblyFile="$(OutputPath)\React.MSBuild.dll" TaskName="TransformBabel" />
<Target Name="TransformBabel">
<Copy SourceFiles="$(MSBuildProjectDirectory)\Tools\Newtonsoft.Json.dll" DestinationFolder="$(OutputPath)" />
<TransformBabel SourceDir="$(MSBuildProjectDirectory)" />
</Target>
</Project>
After this TransformBabel task is finished, then let msbuild overwrite Newtonsoft.Json.dll v6.0.0.0 in $(OutputPath) with whatever Newtonsoft.Json.dll version my project is actually using, ex: v8.0.3.
So, in the main project .csproj, I have something like this:
<ItemGroup>
...
<Reference Include="React.MSBuild, Version=2.3.0.0, Culture=neutral, PublicKeyToken=9aed67b161f7db78, processorArchitecture=MSIL">
<HintPath>Tools\React.MSBuild.dll</HintPath>
<Private>True</Private>
</Reference>
...
</ItemGroup>
...
<ItemGroup>
...
<Content Include="Tools\Newtonsoft.Json.dll" />
<Content Include="Tools\React.MSBuild.dll" />
...
</ItemGroup>
...
<Target Name="TransformBabel" AfterTargets="Build">
<Exec Command=""$(msbuildtoolspath)\msbuild.exe" $(ProjectDirectory)TransformBabel.proj /p:OutputPath=$(OutputPath) /nr:false" />
</Target>
<Target Name="AfterTransformBabel" AfterTargets="TransformBabel">
<Copy SourceFiles="..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll" DestinationFolder="$(OutputPath)" />
</Target>
Replace the path Newtonsoft.Json.8.0.3 inside AfterTransformBabel task to your need.

Nuget add custom variables into .nuspec file compatible to XSD scheme

NuGet obtains packages from our own gallery server. A script then creates a CMAKE script with global variables for each package location. I want to add package specific variables like BOOST_INCLUDEDIR or BOOST_LIBRARYPATH with package relative pathes into the .nuspec file of the package. However, all variables shall be usable in CMAKE later.
The .nuspec xsd schema does not allow additional properties. Is there another solution ?
Here is an example of what I need:
<?xml version="1.0"?>
<package>
<metadata>
<id>boost_x86_src</id>
<version>1.55.0</version>
<authors>Fabian Stern</authors>
<owners>Fabian Stern</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Test Package</description>
<dependencies />
<frameworkAssemblies />
<references>
<reference file="signature.sig" />
</references>
<properties>
<add key="BOOST_INCLUDEDIR" value="include/win32" />
<add key="BOOST_LIBRARYPATH" value="libs/win32" />
</properties>
</metadata>
</package>

Why is msbuild duplicating entries in web.config transformations?

I am using web.config transformations to insert entries into the web.config for certain build configurations.
E.g. my Web.Test.config has this entry:
<elmah>
<errorMail from="me#me.com" to="me#me.com" async="false" smtpPort="25" smtpServer="mail" subject="test.senegal.co.uk Exception" xdt:Transform="Insert" />
</elmah>
This works absolutely fine building from visual studio.
However when creating a deployment package using msbuild, the entry is duplicated in the web.config. This obviously causes an exception.
Any ideas?
UPDATE
My "master" config is Web.Master.config not Web.config. The web.config file gets overwritten on build in visual studio. I think it must have something to do with this.
What I think is happening is msbuild is transforming web.config rather than using the Web.Master.config.
The question is how to tell it to use the right master.
I added /p:TransformWebConfigEnabled=false to the msbuild parameters, as my web.config was already being transformed in a BeforeBuild target like so:
<Target Name="BeforeBuild">
<TransformXml Source="$(MSBuildProjectDirectory)\Web.Master.config" Transform="$(MSBuildProjectDirectory)\Web.$(Configuration).config" Destination="$(MSBuildProjectDirectory)\Web.config" />
</Target>
In my case duplication was caused by xdt:Transform="Insert". If remove it from Web..config and leave the rest it will work properly, e.g.:
<!-- doesn't work -->
<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="My"
xdt:Transform="Insert" />
vs.
<!-- works -->
<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="My"
/>