Deploying static content via WebDeploy in MsBuild AfterBuild target - msbuild

I'm looking for a way to run a WebDeploy call from within my MsBuild target, with the WebDeploy call having nothing to do with the application being built.
I have a commandline msdeploy which looks like this:
msdeploy.exe –verb:sync
-source:contentPath="C:\MyFolderPath"
-dest:contentPath="C:\MyDestinationPath"
This works perfectly. Now I want to plug this into an msbuild file into the AfterBuild target:
<MSDeploy Verb="Sync"
Source="-contentPath:'C:\MyFolderPath'"
Destination="-contentPath:'C:\MyDestinationPath'" />
This gives me ERROR_PROVIDER_NOT_FOUND when I build. I've tried the -contentPath both with and without the -
I can't seem to find the documentation for the MsDeploy task though which isn't helping. Any help much appreciated

Delete the dashes ("-") in the Source and Destination attributes. You may also need to use escaped double quotes instead of single quotes but you can try it both ways:
<MSDeploy
Verb="sync"
Source="dirPath=%22$(FilesToPackageFolder)%22"
Destination="package=%22%(DeployTypes.DeployPackagePath)%22"
/>

Related

When I run msbuild, it makes a call to aspnet_compiler, but doesn't compile my site

I have created a custom .proj file that builds my web site project's solution. It seems to all work correctly and it produces an output. However, when I put it on the server, I got an error about "/Default.aspx is not precompiled and cannot be requested". After some digging I discovered that indeed the precompiled aspx files were not precompiling. In the output from msbuild, I found a call to aspnet_compiler:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v /WebApplication -p WebApplication\ -f -fixednames Output_PublishedWebsites\WebApplication\
When I run this command directly, it generates everything just fine.
How can I get my msbuild wrapper to perform this correctly?
My msbuild task looks like this:
<MSBuild Projects="$(SolutionFile)"
Properties="OutDir=$(OutputRoot);
Configuration=$(AspNetConfiguration)"
Targets="Build" />
I solved this by using the <AspNetCompiler /> task.

Full list of /P MSDeploy arguments for MSBuild from TeamCity

I currently use the MSBuild runner in TeamCity for continuous integration on my local server and this works very well. However, I'm having trouble finding a full list of supported command line switches for MSDeploy in the format that TeamCity expects them.
In my 'Parameters' section at the moment I using the following switches:
/P:Configuration=OnCommit
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=https://CIServer:8172/MsDeploy.axd
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True
/P:UserName=Kaine
/P:Password=**********
/P:DeployIISAppPath="OnCommit/MySite"
/P:SkipExtraFilesOnServer=True
/P:DeployAsIisApp=True
All of these seem to work fine and the MSDeploy works as expected.
The trouble comes when I want to add additional parameters.
I've looked up MSBuild parameters and the MSDeploy documentation and I only seem to find command line parameters like these:
msbuild SlnFolders.sln /t:NotInSolutionfolder:Rebuild;NewFolder\InSolutionFolder:Clean
http://msdn.microsoft.com/en-us/library/ms164311.aspx
It seems that these references for command line arguments don't correspond with the /P: format - for example CreatePackageOnPublish and DeployIISAppPath aren't recognised command line parameters, but they work fine in the TeamCity build process.
Where can I find a full documented list of MSDeploy arguments in the format
/P:Param=Value
Additional info:
There's a list of parameters here:
http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.workflow.activities.msbuild_properties.aspx
However this is not a complete list - for example, this list doesn't include DeployAsIisApp or SkipExtraFilesOnServer, which are both parameters that work from the Team City Build.
Also this related question (possibly duplicate): Valid Parameters for MSDeploy via MSBuild which contains some arguments - but still not a definitive list.
Firstly, the short answer is you can't find the complete list. MSBuild does not have a complete list of parameters you can chose from since you can send any parameter you like. It is a means of communication between the caller of MSBuild and the author of the MSBuild build script (a vs sln or csproj file for instance).
If the build script use the parameter it is used otherwise it is ignored.
So this is a valid call to msbuild:
msbuild /p:<anything>=<anything>
Secondly, you shouldn't send parameters to msbuild from teamcity using the /p: command options. Instead, set configuration or system properties in your teamcity build configuration. They will be passed to msbuild automatically as parameters.
Here are the parameters used by Visual Studio Team Services when creating an ASP.NET (Preview) build definition:
/p:DeployOnBuild=true
/p:WebPublishMethod=Package
/p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true
/p:PackageLocation="$(build.artifactstagingdirectory)\\"
One may also extrapolate from the <PropertyGroup /> blocks defined in these examples:
https://msdn.microsoft.com/en-us/library/ff398069(v=vs.110).aspx
From this example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>Package</WebPublishMethod>
<LaunchASiteUrlAfterPublish>False</LaunchASiteUrlAfterPublish>
<SiteUrlToLaunchAfterPublish />
<MSDeployServiceURL />
<DeployIisAppPath />
<RemoteSitePhysicalPath />
<AllowUntrustedCertificate>False</AllowUntrustedCertificate>
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<DeployAsIisApp>True</DeployAsIisApp>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<UserName />
<SavePWD>True</SavePWD>
<PublishDatabaseSettings>
<!— this section omitted to keep the example short -->
</PublishDatabaseSettings>
</PropertyGroup>
</Project>
You could derive the following list:
WebPublishMethod
LaunchASiteUrlAfterPublish
SiteUrlToLaunchAfterPublish
MSDeployServiceURL
DeployIisAppPath
RemoteSitePhysicalPath
AllowUntrustedCertificate
SkipExtraFilesOnServer
DeployAsIisApp
MSDeployPublishMethod
UserName
SavePWD
PublishDatabaseSettings

Running custom MSBuild tasks as part of the git deployment to Azure WebSites

Problem
As part of my csproj I have a custom MSBuild task that executes the YUICompressor and generates a compiled css and js file.
<PropertyGroup>
<CssOutputFile>$(OutDir)..\Styles\compiled.css</CssOutputFile>
<JavaScriptOutputFile>$(OutDir)..\Scripts\compiled.js</JavaScriptOutputFile>
<BuildDependsOn Condition="'$(Configuration)' != 'Debug'">
$(BuildDependsOn);
CompressorTarget;
</BuildDependsOn>
</PropertyGroup>
This runs fine as part of the git deployment and the file is being generated, however the Azure Web Sites deployment engine will then copy all the output files to another folder. In that process it seems it takes whatever you have in your csproj instead of whatever you have in the folder. That menas that the generated compiled.css and compiled.js won't be copied (because they are not in my csproj)
What Azure does to deploy your project should be exactly the same as if you do the following:
Right click on the project and choose Publish
Change the Publish Method to 'File System'
Enter a path and click Publish
So generally, you'll want to make sure that your build process works such that you get the right file when you do this local publish. If it does, then chances are you'll get the same results when git pushing to Azure.
The workaround I used for now is adding an empty compiled.css and .js file to the csproj and I wanted to write this question in case someone goes through the same thing.
It would be great if someone from MS can comment if there are plans on doing something different for this scenario.
Depending on where you place the compiled scripts, you can use star-includes in your project file:
<ItemGroup>
<Content Include="assets\**\*" />
</ItemGroup>
If Azure uses your project file to determine what gets deployed (which seems somewhat strange to start with), then that should work.

MSBuild via command line with multiple ReferencePath

How do I pass multiple ReferencePath in MSBuild in the command line. I'm currently using this
MSBuild /t:Rebuild "Solution1.sln" /p:ReferencePath="C:\My Library 1\obj\Debug; C:\My Library 2\obj\Debug"
MSBuild is returning an MSB1006 error. Take note that my reference paths have spaces in it.
Try escaping the semicolons as %3b
Try moving the quotes around the entire property expression, not just the values
/p:"Name=Value One;Value Two"
I had the same problem. This worked for me:
msbuild {{slnPath}} /t:rebuild /p:OutDir={{outputpath}} /p:Configuration=Release
Specify /p for every parameter
This wasn't working in powershell
msbuild C:\temp\project.sln /p:referencepath="C:\Checkout\References
\CRM 2011;C:\Checkout\References\Log4Net\4.0\release"
but works fine from an old fashioned cmd prompt.
No matter what I do, I can't seem to make it work using MSBuild. I now use DEVENVE.EXE to compile my solution; it would read my user project settings where the ReferencePath is saved and use that to locate the correct version of the DLL I want to use.
replacing the ';' with '3%B' seems to work in my setup with Nant and Jenkins

Can MS Deploy do a package and transform, but not deploy?

Using msbuild in .NET 4.0, I can build web project with the "Package" target, and it does a nice job of putting the package in a zip file. But, when I look at the web.config in there, it's not transformed, it has "$(ReplacableToken_Web_SiteConnection-Web.config Connection String_0)"
I can run the "TransformWebConfig" target and it will do the proper transform, but just in its own silo.
I can also run the "Build" target and pass the "DeployOnBuild=True;DeployTarget=MSDeployPublish" properties and it will deploy the package on my server with the proper web.config transform done.
But, if I want to manually deploy the package to the server, how do I do a "Package" with a "TransformWebConfig" so that the zip file has the final web.config in there?
If you want to skip this from happening then you need to set a property in your build. You can do this in two ways
Edit your project file
Create a .wpp.targets file
I would recommend #2. For this case create a new file in the same directory as your project file with the name {ProjectName}.wpp.targets where {ProjectName} is the name of your project. Then inside of this file you should place the following contents.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">
<PropertyGroup>
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
</PropertyGroup>
</Project>
In this case you are setting the property AutoParameterizationWebConfigConnectionStrings which tells the Web Publishing Pipeline to not insert those {} placeholders in the web.config for the connection strings.
The way we do this is by modifiying the project build to do the transform prior to packaging it up.
The Target is call TransformXml and is a part of Microsoft.Web.Publishing.Tasks.dll
In your own targets its
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
But it will be included in a default VS C# build.
So
<TransformXml Source="web.config" Transform="web.release.config" Destination="$(DeployPath)\web.config" />
Does the trick for us.
Set up those paths with the right ItemGroup ("content" most likely) and make sure that target gets fired prior to the call to Package in your .csproj, and the build output will contain a "Web.config" like normal, with the right transformed values.
Alternatively (we've used this for packages that need to be everything to everyone), you can use that trick to do ALL the transforms and include each of them in the final package.
Then you call Msdeploy manually and use its skip and replace directives (forgot the technical term) to only output the right one at deploy-time
Assuming you have a web.usethisone.config in your package, that looks like
-skip:objectname=filepath,absolutepath=web\..*\.config
-replace:objectName=filepath,match=.*web\.usethisone\.config,replace=web.config