dotnet publish -o ./dist does not set $OutDir or $OutPath in msbuild - asp.net-core

I Have a file move event which I want to trigger after a publish
<Target Name="CopyEmailTemplates" AfterTargets="AfterPublish">
<ItemGroup>
<TemplatesFolder Include="Views\EmailTemplates\*.cshtml" />
</ItemGroup>
<Copy SourceFiles="#(TemplatesFolder)" DestinationFolder="$(OutDir)Views\EmailTemplates\" />
</Target>
I've confirmed that the command does not return the publish directory with this target:
<Target Name="OutputTest" AfterTargets="AfterPublish">
<Exec Command="echo OutPath: $(OutputPath)" />
<Exec Command="echo OutDir: $(OutDir)" />
</Target>
Expected:
OutDir is set to dist/
Actual behavior:
OutDir is set to bin/Release/netcoreapp2.0/
I am using: .NET Command Line Tools (2.1.4) on osx.10.12-x64

Publish is a two-step process. The project is built using normal build settings and then published to $(PublishDir). Use this property wherever you need to know the path of the publish output.

Self answering in hopes to prevent future headaches for people.
The dotnet publish -o ./dist command will set the $(PublishDir) variable in msbuild.
dotnet build -o ./dist does however set $(OutDir)
To be more explicit with our build I now use the msbuild command
dotnet publish -o ./dist -c Release
Becomes:
dotnet msbuild /t:publish /p:PublishDir=dist/ /p:Configuration=Release

Related

What MSBuild condition should be used to detect target OS?

What Condition Expression for PropertyGroup/ItemGroup should be used to differ target OS (-r argument of dotnet publish)? E.g. on these commands:
dotnet publish -c Release -r win-x86 --self-contained false
dotnet publish -c Release -r linux-arm --self-contained false
Currently I've forced to use different Configurations and build using these commands:
dotnet publish -c ReleaseWin32 -r win-x86 --self-contained false
dotnet publish -c ReleaseLinux -r linux-arm --self-contained false
I know that MSBuild can define even target .NET Core/Framework version (e.g.Condition="'$(TargetFramework)' == 'netcoreapp3.1'"), so probably should also define target OS (something like Condition="'$(TargetOS)' == 'win-x86'").
Does there may be somehow used direct detection of target OS in CSPROJ file without using -c ReleaseWin32 / -c ReleaseLinux for builds for different platforms? Shortly, does MSBuild syntax have any Condition about target OS?
The CLI's -r linux-arm translates to MSBUild -property:RuntimeIdentifier=linux-x64 so you can use $(RuntimeIdentifier) in conditions:
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'linux-arm'">
</PropertyGroup>
<ItemGroup Condition="$(RuntimeIdentifier.StartsWith('win'))">
</ItemGroup>

ASP.NET Core publish FDD (not SCD) with output

I want to publish folder with framework dependent deployments - FDD. But as soon as I want to target different directory then default, application is published as self contained deployments - SCD.
This deploy as FDD:
dotnet publish -c Release
and this as SCD:
dotnet publish -c Release -o "d:\temp\publish"
How can I deploy as FDD and also defined output dir?
I am using .NET Core 2.1.
I also tried (but it's not working):
dotnet publish -c Release -o "d:\temp\publish" -f netcoreapp2.1
My .csproj file is:
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<Version>2.2.0</Version>
<PackagesRoot>..\</PackagesRoot>
<SpaRoot>Angular\</SpaRoot>
<WWWRoot>wwwroot\</WWWRoot>
<!-- Hides dist folders in wwwroot! -->
<DefaultItemExcludes>$(DefaultItemExcludes);$(WWWRoot)dist*\**</DefaultItemExcludes>
</PropertyGroup>
Status:
Not sure if this is a bug, but here is issue on GitHub.
Problem occurred when MSTest Test project (.NET Core) was added to project.
Solution is to specify target project and not publish entire solution.
This works:
dotnet publish ./Hosting/Hosting.csproj -c Release -o d:\temp //publish project
and this not:
dotnet publish -c Release -o d:\temp //publish solution
Here is link to additional explanation.
try specifying the framework like the line below:
dotnet publish -c Release -o "d:/temp/publish" -f netcoreapp2.1
more info about dotnet publish and examples for publishing
The output option works for both options, the difference between a framework-dependent deployment (FDD) and self-contained deployment (SCD) is in the -r RID option along with the optional --self-contained true/false flag (defaults to true when the -r option is used).
So you would use this to create a FDD:
dotnet publish -c Release -o "D:\temp\publish-fdd"
and an SCD with:
dotnet publish -c Release -r win-x65 -o "D:\temp\publish-fdd"
If you don't specify the -o option, the publish output will be put into the project's bin\Release\netcoreapp2.1\publish for FDDs or the runtime-specific subfolder bin\Release\netcoreapp2.1\publish\win-x64 for SCDs

MSBuild and Webpack

I am developing an Angular2 application in VS2015 and have a webpack bundling and minification environment set up for the same.
This is my webpack.conf.js
switch (process.env.NODE_ENV) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod');
break;
case 'test':
case 'testing':
//module.exports = require('./config/webpack.test');
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev');
}
I have also installed a webpack task runner which invokes this with the following commands
cmd /c SET NODE_ENV=development&& webpack -d --color
and
cmd /c SET NODE_ENV=production&& webpack -p --color
The setup seems to work fine. However, I want to integrate this with my TFS builds CI. The webpack command should fire after the project is built and report a build failure incase the webpack build fails. I have tried to incorporate the following code in my .csproj file
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="cmd /c SET NODE_ENV=production&& webpack -p --color">
</Exec>
</Target>
It failed with an error 9009
After that I tried, starting the command up from the node_modules folder where webpack was installed
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="./node_modules/.bin cmd /c SET NODE_ENV=production&& webpack -p --color">
</Exec>
</Target>
still in vain. Even if I get this to work, I am not sure if it would cause the VS build to fail if it encounters an error in webpack.
How do I go ahead with this?
Put different scripts in package.json for development and production mode. Then on 'AfterBuild' event of visual studio, call those scripts on different configurations.
Add following two scripts, 'buildDev' and 'buildProd' in package.json:
"scripts": {
"buildDev": "SET NODE_ENV=development && webpack -d --color",
"buildProd": "SET NODE_ENV=production && webpack -p --color",
}
In AfterBuild events of visual studio add these two conditional commands:
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="npm run buildDev" />
<Exec Condition="$(Configuration) == 'Release'" Command="npm run buildProd" />
</Target>
And finally webpack.conf.js like this:
switch (process.env.NODE_ENV.trim()) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod');
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev');
break;
}
Important Note: Make sure to use trim() function with process.env.NODE_ENV as cmd will treat the blank space in the command "SET NODE_ENV=development && webpack -d --color as character and append it in NODE_ENV variable. So when we are setting it as 'development', it actually gets set as (development + whitespace).
For TFS CI build, you can refer to these steps to achieve your requirement.
Add npm step
Add Command Line step
Note: There is –bail argument, which is required otherwise the step/task will be succeed even though webpack command throws exception.
Also, you can add variable in build definition (variable tab)

build error mono 3.4.0 centos

get source from downloads
make && make install
mkdir -p -- /usr/lib/mono/xbuild/Microsoft/Portable/v4.0
/usr/bin/install -c -c -m 644 targets/Microsoft.Portable.Common.targets /usr/lib/mono/xbuild/Microsoft/Portable/v4.0/Microsoft.Portable.Common.targets
/usr/bin/install: cannot stat `targets/Microsoft.Portable.Common.targets': No such file or directory
the mono 3.4 archive is missing a file named Microsoft.Portable.Common.targets which should be located at path mcs/tools/xbuild/targets/Microsoft.Portable.Common.targets with the following content:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\Microsoft.Portable.Core.props" />
<Import Project="..\Microsoft.Portable.Core.targets" />
</Project>
See this bug:
https://bugzilla.xamarin.com/show_bug.cgi?id=18690
Just a small note (as much for my self) which I made a mistake with as the path specified I found a little confusing. If you installed in extracted in /usr/local/src/mono-3.4/ the path of the file you need to put the content in is:
/usr/local/src/mono-3.4/mcs/tools/xbuild/targets/Microsoft.Portable.Common.targets
not
/usr/local/src/mono-3.4/mcs/tools/xbuild/targets/.content/Microsoft.Portable.Common.targets
or
/usr/local/src/mono-3.4/mcs/tools/xbuild/targets/.content

Exec Task in MSBuild for execution of command on remote machine

I am using following command to install a service via MSBuild file. This works great
<Exec Command= 'c:\test\myService.Appservices.exe install' ContinueOnError='false' />
But the above command install the service on local machine. I want to install the service on a remote machine. How can I specify the machine name using this command?
As per Mike Vine's comment, MSBuild doesn't include tools for remote execution. You could however use something like psexec. e.g.
<Exec Command='psexec -accepteula -s \\RemoteServer "C:\Path To EXE on Remote Machine\my.EXE"' IgnoreExitCode="false" ContinueOnError="false" Timeout="600000" >
<Output TaskParameter="ExitCode" PropertyName="exitCode1"/>
</Exec>