- I have a web project that I want to publish to multiple IIS sites
- Publish in VS should publish to devs local IIS server (MSDeploy)
- Publish from CI/CLI should publish to remote env (MSDeploy)
- CI/CLI and VS publish should be the same
- Building the solution takes ~3 min and should only be performed once
- Config files need to be transformed based on the dest env
How can I accomplish this?
There are several different ways that you can solve this issue, each with its own pros/cons. For example, one method would
be to create an MSDeploy package, and then use that to publish to multiple locations. In the past I've created
package-web which can help with that. But package-web
wasn't really designed with this
scenario in mind, but more for deployments outside of VS.
I spent some time thinking about this and here is the proposed solution for this problem that I've come up with.
1: Create a script that knows how to publish a folder to an IIS server, with the following characteristics.
- Parameter for the folder to publish
- Parameter for env name. Using the env name the script will transform
web.original.config
usingweb.ENV.config
and placeweb.config
in the publish folder. - Parameters needed for publish settings (i.e. MSDeploy settings), or it can be found using conventions and the env name parameter.
web.original.config
should be excluded from publish using MSDeploy parameters.- Parameter for the source folder. This is used for cases outside of VS, and the script should be able to build and publish using a publish profile (more on that below). When this parameter is passed the
folder to publish
parameter should be ignored.
Note: I personally would create a PowerShell script here
- Publish to a folder
- After publish is finished
web.config
is renamed toweb.original.config
. Create a target withAfterTargets="Publish"
to do this work. - Calls the script created in step 1 to publish to local IIS for the 3 target destinations
Then in VS when a developer publishes the project, it will first publish the files to a folder and run the build config transform (i.e. web.release.config
) and then the script is invoked three times to do the local publish.
For your CI/CLI publish you just call the script and pass in different parameters based on the env/dest, as well as the source folder. It should call msbuild.exe
to build and publish the project using the folder profile. To do that invoke MSBuild with /p:DeployOnBuild=true;publishprofile="NAME-OF-THIS-PROFILE"
. Note if you're building a .sln file see my blog post at http://sedodream.com/2013/03/06/HowToPublishOneWebProjectFromASolution.aspx.
As for implementing the script, if you use PowerShell, I'd recommend looking at the publish-module. This is module developed by me and the aspnet team, when I used to work on the team, for ASP.NET 5. It's no longer being used in VS or maintained, but I believe it's high quality and you should be able to fix any issues that you run into. I doubt you'll run into many though.
If you do look at that there is good docs using Get-Help
. You can also view the help by looking at the .psm1 file on github, for example
https://github.com/aspnet/vsweb-publish/blob/master/publish-module.psm1#L264.
With that being said, you don't need to use that module. You can just call msdeploy.exe
directly. If you do use PowerShell to do this, and you
don't use publish-module
then I'd recommend copying the Execute-Command
function in that module to your PowerShell file and then use
that to invoke msdeploy.exe
.