How to tell dotnet watch to run a different build configuration? [duplicate] - docker-compose

This question already has answers here:
How to use "dotnet watch run" with .Net Core 3, Visual Studio 2019 and docker
(3 answers)
Closed 2 years ago.
Today I have a container running dotnet watch -v --project ".\\MyProject" run --no-launch-profile and the "MyProject" folder is mapped transparently to a .NET Core project of my solution. So whenever I alter a file in my Visual Studio it's picked up immediately inside the container and recompiled to allow quick alteration and testing. However I've noticed that this causes conflict issues when I build on my host machine causing a conflict over the bin\Debug\netcoreapp3.1\MyProject.exe
To solve this situation I wanted to see if I can pass an argument/parameter/configuration/... anything to dotnet watch that would tell it to use a different build configuration (copy of Debug really but called Container so that it'd create a separate folder and not conflict with the host Visual Studio)
Sadly I have not been able to locate an example or documentation on how to do this with dotnet watch. Is this possible? Is there a better solution?

Rather than target a different build configuration with dotnet watch, you can solve this by changing the output directory based on a built-in dotnet environment variable, DOTNET_RUNNING_IN_CONTAINER.
<Project>
<PropertyGroup Condition="'$(UsingMicrosoftNETSdk)' == 'true'">
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
<DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
</PropertyGroup>
<PropertyGroup Condition="'$(UsingMicrosoftNETSdk)' == 'true' AND '$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(UsingMicrosoftNETSdk)' == 'true' AND '$(DOTNET_RUNNING_IN_CONTAINER)' != 'true'">
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/local/</BaseIntermediateOutputPath>
<BaseOutputPath>$(MSBuildProjectDirectory)/bin/local/</BaseOutputPath>
</PropertyGroup>
</Project>

Related

How to run maui apps with dotnet cli

With typical web apps we do the following.
dotnet new webapp --name ./MyNewWebApp --framework net6.0
cd MyNewWebApp
dotnet build ./MyNewWebApp.csproj
dotnet run --project ./MyNewWebApp.csproj
And it works. Now I trying to play around with dotnet MAUI projects.
With MAUI the project file is complex when compared to a web project.
It has multiple target frameworks, and the csproj file looks as follows.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
<OutputType>Exe</OutputType>
...
</PropertyGroup>
<ItemGroup>
...
</ItemGroup>
</Project>
Further more, the launchSettings.json file is quite simple.
"profiles": {
"Windows Machine": {
"commandName": "MsixPackage",
"nativeDebugging": false
}
}
With visual studio I am able to create and run them. The Visual Studio launch tool bar shows the following.
So now with MAUI project, build command works fine.
dotnet build ./MauiCliBasic.csproj
But when I execute the run command, I get the following errors.
dotnet run --project ./MauiCliBasic.csproj
The launch profile "(Default)" could not be applied.
A usable launch profile could not be located.
Unable to run your project
Your project targets multiple frameworks. Specify which framework to run using '--framework'.
And when I specify the framework I still get the errors.
dotnet run --project ./MauiCliBasic.csproj --framework net6.0-windows10.0.19041.0
The launch profile "(Default)" could not be applied.
A usable launch profile could not be located.
So what am I missing?
This is a known issue that being tracked in these two threads: Unable to run Windows application from command line , Unable to run Windows application from .NET SDK command line, feel free to follow up with them. BTW, it might be related to the settings in the launchSettings.json file. You can refer to Error after modifying launchSettings: The launch profile "(Default)" could not be applied.

Azure Devops Release pipeline unable to take latest C# version

I have a console application which has async calls for e.g. the signature of the main method looks like this
static async Task MainAsync(string[] args)
{
}
I am able to compile the build in my local machine. But I have a VSTS (DevOps Azure) CI/CD pipeline where I am using a custom hosted agent in that machine, over there once the CI executes it gives the error:
##[error]CSC(0,0): Error CS5001: Program does not contain a static 'Main' method suitable for an entry point
I got it working by forcing the user agent to use VS2017.
Click phase 1 and then change it to the following:
HostedVS2017
This forces the user agent to use 2017 which has the latest version of C# instead of 2015 (which it was falling back to for me).
Can you try building your local code in release mode and see if you are getting the same issue.
Make sure to add C# 7.1 to any CPU and release property groups.
Right-click Your Project, click Properties
Click Build if it's not already selected
Change Configuration to All Configurations
Click Advanced...
Change the language version
Refer this issue in github for more details.
https://github.com/dotnet/roslyn/issues/21783
https://www.visualstudiogeeks.com/azure/devops/using-latest-version-of-csharp-with-dotnetcore
in pipeline
in visual studio build
add to MSBuild Arguments
/property:langversion=latest
or
Edit the c# Project and add
<LangVersion>latest</LangVersion>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PackageAction>BuildDefault</PackageAction>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PackageAction>BuildDefault</PackageAction>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Prevent post build event in VSTS

For development purposes my team has a post build event defined to pack and publish nuget packages locally. This step is not necessary during the build in VSTS because we have a step defined for that during the building to pack and ship the nuget packages to a different server, whithout symbols. Right now this step is executed in any build we run. How to prevent that only in the build server?
You're going to have to dig into MSBuild for this. You need to add a condition to check for one of the environment variables that's set when running in the context of a build, and only run if that environment variable is blank.
For example,
<PropertyGroup>
<PostBuildEvent Condition=" '$(BUILD_SOURCESDIRECTORY)' == '' ">echo Hello World</PostBuildEvent>
</PropertyGroup>
BUILD_SOURCESDIRECTORY is an environment variable that's populated when running in the context of a build, but isn't populated normally on a developer's desktop. Thus, echo Hello World will only run when that value is blank.

TFS - Run Powershell script against package before Deployment

I currently have a CI Setup in TFS 2013 which does the following
Pulls code down from Git on every commit to a branch
Builds the Solution
Runs N-Unit Tests Against the solution
Runs Jasmine Front-end Tests against the javascript
Deploys on success via WebDeploy to chosen server.
I have now managed to install Grunt and NodeJS on the server to do some manipulation of the Javascript between steps 5-6. Does anyone have any advice on how this might be done?
I've tried post-tests scripts to minify the javascript successfully on both the src and bin/_PublishedWebsites directory but this does not seem to persist over to the deployment server. And infact, the _PublishedWebsites route puts the build folder in an undeletable state due to maxmimum character limits on Windows files (argh).
You should switch over to using Release Management for Visual Studio 2013 (works with 2012 as well). This allows you to parameterize your release and push the same output through multiple environments. Very configurable and even makes sure that the tools you need end up on the server that you are deploying to. Supports Puppet, Chef, DSC, and create your own.
http://nakedalm.com/installing-release-management-server-tfs-2013/
And for an overview: http://nakedalm.com/building-release-pipeline-release-management-visual-studio-2013/
I managed to get this working with the addition of two extra steps to the pubxml file used for the deployment.
First, i added a dependency powershell script which ran NPM install and grunt tasks.
<PipelineDependsOn>
CustomBeforePublish;
$(PipelineDependsOn);
</PipelineDependsOn>
<Target Name="CustomBeforePublish">
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -file Pre_Deploy_Javascript_Build.ps1 $(ProjectDir)"/>
</Target>
Following this. I had now created additional files which did not exist in the project. I had to now ensure that these were published. To do this, i added another step.
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CopyMinJSFiles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn >
<Target Name="CopyMinJSFiles">
<ItemGroup>
<_MinJSFiles Include="$(ProjectDir)\App\*.js" />
<FilesForPackagingFromProject Include="%(_MinJSFiles.Identity)">
<DestinationRelativePath>App\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>

SpecFlow wrongly using NUnit

I've just (today) tried SpecFlow for the first time. I'm playing about by creating a new class library in VS2010 Pro and adding a SpecFlow Feature Definition file.
Thing is, the integration doesn't appear to be working properly, with a variety of different errors. I've selected MsTest as the test runner, because I can't be bothered with invoking NUnit (I'd like to use NUnit in the long term but at the moment I just want to get some BDD code working). The generated code files however continue to reference NUnit - which is obviously wrong, since I've just told SpecFlow to run using MsTest. I've done everything I can think of to invoke the code generation again, including creating a brand new class library project with the MsTest option selected in Tools > Options > SpecFlow.
If I leave the test runner field set to 'Auto' and right-click a feature file, then select 'Run SpecFlow Scenarios' I get an error message "Could not find matching test runner".
If I instead change the test runner field to MsTest, I get a different error message on doing the same thing - "Object Reference not set to an instance of an object". I'm not surprised at this one since it's still trying to run NUnit tests even though I've explicitly asked for MsTest, though obviously it shouldn't nullref and present that to the user.
What am I doing wrong? The documentation is not helpful, and as far as I can see, there's no FAQ.
edit #1: I've established that the actual setting I'm looking for is provided using App.Config using the field <unitTestProvider name="MsTest" />. I can see what's happened - the field in the Visual Studio options menu doesn't seem to modify the project you're currently working on. Thing is, this makes it look like that field doesn't do anything at all. I've now persuaded SpecFlow to generate MsTest classes and run using the MSTest runner.
So now the question morphs into a slightly different one: What (if anything) does the Tools > Options > SpecFlow > Test Runner Tool field do?
With VS2010 the correct value is MsTest.2010 not MsTest as documented. Change your app.config (for the test assembly) and it will work fine (at least with SpecFlow 1.8)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<unitTestProvider name="MsTest.2010" />
<!-- For additional details on SpecFlow configuration options see https://github.com/techtalk/SpecFlow/wiki/Configuration -->
</specFlow>
</configuration>
In answer to your latest Question. What is the setting "Tools > Options > SpecFlow > Test Runner Tool" this setting controls what will actually run the tests, not what will generate the test code. If it is set to auto i believe it will look at the App.config file where you have set the unitTestProvider to determine what the best tool is to run the tests. An alternaive Test runner made by the same guys as SpecFlow is SpecRun http://www.specrun.com/
So when you go to run the tests it will use this option. As you have discovered though the code generator uses the config file to determine what type of test it should generate (mstest/nunit..)
If you ran the specfow installer ( https://github.com/downloads/techtalk/SpecFlow/SpecFlowSetup_v1.8.1.msi ) to install all the Visual Studio Intergration components when you change the App.config file it normally promps to regenerate the features using the new provider. The manual way to do this though is to right click the Feature and select "Run Custom Tool"
In regards to documentation have you found the git hub wiki?
https://github.com/techtalk/SpecFlow/wiki/Documentation
The way I've read this is that the test runner is entirely different to that of the code generator although that doesn't always make sense when the MsTest runner doesn't know about NUnit (I think). Out of the box, the latest version (v2.3.2) even when installed with SpecFlow.MsTest nuget package (of the same version) does not configure your machine to generate MsTest based classes in the background. I am running VS2017 and have Resharper installed as my 'test runner' but the main requirement for generating MsTest based code is a change to the app.config. As per the wiki documentation you also need the following in your app.config. When you save the config you should be prompted for the files to be regenerated.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="specFlow"
type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/>
</configSections>
<specFlow>
<unitTestProvider name="MsTest" />
</specFlow>
</configuration>
We are using ReSharper as a runner for SpecFlow acceptance tests; it worked well right out of the box. Although ReSharper is not free, but it worth every penny...
I was never able to get SpecFlow working right from Visual Studio, I spent some time working on it but never go anywhere. Though I found these instructions on setting up NUnit in Visual Studio 2010 and I use this shortcut to run my SpecFlow tests with good effect.
Overall we use PowerShell to run a lot of tests and I was able to incorporate the NUnit command line runner and SpecFlow report generator into a single script I can run easily.