MSBuild: How to build web deploy package for Web Deployment Projects (VS2010)? - visual-studio-2010

I migrated a Web Site project (with Web Deployment project) from VS2008 to VS2010. Now I can make "Build Deployment Package" for Web Deployment Project in VS2010 and it works great! But I can't find a way how to do the same via MSBuild.

I answer on my one question. So after a lot of googling and 2 days of investigation it finally works.
Brief how to:
I created Configuration = QA (based on Debug configuration) for Solution via Configuration Manager.
Important: I removed 'Platform' parameter for QA Configuration. I couldn't build package until I did it. (My dev computer is Win7-x64, and I'm not not sure would be this step necessary for x86. But my build server Win2008-x86 forks fine with this modification.) This is QA Configuration section from my .wdproj
<PropertyGroup Condition=" '$(Configuration)' == 'QA' ">
<DebugSymbols>True</DebugSymbols>
<OutputPath>QA\</OutputPath>
<EnableUpdateable>true</EnableUpdateable>
<UseMerge>true</UseMerge>
<SingleAssemblyName>
</SingleAssemblyName>
<UseWebConfigReplacement>false</UseWebConfigReplacement>
<DeleteAppDataFolder>true</DeleteAppDataFolder>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<ExcludeApp_Data>true</ExcludeApp_Data>
</PropertyGroup>
I build and package .wbproj file with the following command:
msbuild WebSite.Deploy.wdproj /t:Build;Package /p:Configuration=QA
For information: If you need you can use standard Web Publishing parameters (e.g. ExcludeApp_Data, DeployIisAppPath etc.) in the QA configuration section.

Try
MSBuild YourProject.csproj /T:Package
That should generate a deployment package. This page, How to: Use MSBuild to Create a Web Package might give a bit more information, but not much.

Related

Azue Devops multitarget build order

I have complex Xamarin solution with android, ios and nestandard core project (defined via Microsoft.NET.Sdk) and few other csprojs with some logic (some are defined via Microsoft.NET.Sdk as netstandard2.0. others defined via MSBuild.Sdk.Extras for multitargeting the netstandard2.0, xamarin.ios10, monoandroid10.0 and have some platform specific code)
Local build on my macos with latest libraries is ok (both netcore 3 and 5, latest xamarin. tried on Rider and VS for mac).
ADO build succeed on windows-2019 agent using msbuild (just regular CI with codechecks etc)
ADO build on macos-10.15 agent (different jobs for ios and android packaging, using XamarinIos/XamarinAndroid tasks) fails with kind of strange behaviour:
i see a lot of namespace errors in droid/ios projects for platform-specific libraries from my solution.
i've made some investigations and found out that msbuild runs platform specific builds of csprojs first, copies the outputs, then runs the netstandard build for the same csprojs and replace files in output with netstandard versions. which, obviously, didn't have any line of platform specific code.
so, the question is wtf? how am i suppose to fix this?
what i tried:
replace Xamarin tasks with msbuild calls
change Xamarin SDK version to 16_12_3 and 16_12_0 (current is 16_12_2)
change .net version to 5 (current is 3.1.x) both ways - via global.json and installing v5 using the UseDotNet#2 task
core project was converted to multitarget
remove everything from sln and add every project from the scratch
also i thought that msbuild, maybe, trying to make a nupkg from my libraries so i tried this in build props:
<PropertyGroup>
<IsPackable>false</IsPackable>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
</PropertyGroup>
also i have this
<PropertyGroup Label="Multiplatform" Condition=" '$(TargetsToBuild)' != 'All' ">
<TargetFrameworks Condition=" '$(TargetsToBuild)' == 'Android' ">monoandroid10.0</TargetFrameworks>
<TargetFrameworks Condition=" '$(TargetsToBuild)' == 'iOS' ">xamarin.ios10</TargetFrameworks>
</PropertyGroup>
and multitarget projects has this
<PropertyGroup Label="Multiplatform">
<TargetFrameworks>netstandard2.0;xamarin.ios10;monoandroid10.0</TargetFrameworks>
</PropertyGroup>
of course i've tried to remove the tags above and build without them. no luck :(
So the answer is:
you should add csproj references to other projects in right order :/ order is matters for msbild

How to use TeamCity to emulate VisualStudio Publish Web feature

Visual Studio (VS) offers a 'Publish Web' feature, from which you select a profile & it generates the build artfects - this works as expected, my Web.config is transformed from the profile (say web.Test.config).
If I build via teamcity using /p:Configuration="Test" , the build is good, but I dont see any transformation - Is my expectation Ok. I do have octoPack run set.
I do have other VS projects, were I use team city to build nuget packages, that are then deployed to various enviroment via Octopus. Where Octopus does the transformations. I think I'm confusing my expectation of teamcity i.e. its not an emulation of VS's Publish-Web. And I must use both steps teamcity + octopus to buid an output deliverable even if i dont use octopus to deploy to the environment.
To make it work, you must have your configuration in Publish Configuration File *.pubxml. Then, in TeamCity you should use this file as a build step. Here is an example, assuming you have Test configuration next to Debug and Release in Visual Studio:
Test.pubxml
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<AllowUntrustedCertificate>True</AllowUntrustedCertificate>
<Configuration>Test</Configuration>
<LastUsedBuildConfiguration>Test</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://your-website:8080/</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>server-name</MSDeployServiceURL>
<DeployIisAppPath>SITE_NAME_ON_IIS</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>False</EnableMSDeployBackup>
<UserName>UserNameWithPermission</UserName>
<_SavePWD>True</_SavePWD>
</PropertyGroup>
</Project>
Command line parameters:
/p:DeployOnBuild=true
/p:PublishProfile="%teamcity.build.workingDir%\PathToConfiguration\Test.pubxml"
/p:SolutionDir="%teamcity.build.workingDir%"
/p:Password=PASSWORD
Build file path should be your *.csproj file:
TeamCity Configuration

TFS 2017 Build Definition: Packaging Web API Project for deployment

I have a Visual Studio solution that contains four projects:
1 Desktop app;
1 Windows Service;
2 Web API projects.
These projects have been migrated from VS2010 -> 2013 -> 2017. I've removed/edited as much legacy stuff as I recognise.
The solution builds fine in 2017.
I wish to only build one of the Web API projects, generate a deployment package, and publish the package as an artifact. A release definition is going to use WinRM to deploy the package on a Windows Server 2012 system running IIS.
In my build definition I have a MSBuild task.
The parameters of this task are as follows:
Project is set to the path of my webAPI .csproj in TFS source control
Platform is set to "AnyCPU" - ("Any CPU" doesn't work.. its a known (old) issue)
Configuration is "Release"
MSBuild arguments are:
/p:DeployOnBuild=true /p:WebPublishMethod=Package
/p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.ArtifactStagingDirectory)\webapi.zip
Clean is set to true
The build completes successfully, however the webapi.zip package that is produced contains a massive folder structure:
C:\agent2_work\27\a\webapi.zip\Content\C_C\agent2_work\27\s\MyProduct.WebApi\obj\release\Package\PackageTmp
Questions:
Why is it packing this full path? (c:\agent2_work is my build agent's directory)
How do I change it?
It's the expected behavior, it's based on your Package Location. If you publish the project in VS, you will find the similar folder structure. See Create a Web Deployment Package in Visual Studio for details. And this thread for your reference.
However you can change the folder structure with publish profile used in MSBuild Arguments. Following below steps to do that:
1, Create a publish profile.
To create a web deploy package in VS you
will first create a publish profile for that. When you do this, a
.pubxml file will be created for you under
Properties\PublishProfiles. This is your publish profile file, its an MSBuild file. You can customize your publish process by editing
this file. We will modify this file in order to update these paths
in the package.
2, Edit the .pubxml file for the profile and add the following before
the closing </Project> tag. (Create the target AddReplaceRuleForAppPath, and inject that into the package process by adding it to PackageDependsOn property. Once this target is executed it will add a replace rule into the MSDeployReplaceRules item group.)
<PropertyGroup>
<PackagePath Condition=" '$(PackagePath)'=='' ">WebApi</PackagePath>
<EnableAddReplaceToUpdatePacakgePath Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='' ">true</EnableAddReplaceToUpdatePacakgePath>
<PackageDependsOn>
$(PackageDependsOn);
AddReplaceRuleForAppPath;
</PackageDependsOn>
</PropertyGroup>
<Target Name="AddReplaceRuleForAppPath" Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' ">
<PropertyGroup>
<_PkgPathFull>$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))</_PkgPathFull>
</PropertyGroup>
<!-- escape the text into a regex -->
<EscapeTextForRegularExpressions Text="$(_PkgPathFull)">
<Output TaskParameter="Result" PropertyName="_PkgPathRegex" />
</EscapeTextForRegularExpressions>
<!-- add the replace rule to update the path -->
<ItemGroup>
<MsDeployReplaceRules Include="replaceFullPath">
<Match>$(_PkgPathRegex)</Match>
<Replace>$(PackagePath)</Replace>
</MsDeployReplaceRules>
</ItemGroup>
</Target>
3, Save the Publish Profile file and check in the changes
4, Enter below MSBuild arguments: (In this example my publish profile name is 1011DP.pubxml)
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:PublishProfile=1011DP /p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.ArtifactStagingDirectory)
5, Run the build, then check the folder structure.
To make things a bit easier I just created a nuget package that performs these steps automatically for you. See https://www.nuget.org/packages/SharpSvn.ShortMSDeployWebContentPath
Just installing this in your web application project from Visual Studio will change the long path below 'Contents' with just the single word 'web'

Using MSBUILD when specified configuration is not provided

I have a solution with multiple projects. I am trying to use MSBUILD to automate the deployment. I have following configuration values for building
1. Debug
2. Release
3. Dev
For Some projects, I am using Release mode for DEV configuration. But while using DEV as configuration in MSBUILD command, it is throwing exception saying DEV configuration was not found.
Is there any way we can tell MSBUILD to use Release mode if DEV is not available for a project when DEV is used as configuration in MSBUILD?
Thanks
Ashwani
In your (presumably C#) project file, there is typically a line that looks like this:
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
For the projects that don't have a "Dev" configuration, you can get the behavior you want by adding another line, right before that one...
<Configuration Condition=" '$(Configuration)' == 'Dev' ">Release</Configuration>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
This way, when you build with "Dev" specified, these projects will build their Release configuration instead, which mimics the behavior of the solution's configuration manager (which I tend to think of as an abomination of a feature) directly in the project file itself, which is the right place to do it.
Another approach is to use the AdditionalProperties metadata on the item array you would be passing to the MSBuild task to get your projects built. You can specify--for the projects of interest--the following...
<SolutionItem Include="./PathTo/SomeProject.csproj">
<AdditionalProperties Condition="'$(Configuration)' == 'Dev'"
>Configuration=Release</AdditionalProperties>
</SolutionItem>
(Excerpted from the book "MSBuild Trickery" trick #80)
I don't think it can be done with a command argument to MSBuild.
What you could do is use the Configuration Manager for Visual Studio and for the solution configuration 'Dev' point the projects which don't have the 'Dev' configuration to Release.
Then you do a solution build for Dev configuration and some projects will build in release.

TeamCity - problem with Publish on ASP.net site

I am trying to configure TeamCity 5.0 to run "Publish" target on one of my projects.
When I load the solution in VS 2008 and click publish on the project the website is being build nicely - files on server appearing by themselves etc. Yet when I run the sln file via TeamCity Sln2008 runner the TeamCity returns:
[Project "Portal.csproj" (Publish target(s)):] Skipping unpublishable project.
Has anyone had the same problem?
Filip
You could create your own simple build file. For example:
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<PackageFolder>C:\Builds\AppServer\Actual</PackageFolder>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="BeforeBuild">
<MSBuild Projects="TeamWork-AppServer.sln"
Targets="Rebuild"
Properties="Configuration=Debug;OutDir=$(PackageFolder)\;"></MSBuild>
</Target>
</Project>
Or you can use VS 2008 Web Deployment Project. Here is a great turtorial.
If it is a WebProject you can use the Microsoft.WebApplication.targets. Unless you have installed the windows SDK on your build agent you will need to copy the targets file into your source control and reference it from your web project by adding:
<Import Project="{path to your tools}\Microsoft.WebApplication.targets" />
You can find the targets file here (depending on your os):
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications
Now you just need to update your msbuild task to reference the right targets:
<MSBuild Projects="{path to your web project file}"
Targets="Build;ResolveReferences;_CopyWebApplication"
Properties="Configuration=Release;Architecture=Any;WebProjectOutputDir={your web root};OutDir={your web root}\bin\" />
Here is how I modified the .csproj file for an ASP.NET MVC project to deploy via TeamCity 5.1.2. In the .csproj file, replace the AfterBuild target with this XML (If there are already commands in your existing AfterBuild, you will have to merge them into these targets):
<PropertyGroup>
<DeployTarget>0</DeployTarget>
<PublishTarget>0</PublishTarget>
<PublishFolder>..\Deployment\YourWebsiteName</PublishFolder>
</PropertyGroup>
<Target Name="PublishProperties">
<CreateProperty Value="$(PublishFolder)">
<Output TaskParameter="Value" PropertyName="WebProjectOutputDir"/>
</CreateProperty>
<CreateProperty Value="$(PublishFolder)\bin\">
<Output TaskParameter="Value" PropertyName="OutDir"/>
</CreateProperty>
</Target>
<Target Name="WebPublish" DependsOnTargets="BeforeBuild;PublishProperties">
<RemoveDir Directories="$(PublishFolder)"
ContinueOnError="true" />
<CallTarget Targets="ResolveReferences;_CopyWebApplication" />
</Target>
<Target Name="Deploy" DependsOnTargets="WebPublish">
<CreateProperty Value="Path\To\Your\Server" Condition="$(DeployFolder) == ''">
<Output TaskParameter="Value" PropertyName="DeployFolder"/>
</CreateProperty>
<RemoveDir Directories="$(DeployFolder)" Condition="$(CleanDeploy) == 1" />
<ItemGroup>
<DeploymentFiles Include="$(PublishFolder)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(DeploymentFiles)"
DestinationFolder="$(DeployFolder)\%(RecursiveDir)" />
</Target>
<Target Name="AfterBuild">
<CallTarget Targets="WebPublish" Condition="$(PublishTarget) == 1" />
<CallTarget Targets="Deploy" Condition="$(DeployTarget) == 1" />
</Target>
This script uses the $(PublishTarget) and $(DeployTarget) properties to trigger additional steps after your project is built. The PropertyGroup at the beginning sets the default values to 0, so the extra targets are not run. You can override the default in TeamCity by going to the Properties and Environment Variables page of your build configuration and adding System Properties names "PublishTarget" and "DeployTarget" and setting their value to 1.
The Publish target contains most of the magic. This makes a call to the Visual Studio _CopyWebApplication target to output the website to the PublishFolder. By default the publish folder is "..\Deployment\YourWebsiteName" relative to the project file, but this can also be overridden with a System Property. The Deploy target takes the files output by the Publish target and copies them to the DeployFolder. DeployFolder can be set with a System Property in TeamCity or you can replace the "Path\To\Your\Server" path in the Deploy target.
You could also skip the extra Deploy step by simply setting the PublishFolder to whatever your deployment destination is. This script depends on the "Microsoft.WebApplication.Build.Tasks.Dll" and "Microsoft.WebApplication.targets" files installed by Visual Studio, but you can simply copy the files from your developer workstation to the build server. The default location is "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications".
I have this same problem, here's what I've tried:
I have a solution file in Visual Studio 2010, committed to a Mercurial repository.
I have setup an FTP server for the root directory of the site to publish to, and publishing from within Visual Studio 2010 locally works nicely, it connects and uploads everything as expected, and the website works.
Now, I wanted to automate this on every push to the central Mercurial repository, and since I'm using TeamCity, I discovered that the field to specify the Target of the build, usually "Rebuild" can also take "Publish", so I specified "Rebuild;Publish", as per the documentation and help.
I have verified that after publishing in Visual Studio, and committing new files, a file named ProjectName.Publish.xml is accompanying my ProjectName.csproj file, and this file is pulled down into the server directory when TeamCity builds.
Yet, no publishing is done, and when I check the build log, it says:
[19:01:02]: [Project "Test.sln" (Rebuild;Publish target(s)):] Project "Test.UI.Web.csproj" (Publish target(s)):
[19:01:02]: [Project "Test.UI.Web.csproj" (Publish target(s)):] Skipping unpublishable project.
Exactly as the question here says.
Note that this is a development site, publishing just so that we can let more people test changes, so don't get into a discussion of whether this is actually a good idea or not.
Note: I do not care in which way the files are published, I just need the single TeamCity build-step to actually do it, so if anyone got a MSBuild-like solution that just sidesteps TeamCity, then I would be satisfied
Have you tried to execute Visual Studio directly, rather than relying on MSBuild to publish the project directly. MSBuild can't execute certain kinds of projects. I had a similar problem with getting MSI's built from within Team City.
I'm taking a guess at the exact commandline settings to this, since I don't know your exact setup.
<PropertyGroup>
<buildconfiguration>Release</buildconfiguration>
<DevEnv>C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com</DevEnv>
</PropertyGroup>
<Exec Command="%22$(DevEnv)%22 /build $(buildconfiguration) $(teamcity_build_checkoutDir)\Test.sln /project Test.UI.Web.csproj"/>
If you're using the Team City solution runner as your build runner, you'll have to switch to MSBuild.
If you want to stay with the Team City runner, you could always try adding a project to your solution that will be the last one built, (or do it on the project that currently gets built last), and do the spawning trick as a post-build command line on the project.
Can TeamCity publish a Web project using the sln2008 build runner
Can TeamCity publish a Web project using the sln2008 build runner?
What type of project are you trying to publish?
http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/7ec0d942-6354-41c3-9c97-7e7d1f461c29
Taken from above link:
What I discovered is that "Shared-addins" are not publishable
and are distinct and different from document and application level
VSTO addins, which are deployable.
When I rebuilt my application as an application level
VSTO addin, the publish option was available.
http://www.automise.com/Default.aspx?tabid=53&aft=9813
Taken from above link:
Assuming you're using Visual Studio 2008, we're unable to execute the web site
publish feature from FinalBuilder as it's partially implemented by the VS IDE.
You'll need to use to the MSBuild action to compile the application and then
use one of the other actions (FTP, File Copy, etc) in FinalBuilder to perform
the deployment. Visual Studio 2010 has fixed this problem by performing the
entire publish using MSBuild, see this post for more info:
http://www.finalbuilder.com/forums....&afv=topic
Two threads that might help
http://devnet.jetbrains.net/thread/280420;jsessionid=5E8948AE810FFFF251996D85E7EB3FE3
Visual Studio. Publish project from command line
For anyone using Web Application Projects in VS2010, I managed to get TeamCity to package the deliverables and then Web Deploy the package after successfully building the solution.
With a little tweaking, this had the same effect as hitting the 'Publish' button in VS.
My solution has a handful of projects, 1 of which is an ASP.NET MVC Web Application project. I build the solution, package the web app project, and msdeploy the package in 3 steps. I haven't figured out a (better|shorter|simpler|more elegant) way to do this.
I don't have VS installed on my TeamCity server, so I needed to grab both C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web and C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web Applications and put them both in the same spot on the TeamCity server (the second depends on the first). If you're working w/x64 machines, I'd grab them from both Program Files (x86) and Program Files. You also need to have Web Deploy installed on your machine and (I believe) IIS Management Service (i.e., something listening on https://yourservername:8172/MsDeploy.axd)
There are 3 build steps:
Visusal Studio (sln), Target=Rebuild, Configuration=Debug
MSBuild WebProject.csproj, Targets=Package Commandline=/p:PackageLocation=%teamcity.build.checkoutDir%\Debug.zip /p:Configuration=Debug
Commandline, Executable=%teamcity.build.checkoutDir%\Debug.deploy.cmd, Parameters=
/Y "-setParam:'IIS Web Application Name'='Default Web Site/PreCreatedAppInIis'"
In that last step, 'IIS Web Application Name' is an actual parameter name, don't change it. It's value can either be something like 'Default Web Site' or whatever you named your website in IIS and/or it can be an IIS application path below it. If the application doesn't exist, you may run into errors about the app pool not being configured correctly to host the application. Rather than investigate it, I just created an application in the appropriate app pool. In my case, I'm targeting ASP.NET 4.0 x64 where the default app pool is ASP.NET 2.0 x64.

Resources