.NET 7, VS 2022 . Is it possible to define multiple deploy profiles each with different post build commands? - deployment

So for my work I handle a .NET 7 web application that changes in theme and behavior depending on what appsettings.json file group is present in app main folder.
These alterations changes do NOT depend on environment.
For now I just deploy all the files to the server and manually overwrite the appsettings.json group from the folder with the intended configuration.
I'm just wondering if it's possible to automate this process creating as many different deploy profiles, one that copies after build appsettings.json group from 'folderA' and one that copies the json group from 'folderB', etc...
I am aware of the post-build events on application project properties, but this events would be applied for all builds, and I don't see any textbox to set post deploy commands on deploy profile.
Am I missing something, or there is not way for script this behaviour with deploy tool?

Related

How to manage A LOT of similar configurations in TFS

I have an ASP .Net MVC application with 4 different publishing profiles: dev, test, demo and prod.
These publising profiles are build using the same two steps: NuGet restore followed by an MSBuild. Then, they are deployed to lots of different servers: a few dev servers (one server dev per team), one test server, one demo server and several production servers.
msbuild /p:Configuration="$(Configuration)"
/p:PlatformTarget="any cpu"
/p:DeployOnBuild="True"
/p:DeployTarget="MsDeployPublish"
/p:MSDeployServiceURL="$(MSDeployServiceURL)"
/p:DeployIISAppPath="portal"
/p:CreatePackageOnPublish="False"
/p:MsDeployPublishMethod="WMSVC"
/p:AllowUntrustedCertificate="True"
/p:UserName="Deploy_User_For_TFS"
/p:Password="P#ssw0rd"
/p:AutoParameterizationWebConfigConnectionStrings=False
/p:ExcludeFilesFromDeployment="Cache"
Currently I have 4 TFS Build configurations (one for every publishing profile) and a file where I have all the possible values for MSDeployServiceURL parameter.
There are two issues with this approach:
When we had to add a new parameter AutoParameterizationWebConfigConnectionStrings we had to change it in 4 places instead of one.
We have to have a shared file as the source for the parameters. it is not easy to understand where which value should be copied and people often make mistakes.
So I have two questions:
Is there any way to have a one universal template where I can specify only my parameters Configuration and list of possible MSDeployServiceURLs and have everything else stay the same? Having such a template should fix problem #1.
Is there a way to define a drop-down like variable, where the value could not be typed in by the user, but should be selected from a pre-defined list of values?
Is there any way to have a one universal template where I can specify
only my parameters Configuration and list of possible
MSDeployServiceURLs and have everything else stay the same? Having
such a template should fix problem #1.
You could simplify such that the release configuration creates a templated publish profile. Then using TFS's release management, you could update the publish profile with the appropriate values. Based on your description, it seems like you are trying to combine both the compilation and the release.
For example, in TFS you could have one build (for example, MyApp-Release) that builds the code in the release configuration. As part of that process, it passes in placeholders for things like the deploy URL. For example, /p:MSDeployServiceURL="$(MSDeployServiceURL)" would be /p:MSDeployServiceURL="__MSDeployServiceURL__".
In the TFS release, you'd have a step that the replaces tokens (if you need one, you can use Colin's ALM Corner Custom Build Tasks) in the publish profile. The replace token task would then update the __MSDeployServiceURL__ with the value from an release environment variable with the same name (minus the underscores). So your release would have a dev, test, demo, and prod environment and for each environment, there would be a variable named MSDeployServerURL in each with a different value and a replace tokens step.

Using VSTS Release Management, how can I modify the configuration of an Azure Web App for each environment?

I'm using Visual Studio Team Services and I'm trying to set up Release Management to allow automated deployments for our Azure Web App to multiple environments. I would like the same source to be deployed to each environment, but with modified configuration settings.
I was hoping that I could create a single Build for my application, and then modify the configuration at deployment time for each environment. I'm aware that this can be done for appSettings and connectionStrings (either through Tokenization, or even managing those settings via the Azure portal), but I'd like to be able to make more general changes to the web.config file. For example, I want to be able to:
Update 'simple' settings such as appSettings/connectionStrings
Update multiple attributes on elements (like httpErrors)
Insert or rewrite sections of the config file itself (for example to add IIS rewrite rules, or to remove unwanted HTTP handlers for production)
Currently we achieve this by using config file transformations and separate publish profiles for each environment (manual deployment). I can't see a way to re-use this if I want a single release pipeline.
I'm hoping someone can help point me in the right direction. I'm also happy to accept alternative solutions - ultimately I just want to be able to deploy the same source (e.g. from the same commit in source control) to multiple environments, with different configuration, while keeping some kind of flow from dev, to test, to eventually production.
You can use Tokenization Task to update the files base on the environment variables.
More similar extensions: Replace Tokens and Colin's ALM Corner Build & Release Tools.

Environment specific EF6 Code First Migrations using VSTS Release

I have a project that uses Entity Framework 6.x, ASP .NET WebApi 5.x. Data Access is in a secondary project inside the solution. I want to use VSTS (aka Visual Studio Online) to build and release it as a website to environments for integration/dev, qa, stage, and production. There are some great videos on Channel 9 that deal with the generic high-level description. (for example https://channel9.msdn.com/Series/DevOps-Release-Management and https://channel9.msdn.com/Series/DevOps-Fundamentals/Infrastructure-as-Code) There are all kinds of articles and videos about how to do migrations from inside Visual Studio including generating scripts.
Searching around the web I don't even find any older resources or concrete examples of continuous deployment with code first migrations. There must be examples and best practices for methods other than auto-migrations or SQL scripts.
I have configured a Web Deployment Package publish profile. I use it via the PublishProfile msbuild.exe directive. The package is added to the artifacts and then deployed by the Azure Web App Deployment task in each Release environment. However once this package is built, I don't know of a way of changing the connection string in the build package for each time it is released to an environment.
There is probably something I am overlooking, but how should environment specific migrations be done with via VSTS Release?
For Code First Migration, you can "Write App_Start code to run Migrations" or "Write Web.config transforms to configure the MigrateDatabaseToLatestVersion initializer to run", refer to this article for details: http://blogs.msdn.com/b/webdev/archive/2014/04/09/ef-code-first-migrations-deployment-to-an-azure-cloud-service.aspx
For the connection string transformation with profile, you need to add a web.config file for the publish profile and then enter the connection string in this web.config. Refer to this link for details: http://awaitwisdom.com/publish-profile-config-transform/
I hate to answer my own questions here but, ultimately my research took me to the conclusion I am posting at length here. In sort, Web.config and Parameters.xml require some custom scripting that will require you to maintain your own deployment automation. These routes will still require you to additionally create your resource groups or manage them manually.
To avoid these complications and cobbling tools and scripts together, the whole operation can be achieved with two JSON files. These JSON deployment templates allow you to create or update your resource group when your deployment runs. They also allow you to automate setting appsettings and connectionstrings that overwrite your Web.config values in the same manner as you can through the Azure Portal.
the steps: (1) Add the two JSON files to the project setting the name of you connection string on line 88 (2) Add a Azure Resource Group Deployment task to the Release environment. (3) Set Template (WebSite.json) and Template Parameters (WebSite.parameters.json) paths in the task. (4) Set Override Template parameters to -hostingPlanName "myHostingPlan" -webSiteName "myWebsiteName" -connectionString "the-actual-connection-string" (5) make sure you are using the same website name in your Azure App Deployment task.
This does depend on having your code first migrations run via App_Start or something similar. I took the first part of #Eddie's suggestion since App_Start is easy to deal with and doesn't seem to run too often.
As a bonus you can add environment variables for any of this configuration so you can clone the environment and then just change the variables. This ultimately makes your application or api connection string a Release variable.

Azure: How do I disable the deployment an just create a package file?

We have a couple of cloud services and do a Continuous Delivery to a test environment via Team Build.
For the production environment, we have our own deployment powershell script. This script needs a .cspkg file for deployment.
My problem is now that I haven't found a way to let team build just create a .cspkg file but not to publish it to Azure.
I've used the AzureContinousDeployment.11.xaml template and it insists on publishing the package.
I've tried to set the "Deployment Settings Name" to an empty string. The build runs without errors, but that way, no package is created.
Is there a way to stop it somewhere in between?
Maybe something I could change in the .azurePubxml file to achieve that?
Environment: VS2012, Team Foundation Service (visualstudio.com)...
On the Process tab of the edit definition:
If you clear out the Deployment Settings Name and all the values under Publishing - Azure Cloud Service and Publishing - Azure Website (except you can leave True for the Allow Upgrade) the building template won't know where to publish the project.
Also on the Build Defaults tab of the edit definition:
Select the "Copy build output to the following Source Control folder (this folder will be created if it does not exist):"
Add some name and path like: "$/your cloud service/drops"
That will cause all your builds to be moved to the drops folder after a successful build. In those drops folders, there will be a app.publish directory that will have your *.cspkg and *csfg files.
I have my custom build template xaml invoke the MSBuild task (Microsoft.TeamFoundation.Build.Workflow.Activities.MSBuild) on the Azure project (.ccproj file) with the "Publish" target.
(Despite having the same name as the UI command that pushes the package to Azure, the "Publish" target just means "generate the package without pushing it anywhere".)

CI and Deployment with TFS and Powershell

I am working on a CI process with automated deployment. TFS Build is building the solution, and it then uses an InvokeProcess task to kick off a Powershell script. The Powershell script deploys the database changes as a dacpac using sqlpackage, reporting services reports using the web service, fonts to the SSRS server, and the website itself to 1 or more web servers - the whole process uses a deployment configuration file to define drop paths, server ips, installation folders etc. There will be one of these per environment.
I would like to be able to build the solution and deploy to an internal server to run automated tests as part of the automated build. Once tests are completed, and the build has been manually checked, I'd then like to be able to kick off another Build definition which only has the deployment portion of the standard build template, which will simply take a build number or build drop location, and deploy the same build to a different environment (i.e. staging, prod etc.)
The issue I have is that I'm currently managing most of my web/app configuration using config file transformation - i.e. I have build definitions for Debug, Test, Prod etc. and then Web.Debug.config, Web.Test.config etc. I only want to carry out one build, and then deploy that same build to different environments, however at the moment the build will only generate configuration files for one environment - i.e. whatever the build configuration is.
Would the best approach be to generate all config files (or actually pre-createg complete config files for each environment), and then just choose the appropriate one for the specific deployment? Or should I store the env specific config in my deployment configuration file and update the appropriate keys using powershell when deploying?
What would be the normal/recommended approach here?
I'd suggest creating new Configurations for each target environment (e.g. by default you have Debug/Release, create some more). Then use the built-in web.config transforms, for non web-projects use Slow Cheetah
This will spit out pre-configured build outputs for each configuration you specify you want build (in your Build Definition).