publish a website through MSBuild - web-deployment

I am trying to publish an asp.net website through msbuild on command prompt, but I did not get success.
I tried by creating a new web application and execute below command, it works.
C:\Windows\system32>msbuild.exe "C:\VisualStudio 2012\Projects\HelloWorldSample\HelloWorldSample\HelloWorld\HelloWorldSample.csproj" /p:DeployOnBuild=true /p:PublishProfile="HelloDeploy"
But my problem is, in website I don't have .csproj file. That's why I am unable to execute above command for that.
So please any one help me how I can do deploy for a web site.
Thanks.

If your website has no csproj project file it most likely is a directory containing just your website files. You can convert it to a Web Application (thus getting a csproj file) or directly use msdeploy to generate a deployable package and then use msdeploy to deploy it to your website. This is wat actually would happen under the hood when you run msbuild /p:DeployOnBuild
To create a msdeploy deployable website you can use the following snippet
msdeploy.exe
-verb:sync
-source:iisApp="C:\development\mywebsite\the-website-dir"
-dest:package="C:\temp\mywebsite-package.zip"
-declareParamFile:"C:\development\mywebsite\parameters.xml"
You will need to create at a parameter for the site name in the parameters.xml file which will be packaged with the zipped website project
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<!--
This file contains (among others) references to web.config fields (xpath)
which will be 'parameterized' on package before deploy. The actual values will then be filled in based on the given deploy environment.
-->
<parameter name="IIS Web Application Name" tags="IisApp">
<parameterEntry kind="ProviderPath" scope="iisApp" match="" tags="IisApp" />
</parameter>
</parameters>
This will generate a deployable msdeploy package which you can upload to your IIS by using:
msdeploy.exe -source:package=c:\temp\mywebsite-package.zip -dest:auto,computerName=https://mysite.example.com:8172/MsDeploy.axd,userName=USERNAME,password=PASSWORD,authtype=Basic, -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:example-setParameters.xml -allowUntrusted
Together with a setParameter file
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<setParameter name="IIS Web Application Name" value="mysite.example.com" />
</parameters>

Related

Precompiling a site for deployment using .targets file for MSBuild

I have an ASP.NET web project (.Net 4.5, Visual Studio 2015).
The solution uses the XAML builds, not the newer web builds. Some of the builds deploy the application directly to the IIS server using a file copy.
We do not use the Publish action from Visual Studio to publish the project.
In the .csproj file of the ASP.NET project, the following import statement was added to add an additional .targets file:
<Import Project="CSADeploy.targets" Condition="Exists('CSADeploy.targets')" />
<Target Name="AdditionalTargets">
<!-- ... -->
</Target>
In this target file the files are copied.
Here is a short excerpt from the .targets file:
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
I would like the code that is deployed to the server to be precompiled for deployment either Deployment Only or Deployment with updateable UI is fine. I know there is a checkbox in the Publish action to precompile but I can't use that. I must use the existing XAML builds with the targets file and possibly instruction in the .csproj file.
I also know that I can use the Aspnet_compiler.exe tool on the server once the file are deployed. But I must do it before the file are copied because I do not have access to this server and I want to prevent adding a manual action to the build process.
How can I precompile the ASP.NET pages for deployment so that they are deployed correctly in my scenario?
You could create a .pubxml file for your project then check in to TFS, in the .pubxml file, set precompileBeforePublish to True.
<PropertyGroup>
......
<PrecompileBeforePublish>True</PrecompileBeforePublish>
</PropertyGroup>
In the xaml build definition, add these msbuild arguments:
/p:deployOnBuild=true /p:publishProfile=***.pubxml
Then in TFS xaml build, it will do precompile before deploy.

Webdeploy - precompile asp.net application error with excluded connectionstrings in excluded app_data folder

I try to use webdeploy for our asp.net application. Today I tried to activate the "Precompile during publishing" flag. It seems that this flag doesn`t work together with the "Exclude files from the App_Data folder".
Before I activated the precompiling in webdeploy everything worked fine. If I remove the configSource from my connectionStrings and run the webdeploy with precompiling it works again.
The problem is that I have to load the external connectionstring file, because it will be managed by the administrators for production-environments.
The error message I get from webdeploy is:
"An error occurred loading a configuration file: Directory 'C:\MyProject\obj\Release\AspnetCompileMerge\Source\App_Data' does not exist. Failed to start monitoring file changes."
My current setup is the following:
Web.Config:
<configuration>
<!-- Section stuff here -->
<connectionStrings configSource="App_Data\DBConnection.xml" />
<!-- More stuff here -->
</configuration>
New webdeploy settings:
Try excluding the config file from the package by adding the following MSBuild script to either your project file or a wpp.targets file:
<ItemGroup>
<ExcludeFromPackageFiles Include="App_Data\DBConnection.xml">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
</ItemGroup>
Hey this did not work for us. But we also updated our tfs in the last days and we had a look into the webdeploy parameters which can be set easily with the release Manager from our new tfs. So we just readded he connectionstrings into the web.config and than we compile everything. In the end we decided where it's going to be deployed and than we set automatically the connectionstrings, which are hidden for us Devs.

MSBUILD script building solution, but not deploying publishing profile

I have created a publishing profile for my web page, and I can successfully publish using the web deploy interface in Visual Studio (right click project, deploy etc). It builds the project on my local PC, and copies the files across to destination IIS server.
But now I am trying to create a MSBuild command, which should do the same, but it is only building the solution, not copying it across to the server.
My MSbuild command looks like this, and I run it from the solution source directory
msbuild "test.co.za.sln" p:DeployOnBuild=true /p:PublishProfile="test.co.za" /p:UserName="domain\test" /p:Password="test"
Is there anything wrong with my build command? As you can see in the screenshot, it is building successfully, but no files are being copied across. Which makes me wonder if the publishing profile is executed at all.
I have tried various combinations of publishprofile paths, full paths, with extensions, without, nothing seems to copy my files accross.
My publishing profile looks like this App_Data\Publishprofile\test.co.za.pubxml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<SiteUrlToLaunchAfterPublish>http://test.co.za</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<MSDeployServiceURL>test.co.za</MSDeployServiceURL>
<DeployIisAppPath>test.co.za</DeployIisAppPath>
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<UserName>domain\test</UserName>
<_SavePWD>True</_SavePWD>
</PropertyGroup>
</Project>
EDIT: This is an existing classic ASP website which I added to a solution, it doesn't contain a ".csproj" file, just a "website.publishproj", which doesn't seem to execute
It doesn't look like you are passing in the VisualStudioVersion property. You should include that. The value will either be 11.0, 12.0, or 14.0 based on the version of Visual Studio you are using. You should likely pass in a value for Configuration as well but it's not required. I've blogged about why this is important at http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx.
You can find the docs for asp.net command line publishing at http://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/command-line-deployment
Looks like my "website.publishingproj" is never being built when I run the msbuild command. Not sure why, #Sayed do you perhaps know?
I had to create a targets file next to my solution called "after.solutionName.sln.targets" and copy the code from this answer : https://stackoverflow.com/a/15138373/1184603
<!--?xml version="1.0" encoding="utf-8"?-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Deploy Website" AfterTargets="Build">
<Message Text="Starting Website deployment" Importance="high">
</Message>
<MSBuild Projects="$(MSBuildProjectDirectory)\MyWebs\website.publishproj"
BuildInParallel="true" />
</Target>
</Project>
It now publishes correctly from my msbuild script.

How do I target an already existing application pool with webdeploy?

I am trying to make sure that my app gets deployed to a specific application pool that already exists when using Web Deploy. The application pool should be configurable by the user using the GUI when installing app through IIS Manager or by changing the value in the .setparameters.xml file when installing via the commandline from a web package. Inserting the following parameter entry into my parameters.xml doesn't do the trick.
<parameter name="Application Pool" description="Application Pool for this site" tags="iisApp" defaultValue="ASP.NET v4.0">
<parameterEntry kind="providerPath" scope="IisApp" match="applicationPool" />
</parameter>
Is there a straightforward way to accomplish this? If not, how would I go about getting this done?
Here's what I did to set the application pool via command line or SetParameters.xml after lots of reading on SO and elsewhere:
Add a Parameters.xml file to the project.
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="AppPool" defaultValue="ASP.NET 4.0">
<parameterEntry kind="DeploymentObjectAttribute" scope="application" match="applicationPool/#applicationPool" />
</parameter>
</parameters>
Sources:
How to specify MSDeploy parameters from MSbuild
http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html
Add two parameters to msbuild when creating the package:
/P:IncludeIisSettings=true
/P:IncludeAppPool=true
Source:
https://stackoverflow.com/a/13678143/448876
Set via SetParameters.xml:
<setParameter name="AppPool" value="Some AppPoolName"/>
OR
Using command line parameter (msdeploy or *.deploy.cmd):
"-setParam:'AppPool'='Some AppPoolName'"

How do I get msdeploy to create App_Data if it doesn't exist, but not delete any contents of the remote directory?

I have an application setup with the following Package/Publish Web settings:
Only files needed to run this application
(unchecked) Exclude generated debug symbols
(checked) Exclude files from the App_Data folder
(checked) Include all databases configured in Package/Publish SQL tab - note I do not have any databases configured
(unchecked) include IIS settings as configured in IIS Express
In the project, I have an App_Data folder setup, primarily to handle application logs.
The behavior I'd like to see (and expect) is the following:
On initial deploy to a brand new server, the application is copied and an App_Data folder is created with write permissions assigned for the application.
On subsequent deployments, the App_Data folder is ignored because it already exists and the "Exclude files from the App_Data folder" is checked.
However, msdeploy does not appear to do step #1 (step 2 is fine if I create the folder manually). I've been unable to find any documentation on the web besides this unanswered so question that seems to confirm the behavior I see.
How do I get msdeploy to create App_Data and assign permissions on initial deployment in this scenario?
Getting App_Data deployed when starting from scratch
#tdykstra got this part right. To get App_Data out there (and ACLs set automatically), I did the following:
Adding a placeholder file in App_Data
Set the build action to content on the placeholder (my placeholder file has text in it to let people stumbling across it know why it's there).
Unchecked "Exclude files from the App_Data folder" on the Package/Publish Web tab of the project properties in VS 2010
This gets my App_Data folder created and ready for use on the server. However, it will result in all my files getting deleted whenever I republish. This is problem #2 in my question above, and pretty closely resembles this other SO question/answer.
Preventing data on the server from being deleted on subsequent publish events
There are two mechanisms in MsDeploy that can get confused (at least I confused them):
Excluding files
MsDeploy skip rules
These can both be used to solve the problem, depending on the scenario:
#tdykstra's solution will likely work if you:
Know the names of the files in App_Data in advance (e.g. a sqllite database)
Have the files included in the App_Data folder in your project
The use MsDeploy skip rules to tell MsDeploy to completely skip all deletes on the server for that directory and files in that directory. This solves the problem in all cases, but is much more involved.
Implementing MsDeploy skip rules
To implement skip rules you'll have to abandon the right-click, Deploy option in VS 2010 in favor of right-click, Package, go into a command line, re-jigger a batch file and run a command line). If you're willing to put up with this experience (I am, because I'm automating it all through a CI process), here are the details:
Edit the project file and add the following. Note that the AbsolutePath argument is a regular expression, so you can get way fancy:
<Target Name="AddCustomSkipRules">
<ItemGroup>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
Package, do not deploy the project. This will create a zip file and .cmd file in the target directory (defined by "Location where package will be created" on the Package/Publish Web Tab). By default, this is obj\Debug\Package (or obj\Release\Package)
Deploy the site using the the resulting command file
In my testing, you must package and run the command file. The project file tweaks will tell msbuild to put the necessary -skip rule into the command file. However, using the "publish" feature straight from VS 2010 doesn't seem to run the command file (see the warning on this walkthrough)...it calls msdeploy directly and doesn't seem to honor the project file skip rules. I believe this is the difference between VS using msbuild -T:Package and msbuild -T:MsDeployPublish to build the project, but I have not tested this.
Finally, the command file isn't quite correct, at least in VS 2010 SP1. There's a great description of what goes wrong in this SO answer, but basically, VS (or maybe the /t:Package target is a better culprit) sets up the command file to publish to the machine without specifying a site. To fix that, you'll need to somehow get "?site=sitename" (probably this is ?site=Default+Web+Site, for a full URL of https://machine:8172/MsDeploy.axd?site=Default+Web+Site) onto the end of the computerName argument.
The problem I had was that the command file (batch file) has a hard time with using site= anything on the command line since it mis-parses the command line argument (even if escaped). I don't see a way around this problem other than modifying the cmd file directly, but for testing I copied the msdeploy.exe output I saw from my failed test run and modified that to call msdeploy.exe directly without the script.
Now that it's working, my intention is to work this into my CI build processes. What I'll be doing for the final solution is:
Change my build script to use /T:Package (right now it's /T:MsDeploy)
Have a scripted search/replace routine alter the generated cmd deployment script
Run the altered deployment script
This really should be easier.
Update
Here's the scripted search/replace routine I've come up with in PowerShell:
(Get-Content "project.deploy.cmd")
-replace('^set _ArgComputerName=$'
,"set ArgComputerName=https://server:8172/MsDeploy.axd?Site=Default+Web+Site")
| Out-File -Encoding ascii deploy.cmd
Once that is run, deploy.cmd can be called (without the /M option) and it will work as expected.
Web Deploy won't create a folder if there are no files to copy to it. One workaround in your scenario would be to not use the Exclude files from the App_Data folder check box, put a dummy file in App_Data (such as a .txt file with nothing in it), and specify file exclusion rules for whatever else you have in the App_Data folder (such as your .sdf file).
On excluding individual files (you can use wildcards), see the first question in the deployment FAQ on MSDN:
http://msdn.microsoft.com/en-us/library/ee942158.aspx#can_i_exclude_specific_files_or_folders_from_deployment
On using the dummy file method for causing a folder to be created, see Making Sure that the Elmah Folder gets Deployed in this tutorial:
http://www.asp.net/web-forms/tutorials/deployment-to-a-hosting-provider/deployment-to-a-hosting-provider-configuring-project-properties-4-of-12
I managed to get it working when using the Publish Web dialog from within Visual Studio. Note: it works for any folder and not only App_Data.
This is the basic .pubxml profile:
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Local</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>localhost</MSDeployServiceURL>
<DeployIisAppPath>SuperCoolAwesomeAppName</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>InProc</MSDeployPublishMethod>
<EnableMSDeployBackup>False</EnableMSDeployBackup>
<UserName />
<_SavePWD>False</_SavePWD>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
</PropertyGroup>
<PropertyGroup>
<UseMsDeployExe>true</UseMsDeployExe>
</PropertyGroup>
<Target Name="CreateEmptyFolders">
<Message Text="Adding empty folders to Files" />
<MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 1" />
<MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 2" />
<MakeDir Directories="$(_MSDeployDirPath_FullPath)\Files\Folder 3\Test"/>
</Target>
<Target Name="AddCustomSkipRules" DependsOnTargets="CreateEmptyFolders">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipFilesInFilesFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Files\\.*</AbsolutePath>
<Apply>Destination</Apply>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipFoldersInFilesFolders">
<SkipAction></SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Files\\.*\\*</AbsolutePath>
<Apply>Destination</Apply>
</MsDeploySkipRules>
</ItemGroup>
</Target>
</Project>
Here's a detailed post explaining it:
Using MsDeploy publish profile .pubxml to create an empty folder structure on IIS and skip deleting it with MsDeploySkipRules
Summarizing and simplifying Emil and Leniel answers in a concise one, if you just want to allow App_Data deploy for adds and updates, but prevents deletes, add this to your .pubxml.
<Project>
...
<PropertyGroup>
<UseMSDeployExe>true</UseMSDeployExe>
<ExcludeApp_Data>False</ExcludeApp_Data>
</PropertyGroup>
<Target Name="AddCustomSkipRules"
AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>App_Data\\.*</AbsolutePath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>App_Data</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
</Project>
<UseMSDeployExe>true</UseMSDeployExe> is really needed or it will fail complaining Unrecognized skip directive 'skipaction'.

Resources