Please don't be too harsh, because I do not grasp this entirely correctly still, but msbuild/msdeploy is giving me some headaches lately.
Hopefully someone can provide a textual aspirin of some kind? So here is what I want to do:
I have a web application project, that has multiple configurations, thus multiple web.config-transforms.
I would like to deploy this project from command line.
I would rather not want to modify its project file. (I want to be able to do this for several web applications so as least as editing as possible is much appreciated)
I would like to be able to build it only once and then deploy the different configurations from it.
So far I deployed from command line using something like this:
msbuild D:\pathToFile\DeployVariation01.csproj
/p:Configuration=Debug;
Platform=AnyCpu;
DeployOnBuild=true;
DeployTarget=MSDeployPublish;
MSDeployServiceURL="localhost";
DeployIisAppPath="DeployApp/DeployThis01";
MSDeployPublishMethod=InProc
And this performs just what I want, except it only deploys the "Debug"-Configuration.
How can I, with minimal adjustments, make it deploy my other configurations as well?
I was thinking maybe I could build a package that includes all my configurations and then deploy from that and decide "while deploying" which configuration to deploy?
Unfortuanetly I am pretty much stuck here, the approaches I have read about all seem to require some modifications to project files, is there a way around that?
UPDATE:
I am still not really where I want to be here :).
But I looked into this PackageWeb-approach (also interesting video about that here) and it seems pretty nice; I can now build a package that includes all my transforms and then deploy from that as often as I want into multiple configurations.
One thing that I dislike about this is that I have to store my password in plain text into the generated parameters file for the powershell script, does someone know a way around this, I really would rather have that being an encrypted password.
Also other approaches to solve my original problem are still appreciated.
I am working on the same problem and am taking two paths using Microsoft Web Deploy or MSDeploy which is now in version 3.0.
I first compile the project using MSBUILD using the Package target passing in system.configuration, system.packagelocation. The Package Target generates a set of package files including a {PackageName}.SetParameters.xml file. The SetParameters.xml file by default allows on-publish changes to ConnectionStrings without recompiling when using msdeploy.exe to publish the file. The publish transformation process can also be customized by adding a parameters.xml file to the process defining additional parameterized web.config settings which can be changed at deploy time.
After the initial build I use the {PackageName}.deploy.cmd file generated by MSBUILD during the Package process to deploy the package to the target website. The Package process essentially duplicates the process you are currently doing from MSBUILD in that I can publish one Build-Configuration web.config transform from one compile. The process provides a consistent deployment process that can target remote servers from a central CI environment, which is great from a purely deployment process. The PackageBuild/Deploy process is parameterized within TeamCity, requiring changes to only a few parameters to setup a new deployment.
Like you, I cannot, however, compile a single version of code and deploy to multiple servers using the process as it exists today - which is my current focus. I want to parameterize the transform in a Continuous Deployment, build-once-deploy-many pattern to Dev, QA, User Testing, Staging, and Production.
I anticipate using one of two methods:
Create a Parameters.xml file for each project defining the variable deployment parameters along with a custom {ServerName}.SetParameters.xml for each target deployment, both to be used in conjunction with msdeploy.exe.
a. I am not sure defining a parameters.xml is a flexible enough process for my needs as the current project inserts and removes a variable number of web.config settings. Implementing a parameters file incorporating all of the variables could be too complex for my taste. I would also end up creating all of the target transformations, instead of the current developers initiated process. Not ideal.
I am following up on very recent updates to VS2012 Web Tools 2012.2 which allow tying a web.config transform to the publish profiles (profile.pubxml) now stored under SolutionName/Properties/PublishProfiles in VS2012.
VS2012 release 2012.2 adds the capability to create a second transform tied to the publish profile. The resulting transform process first runs the build configuration transformation, followed by the publish transformation, i.e. Release Transform followed by TargetServer Transform. Sayed Hashimi has a great YouTube video demonstrating the entire process using MSBUILD.
What is not entirely clear is whether the second transform is supported separately from the build using MSDeploy in a Continuous Deployment, build-once-deploy-many Pattern, or if the publish transformation is only supported during a separate Package/Build for each target transformation.
Option 1 will definitely work for some environments and was my first plan for tackling a Continuous Deployment process. I would much rather use Web Transforms to accomplish the process if possible.
An outside third possibility is using one of several CodePlex commandline projects that are capable of transforming web.config using the XDT transform engine. Unfortunately, using these tools would mean splicing the results into the Build/Package MSBUILD process in order to get the resulting web.config transformation into the deployment package - something I've not yet been successful in accomplishing. Sayed Hashimi also has a PackageWeb project from 2012 that might work as well. I am hoping his more recent work replaces the need for the extra steps involved in the packageweb solution.
Let me know if you decide on a solution - as I am definitely interested.
Related
I have a solution that is using an hybrid .csproj and project.json combination (for nuget management purposes). So basically the "project.json" file is working as a "packages.config" file with a floating version capability.
This solution is using a custom RuleSet that is being distributed via Package, and is imported automatically. On the dev machine, works without a problem.
At the build machine (that is, inside the machine itself, working as an user) the solution also compiles without a problem.
However, when a vNext build (is this the name for the new build system?) is queued, it ignores completely the custom ruleset and just uses the StyleCop one (that is also included), which gives a bunch of warnings. Said warnings should not appear as the Custom RuleSet basically suppresses those warnings (ie: Warning SA1404: Code analysis suppression must have justification,
Warning SA1124: Do not use regions, etc)
As far as I have checked, there is no setting to specify the ruleset, and this works with XAML Builds. What is different in this new build system that is causing this? Is there a way to force/specify the Code Analysis Rule Set from the definition?
Thanks in advance for any help or advice on the matter.
Update/Edit
After debugging back and forth with the wonderful help of jessehouwing I must include the following detail on my initial report (that I ignored as I did not know that it was influential):
I am using SonarQube Analysis on my build definition.
I initially did not mention it as I did not know that it replaces the Code Analysis at Build Time (and not only when it "analyzes", as I thought).
If you are using the SonarQube tasks
The SonarQube tasks generate a new Code Analysis Ruleset file on the fly and will overwrite the one configured for the projects. These rulesets will be used regardless of what you've previously specified.
There is a trick to the naming of the rulesets through which you can include your own overrides.
More information on the structure can be found in the blog post from the SonarQube/Visual Studio team. Basically when you Bind your solution to SonarQube it will generate 2 ruleset files. One which will be overwritten during build, the other containing your customizations.
There is a toolkit/SDK to generate a SonarQube plugin for custom analyzers which allow you to import your rules into SonarQube, so it will know what rules to activate for your project(s).
If you're not using SonarQube
Yes you can specify the ruleset you want to use and force Code Analysis to run. It requires a couple of MsBuild arguments:
/p:RunCodeAnalysis=true /p:CodeAnalysisRuleset="PathToRuleset"
Or you can use my MsBuild helper extension to configure these settings with the help of a UI template:
I am trying to set different artifact paths configuration wise. e.g
In general settings of teamcity I am specifying following artifact paths:
testing\obj\Deploy-Dev\package
testing\obj\Deploy-Test\package
testing\obj\Deploy-Live\package
But when I am publishing a site using the following:
/M /P:Configuration=%env.Configuration% /P:DeployOnBuild=True/P:DeployTarget=MSDeployPublish /P:MsDeployServiceUrl=%env.TargetServer%/MsDeployAgentService /P:DeployiisAppPath=%env.IISPath% /P:MSDeployPublishMethod=RemoteAgent /P:CreatePackageOnPublish=True /P:Username=%env.username% /P:Password=%env.password%
In this step I am using only 1 configuration. I am assuming that by specifying these artifact paths. it will also transform the web configs according to specified configuration. But it is only transforming the one specified while actually packaging.
Any idea how to have web configs transformed in all packages as well.
I am not sure if I fully understand your question but here is what I think that you are asking. "How can I create a web package which has all the web.config transforms required so that I can publish the same package to multiple different environments?"
Unfortunately the way that packaging works is that the web.config is transformed using the web.config transform of the build configuration which is being built. Then the transformed web.config file makes it into the package. The transform files are not packaged.
I do realize that it's important to create a single package and publish that to different locations. We were not able to build the features into the box but I have created a NuGet package, PackageWeb, which can help in this case. I have a 5 minute video posted at http://sedodream.com/2012/03/14/PackageWebUpdatedAndVideoBelow.aspx which you can take a look at. I am fairly certain that it will help in your scenario. FYI the code for package-web is open source at https://github.com/sayedihashimi/package-web. We do have some known issues. If you do end up using this please do let me know.
Try setting a environment variable for your teamcity artifact path.
testing\obj\%env.Configuration%\package
Troy Hunter -You're deploying it wrong! TeamCity, Subversion & Web Deploy part 5: Web Deploy with TeamCity
Artifact paths do not affect build\packaging process anyhow. They just provide ability to keep some files\folders available after build for further access.
If you want to produce 3 different packages, you will need to specify 3 corresponding build steps in your configuration and get rid of '%env.Configuration%'.
Our solution has got a ton of projects in it, and our MSBuild file is becoming a gigantic, unstable morass of angle brackets that has gotten so large that I've begun to be scared to touch it. However, I noticed that most of our projects fall into two groups.
There are web projects, which have a .csproj extension and are built and deployed using web deployment projects to dump them into a directory. There is also a configuration transform process. Basically, to deploy a web project, one only needs the project name, the output directory, and the config transforms.
Similarly, we have an ever-increasing number of service apps that will live under TopShelf. These are basically dlls that are built from .csproj files. Like the above websites, they undergo a config transform, but they are copied to the output directory instead of going through the web deployment steps.
It occurred to me that it would be really slick if I could simply provide the MSBuild project with a couple of text files (one for the webs and the other for the services) that MSBuild could then use to dynamically compile all the various projects. I was thinking that if I could just feed it a comma-delimited list of projects, output locations, and config replacement files that there might be a way to get msbuild to read them in, iterate over them, and dump out the projects where they are supposed to go.
However, my MSBuild-fu is weak. How do I even get started on this?
You can start here, this is part 2.
For config files I'm using XmlPreprocess tool for config files manipulation. It is using one mapping file for multiple environments. You can edit mapping file by Excel. It is very easy to use.
At my current client, we are using CruiseControl.Net for continuous integration. We are building website projects using MSBuild.
The issue that I have run up against is the following: We want to move all code and associated DLLs with every release. However, we also have (sometimes) hundreds of megs of files and images that are unchanged. In the CC.Net world, I will probably split these in to two different builds, one for a site and the other for static content.
What I would like to know is if anyone knows of an MSBuild or CCNet plugin that will allow me to do a binary diff on my static content? I'd like to be able to know if an image has chnaged or been added and then package only the changed/added content up and push them to a QA environment.
I did that with svn logs and MsBuild tasks.
Every time I Deploy the website, I save somewhere the revision number (basically in a flat file).
Then at the next Build-Deploy, I will do a svn log to see the diff between the latest release and now. Then my MsBuild Task takes the svn log xml output, parses it and outputs in another file the interesting static files added/modified/deleted.
Then the usual tasks come in and process only the modified files instead of every file.
That was a huge piece of work (above all with internal logic : our "static" contents are dynamically generated for each environment, each partner and each theme) but it was worth it.
Either way, you can try using a ChecksumCopy, but I don't know if it's less expensive...
Ok, so I've got a somewhat complicated problem with my build environment that I'm trying to deal with.
I have a solution file that contains multiple C# projects which is built by a NAnt script calling MSBuild - passing MSBuild the name of the solution file and a path to copy the binaries to. This is because I want my automated build environment (CruiseControl.Net) to create a folder named after the revision of each build - this way I can easily go back to previous binaries for any reason.
So idealy I have a folder layout like this
c:\build\nightly\rev1
c:\build\nightly\rev2
c:\build\nightly\rev3
...
c:\build\nightly\rev10
etc.
The problem that's arisen is I recently added the latest version of the Unity IoC container to my project, checking it directly out of MS's online SVN repository. What's happening is I have a Silverlight 3 project that references the Silverlight version of Unity but I also have other projects (namely my Unit testing project) that reference the standard (non-Silverlight) version of Unity.
So what happens is since MSBuild is dumping everything into one single folder the Silverlight version of the Unity assembly is overwriting the non-Silverlight version because they have the exact same assembly file name.
Then when CruistControl runs my unit tests they fail because they don't have the proper dependencies available anymore (they try to load the Silverlight specific Unity assembly which obviously doesn't work).
So what I want to do is:
keep my desired output directory
structure (folder\revision)
I don't want to have to manually edit
every single proj file I have as this
is error prone when adding new
projects to the solution
Idealy I would like MSBuild to put everything into a folder structure similar to this:
nightly\revision1\project1
nightly\revision1\project2
nightly\revision1\project3
...
nightly\revision2\project1
nightly\revision2\project2
nightly\revision2\project3
etc
I can't modify the Unity project to give it a different file name because it comes from another SVN repository I cannot commit changes to. I found a similar question posted here and the suggested solution was to use a "master" MSBuild file that used a custom task to extract all the project file names out of the solution then loop over each one building them. I tried that but it doesn't build them in the order of their dependencies, so it fails for my project.
Help?
Firstly I would always have the build server delete the old working copy and check out a fresh copy to avoid any problems with stale artifacts from the previous build.
Next I would have nant or msbuild build the solutions as before with the artifacts from each build going to their local working output folders.
After that I'd move the artifacts from their working paths to their output paths, this shouldn't require digging through the project files since you can just tell msbuild/nant to copy working\project1\bin\release\**\*.* to artifacts\project1\.
The script that does this should ideally be stored along with the source with the main file, e.g. build.nant or build.proj in top level of the trunk.
For third party libraries I would simple include the DLLs directory in your repository. Nothing worse than writing some code and having a third party dependency break your build because of changes on their end.
Simply document the versions of the libraries you are using, and if you must update them, you'll have a better sense of what breaks the build before you even check it in.
Also, doesn't CC.Net automatically handle the providing of releases based on revision? I'm using TeamCity and it keeps a copy of the artifacts of every build.
I highly recommend reading JP Boodhoo's Automating Builds with NAnt blog series. That's been my starting point and have made lots of changes for my own taste. I also highly recommend checking out the builds of many open sources projects for examples. I've learned a lot from the builds of the Castle/Nhibernate/Rhino-Tools stack.