How to add a custom post deployment script to azure websites? - azure

My problem is that I need to run a custom cmd file after the build.
Instead of modifying the deployment scripts I just want to run few MSDOS commands to my deployment easily.
The task I need to do is to run a cmd at the repository located at /source/copyextrafiles.cmd after the build succeeded.
How can I achieve that?

At the azure portal on the CONFIGURE tab of your website add a "app settings" entry called POST_DEPLOYMENT_ACTION with the value of source/copyextrafiles.cmd
Save and the next deploy will run the cmd for you after the deploy.
Here the picture:

An alternative in addition to the solutions already provided is to copy the script in to a specific folder provided for post deployment action hooks.
So after creating a new directory in "D:\home\site\deployments\tools\" named "PostDeploymentActions", you could just add script files (.bat, .cmd or .ps1) into the directory and they will all run, one by one, after each deployment.

Related

Bug in Azure devops pipeline/VS templates/dockerfile?

Trying to deploy a multi-project app to azure using pipelines. After trying various combinations (pipeline log is showing about 75/80 runs in the last couple of days), it looks like the problem is with the Dockerfile by Visual Studio 2019 or with the Azure Pipeline somewhere.
Here's what I've narrowed it down to:
Project A-
create a vs asp.net core webapp project, say test1sp,
select the checkbox which says create solution and project in the same folder,
select docker support (I selected Linux) or add it later
no code added, the boilerplate code runs fine as-is
add it to GitHub
create a project/pipeline in azure, source Github, I use the classic editor without YAML
create a docker build/push task and setup, I choose the most basic options, subscriptions, etc.
build works great, I also added a deploy to app service task and it deploys to the app service
Project B - my project is called demo8
Same as project A, except for step #2 - do NOT select create solution and project in the same folder. Follow the rest of the steps and now you should get this error.
Step 7/17 : COPY ["demo8/demo8.csproj", "demo8/"]
...
...
##[error]COPY failed: file not found in build context or excluded by .dockerignore: stat demo8/demo8.csproj: file does not exist
It works fine on localhost/docker. So, I'm guessing maybe vs2019 uses some more tolerant implementation to patch it over. Or, there's a problem with azure's implementation or something else?
I am relatively new to Dockerfile editing and see lots of detailed/complex scenarios, hopefully, someone can shed some light on how to get it working?
Here's a screenshot of the project files/structure:
UPDATE -
Moving the Dockerfile to the solution folder in project B makes it work in azure BUT
then it does NOT work in Visual Studio, no debugging, etc.
make a copy of Dockerfile in project & parent folders ( + keep in sync )
BUT if your solution has multiple projects like mine then
you have to name the Dockerfile different to have unique names in the parent folder
and modify the pipelines to use respective file names
Posting it here in case it helps someone.
The code in the Dockerfile must have the relative path to the folder level that the Dockerfile is in.
Tow ways to solve the problem. One is the change the code in the Dockerfile, for the project B, you can change the COPY code like this:
COPY ["demo8.csproj", "demo8/"]
Another way is to move the Dockerfile to the path that matches your COPY code. But in this way, it may affect other codes in your Dockerfile.
And you'd better plan your projects in different folders and create the Dockerfile for each project in different folders.
I just ran into this problem with a default console app in VS2022. I fixed it by changin the "Build context" parameter in the ADO build pipeline's Docker "build and push" step from the default of ** to **/.. so that the working directory was the solution folder, which matches VS (AFAIK).
Similar to #Josh's answer above -- I explicitly set
buildContext: '$(Build.SourcesDirectory)'
in the Docker task in the Azure Pipelines YML file, and it worked like a charm.
Something for the Azure pipelines template maintainer(s) to look into perhaps?

Running Kentico continuous integration on Azure app services

We have a new project in which we are trying to make use of the built in continuous integration in Kentico for tracking changes to templates, page types, transformations etc.
We have managed to get this working locally between two instances of a Kentico database, making changes in one, syncing the changes through CI and then restoring them up to the second database using the Continuous integration application that sits in the bin folder in the Kentico site.
The issue we are having is when it comes to deploying our changes to our dev and live environments.
Our sites are hosted as Azure App services and we deploy to them using VSTS (Azure DevOps) build and release workflows however, as these tasks run in an agent, any powershell script we try to run to trigger the CI application fails because it is not running in the site / server context.
My question is, has anyone managed to successfully run Kentico CI in the context of an Azure app service? Alternatively, how can I trigger a powershell script on the site following a deployment?
Yes, I've got this running in Azure DevOps within the release pipeline itself. It's something that we're currently rolling out as a business where I work.
The key steps to getting this working for me were as follows:
I don't want to deploy the ContinuousIntegration.exe or the repository folders, so I need to create a second artefact set from source control (this is only possible at the moment with Azure Repos and GitHub to my knowledge).
Unzip your deployment package and copy the CMS folder to a working directory, this is where you're going to run CI. I did this because I need the built assemblies available.
From the repo artefact in step 1, copy the ContinuousIntegration.exe and CI repository folders into the correct place in your unzipped working folder.
Ensure that the connection string actually works for the DB in your unzipped folder, if necessary, you may want to change your VS build options in regards to how the web.config is handled.
From here, you should be able to run CI in the new working folder against your target database.
In my instance, as I don't have CI running on the target site it means that everything is restored every time.
I'm in to process of writing this up in more detail, so I'll share here when I've done that.
Edit:
- I finally wrote this up in more detail: https://www.ridgeway.com/blog/web-development/using-kentico-12-mvc-with-azure-devops
We do, but no CI. VSTS + GIT. We store virtual objects in the file system and using git for version control. We have our own custom library that does import export of the Kentico objects (the ones are not controlled by Git).Essentially we have a json file "publishing manifest" where we specify what objects need to be exported (i.e. moved between environments).
There is a step from Microsoft 'Powershell on Target Machines', you guess you can look into that.
P.S. Take a look also at Three Ways to Manage Data in Kentico Using PowerShell
Deploy your CI files to the Azure App Service, and then use a Azure Job to run "ContinuousIntegration.exe"
If you place a file called KenticoCI.bat in the directory \App_Data\jobs\triggered\ContinuousIntegration - this will automatically create a web job that you can can trigger:
KenticoCI.bat
cd D:\home\site\wwwroot
ren App_Offline.bak App_Offline.htm
rem # run Kentico CI Integraton
cd D:\home\site\wwwroot\bin
ContinuousIntegration.exe -r
rem # Removes the 'App_Offline.htm' file to bring the site back online
cd D:\home\site\wwwroot
ren App_Offline.htm App_Offline.bak

Azure web app - syncing files from external process

This question feels so simple that I'm confused why I can't find an answer!
We have an Azure web app, typically running on 2 to 5 instances.
At the moment we manually run a quite intensive PHP script a few times a day on a local computer to generate a folder of files. (The resulting folder isn't huge - typically about 10MB in size and a few hundred files in total.) We then sync them via Github and they deploy to the website. Easy.
That process is fine, but we want to move the PHP script to Azure so we can remove the dependency on running it locally and instead run it as a chron job.
How can we reliably sync the outputted folder from our script into our web app?
One option is to use a triggered WebJob with a cron schedule. Your WebJob can contain just your PHP script. Or if it needs a special command line to run, include a run.cmd batch file with the full PHP command line.
In your PHP script, do whatever you need to gather the right set of files, and then just copy them to %home%\site\wwwroot\json-data.
For this to work, everything you need to do within your PHP script needs to be runnable within the App Service sandbox. You should first try this directly from Kudu Console before moving it to a WebJob, to make sure everything can run.
Set your web app deployment source to Local Git. After that push your code to WebApp by Git Push . I am not sure about PHP build process but when you push your code to AzureWeb app via LocalGit method it builds and restores all dependencies and deploy it . For custom build script you can refer https://github.com/projectkudu/kudu/wiki/Custom-Deployment-Script.
https://medium.com/#trstringer/custom-build-logic-post-git-push-with-azure-app-service-and-kudu-for-a-node-js-web-app-1b2719598916

Azure continuous deployment for multiple projects

I have created an Azure Web Site and connected it to Visual Studio Online, and this automatically set up a continuous deployment build (as per this page).
Initially this worked for a solution with one project, but now I have added a Web API project as a back end. This is named such that it is the first of the two projects alphabetically, and so now it is the only project that gets built and deployed whenever files are checked in. Which leads to my question:
How can I modify the default continuous deployment build to deploy both applications?
I'm sure it must be a fairly simple change to either the build template or parameters, or the publish profiles that are being used by the build. The only problem is I don't know: A) how to change those settings in the default TfvcContinuousDeploymentTemplate.12.xaml build template, and B) how to modify the publish profiles that are used in the continuous deployment build.
I have already, from within Visual Studio, manually published the two projects and got them to deploy to the right locations by following the instructions in this answer. I right-clicked on each project, clicked publish, then selected the "Microsoft Azure Web Apps" publish target which (after filling in all the settings) added the publish profiles to my projects and allowed me to manually deploy them how I wanted.
Unfortunately there seems to be no way to re-upload those publish profiles so that they can be used in the CD build. I've checked them into source control, I just need to know how I can get the CD build to make use of them. How can I do this?
After reading through the first link in my question again, I noticed that you can edit the build definition (or template) to point to the publish profile that you want to use:
Path to Deployment Settings: The path to your .pubxml file for a web app, relative to the root folder of the repo. Ignored for cloud services.
Unfortunately, this both doesn't work and only allows you to specify one publish profile file. Presumably, even if specifying this argument worked, the build would still only deploy the first app in alphabetical order.
This lead me to this question and answer though, which suggests that the Azure/TFVC continuous deployment works simply by using the ordinary Web Deploy arguments to MSBuild. Looking at the diagnostic logs of my build in Visual Studio Online proved this to be the case; here are the relevant arguments:
C:\Program Files (x86)\MSBuild\14.0\bin\amd64\msbuild.exe /p:DeployOnBuild=true /p:CreatePackageOnPublish=true /p:DeployIisAppPath=mysitename
So, as per that question, to use a specific publish profile you can just set the additional necessary MSBuild arguments in the build definition:
Each project needs to have a publish profile called "publishprofilename.pubxml", in this case, checked into source control. I found that the user name (which is your site name with a dollar sign in front of it) is not needed, but unfortunately the password string is required. If you don't include it you get an error like this in the build:
Web deployment task failed. (Connected to the remote computer
("[mysitename].scm.azurewebsites.net") using the Web Management Service,
but could not authorize.
No other arguments were required for me, but it doesn't seem ideal that the password has to be included. The default deployment setup, without using publish profiles, must be authorising with that password somehow, but I don't know how.
So after making this change I navigated to [mysitename].azurewebsites.net, and it appeared that still only the Web API project was being deployed. However, by going to console for the site and entering dir D:\home\site\wwwroot I can see that both projects are actually being deployed. It's just that both projects are being deployed to the root of the site, at D:\home\site\wwwroot. The DeployIisAppPath settings are different in each publish profile, but these values are being ignored. This is because the /p:DeployIisAppPath=mysitename argument to MSBuild (mentioned above) overrides any PropertyGroup settings in publish profile *.pubxml files, as described in this blog post.
What I have found is that the continuous deployment process for Azure/TFVC works by having an InitializeContinuousDeployment build activity in the TfvcContinuousDeploymentTemplate.12.xaml build template, immediately before the RunMSBuild activity. This takes the MSbuild arguments you specify in the build definition, and appends to them the ones needed to deploy to Azure. Unfortunately, this is mostly hard-coded, and that means it always specifies a single deployment path for all web projects in the solution. You can't deploy each web app to a different location using publish profiles alone.
So one workaround option is to add something like a BeforeBuild MSBuild target to each project, to override the command line value of DeployIisAppPath. The problem with this is that the path specified in the publish profile, and seen in the publish wizard, will no longer be the path actually being used for deployment.
So the solution I went with is marginally better; it is what we would describe in New Zealand as "huckery".
Basically I added an InvokeMethod build activity between the InitializeContinuousDeployment and RunMSBuild activities. The arguments for this activity are as follows:
DisplayName:
Configure build for using publish profiles (removes DeployIisAppPath MSBuild parameter)
GenericTypeArguments:
System.String
MethodName:
SetValue
TargetObject:
AdvancedBuildSettings
Parameters:
Direction: Type: Value
In String "MSBuildArguments"
In String String.Join(" ", AdvancedBuildSettings.GetValue(Of String)("MSBuildArguments", String.Empty).Split(New String() {" "}, StringSplitOptions.RemoveEmptyEntries).Where(Function(s) Not s.StartsWith("/p:DeployIisAppPath=")))
What this does is removes the DeployIisAppPath argument from the MSBuild command line arguments list completely, so that it doesn't override this same property in the publish profiles. Instead of the messing around with splitting and joining the string, it would be slightly nicer if you could just append /p:DeployIisAppPath="" to the command line, but this just sets the property to an empty string and you get an error:
"ConcatFullServiceUrlWithSiteName" task was not given a value for the
required parameter "SiteAppName"
So like I said, pretty huckery, but it's a solution that allows you to have continuous deployment of multiple web projects to Azure with a minimal amount of changes to the default setup.
You can override the deployment engine in Kudu by using the Azure CLI Tools. Running the azure site deploymentscript command and passing in the parameters for one of your projects -s <solutionFile> --aspWAP <projectFilePath>.
This will create a .deployment file and a deploy.cmd (or deploy.sh if you pass the -t bash parameter) modifying the deploy.cmd to add build/deploy steps for the second project.
More information is on deployment hooks is available in the project kudu wiki.
EDIT
You can use App Setting COMMAND to add a deployment script to your site.

Teamcity MsBuild generates wrong cspkg file

I am trying to build and Deploy our solution to Azure using TeamCity.
When I Build the azure solution (Web.Azure.ccproj) using TC, it always generates wrong file like Web.Azure.ccproj.cspkg in Release\app.publish folder. I am not understaing why it is generating a file like ccproj.cspkg. Rather it should have just generated Web.Azure.cspkg.
Note: when I try directly in command prompt (msbuild Web.Azure.ccproj /t:Publish) am able to see proper files generated.
Any reason why this is happening?
Thanks in Advance
I don't know why the generated files are different. However, if you are looking to deploy to Azure Cloud Services from TeamCity, maybe this link will help.
The linked post has a powershell script that will deploy the solution and you can include that as a build step in TeamCity. The script deals with having different Live and UAT environments etc, which you may not need.
For what it's worth, we're building the entire solution with a Visual Studio (.sln) runner and it builds the Azure projects fine.
Some of our parameters:
Targets: Rebuild
Configuration: Dev (Could be Stage or Release per our environments)
Command line parameters: /p:TargetProfile=Dev /P:Configuration=Dev
The last set of parameters are where I originally got stuck. We have profiles for Azure projects and configurations for the entire solution. We need both to get the right packages created.

Resources