MSbuild command line parameter for skipping the directory - msbuild

I have following command line parameters in team city for deployment. everything works fine but i want to skip some directory while deployment. how can i add that logic in following msbuild script in team city
/P:Configuration=%env.Configuration%
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=https://%env.TargetServer%/MsDeploy.axd
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True
/P:SkipExtraFilesOnServer=True
/P:UserName=xxxxx
/P:Password=xxxxx

I was working on the same thing. I didn't like having to modify my .csproj file, so I tried this. It is working for me so far. In my case, I was excluding the media, App_Data\Logs, and App_Data\preview folders from deployment instead of the Data folder.
Basically, you can pass the ExcludeFoldersFromDeployment as a parameter to MSBuild. Combining that with the SkipExtraFilesOnServer does the trick.
/p:Configuration=Debug
/p:DeployOnBuild=True
/p:DeployTarget=MSDeployPublish
/p:MsDeployServiceUrl=OurDevWebServer/msdeployagentservice
/p:AllowUntrustedCertificate=True
/p:MSDeployPublishMethod=RemoteAgent
/p:CreatePackageOnPublish=True
/p:DeployIisAppPath=umbraco_TestSite
/p:IgnoreDeployManagedRuntimeVersion=True
/p:SkipExtraFilesOnServer=True
/p:ExcludeFoldersFromDeployment="media;App_Data\Logs;App_Data\preview"
/p:IncludeSetAclProviderOnDestination=False
/p:AuthType=NTML /p:UserName=

You can't specify a WPP skip rule via the command line because they are declared as items, not properties.
Here is the syntax for declaring the skip rule inside your pubxml (or wpp.targets):
<ItemGroup>
<MsDeploySkipRules Include="SkipErrorLogFolder1">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>ErrorLog</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>

Actually I already implement this in my project as follow:
<ItemGroup>
<MsDeploySkipRules Include="SkipDeleteApp_Data_Import">
<SkipAction></SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_Escaped_WPPAllFilesInSingleFolder)\\App_Data\\Import</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
<ItemGroup>
<MsDeploySkipRules Include="SkipDeleteApp_Data_File">
<SkipAction></SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_Escaped_WPPAllFilesInSingleFolder)\\App_Data\\en-US-custom.txt</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>

Related

MSBuild ignores GatherAllFilesToPublish?

So, I created a publish profile for my web app. I did this with the GUI in VS 2017 Enterprise. I then found an example of how to change the pubxml to make it zip all the output files. Eventually I ended up with this:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<PrecompileBeforePublish>True</PrecompileBeforePublish>
<EnableUpdateable>True</EnableUpdateable>
<DebugSymbols>False</DebugSymbols>
<WDPMergeOption>DonotMerge</WDPMergeOption>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>bin\Release\Publish</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
<Configuration>Release</Configuration>
</PropertyGroup>
<Target Name="ZipPublishOutput" AfterTargets="GatherAllFilesToPublish">
<Exec Command='powershell -nologo -noprofile -command "compress-archive -force -path $(WPPAllFilesInSingleFolder)\* -destinationpath $(publishUrl).zip"' />
</Target>
</Project>
This works perfectly fine if I do a publish through Visual Studio. However, I've been trying everything I can think of to get this to work in MSBuild, with no luck.
Here is an example of what I think should work:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe" WebApp.csproj /nologo /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=ReleasePublish
And for reference, here is the version of MSBuild:
Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe for .NET Framework
I know MSBuild is finding the profile pubxml because I can make a change to the settings, such as publishUrl, and those changes are applied the next time I run MSBuild. What doesn't seem to work is the ZipPublishOutput target. And even running MSBuild with diagnostic verbosity shows that GatherAllFilesToPublish never runs, which would mean my target wouldn't run.
I've found many different suggestions and nothing seems to help. A lot of the solutions I found seemed to be with MSBuild not finding the pubxml, but that's not the case here.
So, is GatherAllFilesToPublish something that is Visual Studio specific, and therefore MSBuild doesn't know about it? That seems like how it's acting.
Just got the same problem using msbuild with Jenkins.
To execute the target GatherAllFilesToPublish with msbuild I had to add the target /t:GatherAllFilesToPublish in the msbuild command line.
You should have something like this :
/p:DeployOnBuild=true /p:PublishProfile=fullPathToMyPubXML.pubxml
/t:GatherAllFilesToPublish

MSBuild target with MSBuild task pass in properties from command line

I have a targets file which uses the MSBuild task to compile bunch of .csproj files. This works as expected.
Is it possible to take the properties from the commandline?
<Target Name="MyBuild">
<MSBuild Projects="#(Projects)" Properties="FROM COMMAND LINE"/>
</Target>
msbuild mybuild.proj /p:myProperty=true
You can do something like this:
<Target Name="MyBuild">
<MSBuild Projects="#(Projects)" Properties="$(MyProperties)"/>
</Target>
and call MSBuild this way:
msbuild mybuild.proj /p:MyProperties="MyProperty=true;MyOtherProperty=false"
Environment variables can be used to set MSBuild properties. We use batch files to set env variables based on command line parameters, which then invokes MSBuild after setting env variables based on the command line parameters.

How to change verbosity of the MSBuild task?

I'd like to have a different verbosity for the msbuild project invoked from the commandline, and those invoked by the MSBuild task from within the project. For example:
Inside my.proj:
<Target Name=Foo>
<MSBuild Projects="a.csproj;b.csproj;c.csproj"/>
</Target>
On the commandline:
msbuild /v:d my.proj
now when the MSBuild task builds the .csproj files, it does it with detailed verbosity as well. However I'd want to build it with minimal verbosity.
I know it is possible to invoke msbuild manually like so:
<Target Name=Foo>
<Exec Command="msbuild /v:m a.csproj"/>
<Exec Command="msbuild /v:m b.csproj"/>
<Exec Command="msbuild /v:m c.csproj"/>
</Target>
or in practice
<Target Name=Foo>
<Exec Command="msbuild /v:m %(Projectlist.Identity)"/>
</Target>
and this works well off course, but then I cannot get the functionality of the BuildInParallel switch anymore (I do not think it is possible to invoke msbuild from the commandline with multiple projects without them being contained in a solution?)
Update
I went with Ludwo's option: basically create a custom logger that holds two ConsoleLoggers as a member. One has the verbosity passed at command line, the other one is 'minimal'. The logger registers for all events and passes them to one of the loggers depending on whether a csproj file is currently being built or not. Output looks exactly like normal, except it doesn't include thousands of lines from the csproj files.
You have two options (at least) :)
Create one additional msbuild script for building abc projects
"BuildABC.proj"
<Target Name="BuildABC">
<MSBuild Projects="a.csproj;b.csproj;c.csproj" BuildInParallel="true"/>
</Target>
In your parent script execute MSBuild using Exec task and call
"BuildABC.proj" with minimal verbosity
<Target Name=Foo>
<Exec Command="msbuild /v:m /m:2 BuildABC.proj"/>
</Target>
You have to pass explicitly all parent properties needed in the BuildABC project to msbuild /p parameter.
Use custom logger. See this how to do it. In this case you can use your original script:
<Target Name=Foo>
<MSBuild Projects="a.csproj;b.csproj;c.csproj"/>
</Target>
In your custom logger do not log anything related to e.g. "a.csproj" project between ProjectStarted and ProjectFinished events where e.ProjectFile == "a.csproj" (to disable diagnostic logging on "a.csproj" project while building parent project with diagnostic verbosity)

Property scope using msbuild extension pack detokenise

Im trying to use the msbuild extensions pack to fix up the configuration of our app on deploy,
i want to be able to pass a property (ENV) which will load my environment specific config file to use with the detokeniser, and fix up my application configs.
Like this:
<UsingTask TaskName="MSBuild.ExtensionPack.FileSystem.Detokenise"
AssemblyFile=".\Tools\MSBuild Extension Pack 4.0.3.0\MSBuild.ExtensionPack.dll"/>
<Import Project=".\Environments\$(Env).properties"/>
<Target Name="Build" >
<ItemGroup>
<SourceTemplates Include=".\Templates\**\*.*"/>
</ItemGroup>
<RemoveDir Directories=".\Temp"/>
<MakeDir Directories=".\Temp"/>
<Message Text="#(SourceTemplates)"/>
<Copy SourceFiles="#(SourceTemplates)"
DestinationFolder=".\Temp\%(RecursiveDir)" />
<ItemGroup>
<TargetTemplates Include=".\Temp\**\*.*"/>
</ItemGroup>
<MSBuild.ExtensionPack.FileSystem.Detokenise
TaskAction="Detokenise"
TargetFiles="#(TargetTemplates)"/>
</Target>
So i call this using
msbuild Detokenise.msbuild /p:Env=Prod
Msbuild knows about my file and i have access to its properties, but when the detokeniser runs i get the error:
Detokenise Task Execution Completed [15:07:50]
C:\Source\1.2\Build\Detokenise.msbuild(27,3):
error : InvalidProjectFileException: The imported project "C:\Source\1.2\Build\Environments\.properties" was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
C:\Source\1.2\Build\Detokenise.msbuild\r
C:\Source\1.2\Build\Detokenise.msbuild(27,3): error :
All works fine if i hard code it-
Any ideas how to solve this. I thought of doing some text replacement on the msbuild before i execute...
You could try to assign this parameter to a local property:
<PropertyGroup Condition="'$(Env)'=='Prod'">
<TargetEnv>Prod</TargetEnv>
</PropertyGroup>
<!-- add other environments as needed -->
<PropertyGroup Condition="'$(Env)'=='Test'">
<TargetEnv>Test</TargetEnv>
</PropertyGroup>
<Import Project=".\Environments\$(TargetEnv).properties"/>
You could also try to enclose your parameter value in quotes:
msbuild Detokenise.msbuild /p:"Env=Prod"
As is your problem can't be reproduced, so it may be a side effect of other parameters not shown in your sample code.
I've seen a number of other questions where a similar problems was happening:
Visual Studio Ignoring MSBuild file (csproj) Customizations

MSBuild doesn't respect PublishUrl property for my ClickOnce app

I'm trying to make a batch file to publish the few ClickOnce application we have in one click. I'm using msbuild for that, and as an example the below command line shows how I'm doing it:
msbuild
MyApp.sln
/t:Publish
/p:Configuration=Release
/p:PublishUrl="C:\Apps\"
/v:normal > Log.txt
(wrapped for easier reading)
when I run the above command it builds and publish the application in the release directory, i.e. bin\release! Any idea why msbuild doesn't respect PublishUrl property in my example above?
PS: I tried also different combinations including remove 'Configuration', use 'Rebuild' and 'PublishOnly' as targets, and remove the the quotation marks but without any success.
You are setting the wrong property. Try PublishDir instead.
You can pass it into MSBuild as you are or you can set it in the project file (or maybe the sln file too, not sure I always use the project file.) like this
<PropertyGroup>
<PublishDir>C:\Dev\Release\$(BuildEnvironment)\</PublishDir>
</PropertyGroup>
I've just done a few blog posts on MsBuild and ClickOnce stuff, check it out you 'should' find them useful...
Some features are done by Visual-Studio and not by the MSBuild-script. So the click-once-deployment behaves differently when it's executed from the command-line.
The ApplicationRevision isn't increased with every build. This works only when is exectued from Visual Studio
In in somecases, the PublishUrl isn't used. Quote from MSDN:
For example, you could set the PublishURL to an FTP path and set the InstallURL to a Web URL. In this case, the PublishURL is only used in the IDE to transfer the files, but not used in the command-line builds. Finally, you can use UpdateUrl if you want to publish a ClickOnce application that updates itself from a separate location from which it is installed.
I've created a special MSBuild-file which does this things. It runs the publish-target and copies then the files to the right location.
An example of the build-file, as requested by alhambraeidos. It basically runs the regular VisualStudio-build and then copies the click-once data to the real release folder. Note that removed some project-specific stuff, so it's maybe broken. Furthermore it doesn't increase the build-number. Thats done by our Continues-Build-Server:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Publish" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- the folder of the project to build -->
<ProjLocation>..\YourProjectFolder</ProjLocation>
<ProjLocationReleaseDir>$(ProjLocation)\bin\Release</ProjLocationReleaseDir>
<ProjPublishLocation>$(ProjLocationReleaseDir)\app.publish</ProjPublishLocation>
<!-- This is the web-folder, which provides the artefacts for click-once. After this
build the project is actually deployed on the server -->
<DeploymentFolder>D:\server\releases\</DeploymentFolder>
</PropertyGroup>
<Target Name="Publish" DependsOnTargets="Clean">
<Message Text="Publish-Build started for build no $(ApplicationRevision)" />
<MSBuild Projects="$(ProjLocation)/YourProject.csproj" Properties="Configuration=Release" Targets="Publish"/>
<ItemGroup>
<SchoolPlannerSetupFiles Include="$(ProjPublishLocation)\*.*"/>
<SchoolPlannerUpdateFiles Include="$(ProjPublishLocation)\Application Files\**\*.*"/>
</ItemGroup>
<Copy
SourceFiles="#(SchoolPlannerSetupFiles)"
DestinationFolder="$(DeploymentFolder)\"
/>
<Copy
SourceFiles="#(SchoolPlannerUpdateFiles)"
DestinationFolder="$(DeploymentFolder)\Application Files\%(RecursiveDir)"
/>
<CallTarget Targets="RestoreLog"/>
</Target>
<Target Name="Clean">
<Message Text="Clean project:" />
<MSBuild Projects="$(ProjLocation)/YourProject.csproj" Properties="Configuration=Release" Targets="Clean"/>
</Target>
</Project>
I'll put in my 2 cents, this syntax seems to work (right or wrong):
/p:publishUrl="C:\\_\\Projects\\Samples\\artifacts\\Web\\"
For me, the soultion was to escape the path.
Instead of:
/p:PublishUrl="C:\Apps\"
Put:
/p:PublishUrl="C:\\Apps\\"