ASP.NET 4 web.config transformation MSBUILD - web-config

I want to use the newly introduced web.config transformation options in VS2010. But I'm not using the Deploy option of VS2010, i'm using Web Deployment Projects with MSBUILD tasks.
Can I apply the transformation with an MSBUILD task?

Related

Deploy Azure App Service and Webjobs using Azure Devops in .Net Framework

I have created Azure AppService and added Webjobs console application in a single solution. I'm trying to build the solution through Azure DevOps build pipeline and Deploy the package through Octopus. When I build the solution there files required for Appservice such as Web.config and Global.asax are missing from Artifacts folder. so When deploying that package is breaking the AppService.
I tried to change the MSBuild arguments while building the solution. the current MSBuild arguments are as follows:
/p:DeployOnBuild=true/p:WebPublishMethod=Package
/p:Configuration=$(BuildConfiguration) /p:OutputPath=.\bin\ /p:PackageTempRootDir="$(build.artifactstagingdirectory)\temp" /p:packageAsSingleFile=true /p:TargetProfile=Cloud
I suspect, while building the Webjobs it is removing the App Service files, so the generated package does not contain all the required files. My Build pipeline looks like below.
My Artifacts folder Creates a Nupkg file which has following files.
If the App Service is deployed alone, It is working fine,Please suggest me the way I can deploy both from single solution and one Build definition on Azure devOps.

How to include my config transformation files in the web deploy zip?

Im setting up a new build and deploy pipeline in Azure Devops. It is an older Web application with some transformation files for the web.config. In the old days we would build the same code x times depending on how many environments. This this is no longer necesary as I read from here https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/transforms-variable-substitution?view=vsts#xmltransform
it looks like the deploy pipeline can pick up the changes from my transform file.
But the problem is that my other transform files does not get included in the package so I get these warning message:
[warning]Unable to apply transformation for the given package. Verify the following.
[warning]1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the <DependentUpon> tag for each config in the csproj file and rebuild.
[warning]2. Ensure that the config file and transformation files are present in the same folder inside the package.
And yes when i download the artifact the Web.[stage].config files are not there as suggested.
Is there some setting somewhere that let me include these files? Or stop them from being transformed?
For Web applications
MSBuild knows how to transform the web.config files based on the following settings/properties/parameters (in order)
Build Configuration dotnet publish --configuration Release
Publish profile dotnet publish --configuration Release /p:PublishProfile=FolderProfile
Environment dotnet publish --configuration Release /p:EnvironmentName=Production
Custom file transform dotnet publish --configuration Release /p:CustomTransformFileName=custom.transform
I think it's typical for developers to make this happen based on build configuration only, and I believe MSBuild (and dotnet) know how to do this based on the <DependentUpon>Web.config</DependentUpon> element in the Web.[configuration].config item in the project or build script file.
Azure DevOps Release Pipelines is a little different.
The pipeline wants to transform your web.config after the project has been built/published and doesn't know how to do that if MSBuild (or dotnet) has already made an attempt at it. Thus:
[warning]Unable to apply transformation for the given package. Verify the following.
[warning]1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild.
[warning]2. Ensure that the config file and transformation files are present in the same folder inside the package.
The warning text states:
Remove the <DependentUpon> tag for each config in the csproj
Thus: you need to remove the tag from the csproj to prevent MSBuild from transforming the files
Or: you need to use the /p:TransformWebConfigEnabled=False argument to MSBuild. (note: I believe it is correct that this can be used w/o removing the dependent upon tag, but I could be wrong)
Make sure the transform source and target files are in the same folder inside the package.
There may be several ways to do this. I've chosen to mark the transform source config files as content to force MSBuild to include them in the published package.
Now you need to organize your release pipeline in accordance with the File Transforms and Value Substitutions documentation.
[section]Starting: IIS Web App Deploy
====================================
Task : IIS Web App Deploy
Description : Deploy a website or web application using Web Deploy
Version : 0.0.51
Author : Microsoft Corporation
Help : More information
====================================
...[command]C:...\ctt\ctt.exe s:C:...\Web.config t:C:...\Web.Release.config d:C:...\Web.config pw i
[command]C:...\ctt\ctt.exe s:C:...\Web.config t:C:...\Web.Development.config d:C:...\Web.config pw i
XML Transformations applied successfully
...
For Non-Web Applications Needing .config Transformation
Getting your .config files to the release pipeline can happen several ways. Here are two.
Your release should have "access" to the repository as a part of the artifact, which will ensure that the deploy agent downloads the source (not desirable IMHO).
You will need to include the web.[stage].config files as part of your build artifact with a copy task, or a minimatch that picks them up.
Once you have the .config files available to the release pipeline
You can use the File Transform Task or XDT Transform Task to perform the transformation operations.
Option 2 is the route I've gone.
Here is an image of what that task looks like for me.
That task puts the config in the artifact from the build that I can then use in the release pipeline without rebuilding xx times.
Cleanup
If you're in a position where you care to not have the transform files persisting on the agent after the release is complete, then you'll need to add that to your pipeline.

parameterize DB connection during Build & deployment in Visual Studio Online VSO with .net project

I have a .Net 4.5 project (it will soon be upgraded to 4.6) that talks to a database. Right now I have different databases (dev test production) parameterized in my web.config file that looks like this
<add name="DevConnection" connectionString="blah...." />
<add name="TestConnection" connectionString="blah ... test" />
<add name="ProductionConnection" connectionString="blah... production" />
The way I switch this before I deploy Azure (PaaS or IaaS) is I change the following
public DBContext(): base("DevConnection") // this one is our azure Dev DB
{
}
in my DbContext file.
Is there a way I could parameterize that DevConnection on the right so when I queue up a build in Visual Studio Online aka VSTS or Visual Studio Team Services so it can switch the database to match the environment I am deploying to? Any insight on preferred ways to do this would be appreciated.
You can use Web.Config Transformation, refer to following links for detail:
http://blogs.msdn.com/b/webdev/archive/2009/05/04/web-deployment-web-config-transformation.aspx
Assuming you're using the new web based build system, you can build the .NET project to a WebDeploy package using the Visual Studio Build step and with a second Azure Web App Deployment step deploy the WebDeploy to Azure. Instead of having different connection strings you'll pass different parameters to the WebDeploy deployment step to set the connection string in the web.config accordingly.
You can also use the new release management, which is currently in preview, to deploy the web deploy to different environments.
You can create a single build and then use Release Management to deploy to different environments.
You can use the Tokenizer task to change the DB config string depending upon the environment you are deploying to. The task is not there in VSO by default and the instructions to upload the same are in the below link.
tokenization VSTS task (github repo)

Update Azure CSPKG with a transformed web.config post-publish

My build:
Build with msbuild (/t: build)
Publish with msbuild (/t: publish)
Package with nuget
Deploy with octopus
produces an artifact (nuget package) that contains the following files:
Azure.ccproj.cspkg
ServiceConfiguration.Production.csfg
Web.config
(which will be transformed during deployment via Octopus)
The cspkg is a valid, deployable package. The problem is that it contains a web.config that is pre-transform because the transform occurs at deployment time. See the Octopus documentation for transforms and variable substitution for reference.
How do I overwrite the web.config inside the cspkg with the transformed web.config that resides in the deployment package?
I have powershell and the full .net framework at my disposal.
Alternatively, if it makes more sense to unpack the cspkg, overwrite the file and then re-package, I consider that acceptable. I am not sure how to do that either.
I know that Save-AzureServiceProjectPackage exists but I cannot get it to run and the documentation is lacking.
I have an Octopus project with 2 steps: first for Dev hosted in IIS, second for Prod hosted in Azure. TeamCity procuded 2 nuget packages: one by OctoPack for Dev, another by NuGet Pack for Prod with cspkg.
I have this target in my Azure.ccproj:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="Transform" BeforeTargets="BeforeBuild" Condition="'$(TEAMCITY_VERSION)' != ''">
<PropertyGroup>
<SourceTransformFile>..\Api\Web.config</SourceTransformFile>
<TransformFile>..\Api\Web.Prod.config</TransformFile>
<DestinationTransformFile>..\Api\Web.config</DestinationTransformFile>
</PropertyGroup>
<TransformXml
Source="$(SourceTransformFile)"
Transform="$(TransformFile)"
Destination="$(DestinationTransformFile)" />
</Target>
The condition allows to run in only on the build server and not locally.
I have solved this by sending the solution as it is to Octopus Deploy which allows me to run .config transformations in Octopus. After running the transformations I create the .cspkg package with custom powershell script.
I have written a thorough post of the Octopus deploying part. You can find it here: http://henrihietala.github.io/
I have figured out how to do what I need based upon the information contained in Brad Webber's post in the Octopus Support forum.
I have posted a public git repo containing a simple sample solution and documentation here.

Force rules for build and deployment

Our web project is source-controlled with SVN. It contains MSBuild file to build local, test and production builds. We also use CruiseControl.NET to deploy production and test versions to servers manually (not after every commit).
The question is how to check that if production deployment is being done using CC.NET web project is built using production build (not test or other)? How to force specific steps to be executed when building and deploying to production (like compress JS and CSS, compile with debug="false", etc...)? Now it is possible for every developer make changes in MSBuild file (so he/she can forget to compress JS on production build, etc.).
I used CruiseControl with NAnt extensively, but not MSBuild. Do you have different MSBuild files for each build type (i.e. local/test/prod)? Could you have a single one that can be parameterized such that your CCNet integrators can explicitly call the appropriate options for the target environment? That's how I have my continuous integration versus release candidate builds configured in CCNet. A single master NAnt build script and a different CC integrator for each target env with the necessary build parameters (be them targets or property values). I imagine you could do something quite similar with MSBuild vars/targets.