We’re now in the world of automation. For today, just wanna share about how to do Continuous Deployment on Azure Website…
There are many many ways to do continuous deployment. We can have a build machine which do monitoring our source control then trig a service to do a new build and deploy each time we check-in the code. But .. that mean we have to had that build machine. (You may get it for free if you’re using the Visual Studio Team Services (aka. Visual Studio Online) which I don’t want to mention about it now.
For today with Azure website which everyone can get it free for 10 (tiny) instances, we will talk about automate deployment without any build machine. The azure website itself can do continuous deployment for you.
First thing first – Setup deployment source for Azure website.
You can do it by open your Azure Portal then open you website instance.
Go to Settings > Publishing section > Deployment source which you can pick from several souce control you’re using. It may ask you to enter credential to access your git repository and also let you select your project/branch.
Boom !! it’s done.
What it done is it get the latest code from repository (if it’s git), find a (first) web project, build it then deploy to current web instance. It seem to be easy, isn’t it?
Now .. let’s think about more realistic …
If you have more that one web project in a solution, how it know that which one should be selected to bulid and deploy.
If your web project require external tool such as node.js, gulp task or bower to make the project ready to deploy.
That’s lead to the customization …
To solve the first issue, if we have more than one web project, how to select the one we need to be deployed.
Solution: It’s too easy, I can’t even call this a customization. You can specific the project by set the project path (from your repository root) in the Application Settings of Azure Website.
To access Application settings, just select youe Website > open Settings panel > Application settings will be in General Tab. Then you can select your project by add new key name ‘Project’ with the value of path from you root directory to the project file (.csproj). For example, “src/WebProject/WebProject.csproj”
Then after we specific the project, the continuous engine will now bulid and deploy this project instead.
Next issue, What about the external tool to do additional work for us.
before go to the customization, the engine that do automate build for us above is called Project Kudu. We already used it. !!
First thing to do the customization is we need a file named “.deployment” which the engine will lookup this file when it start doing build.
If this file is not exist it will do everything automatically. But if it exist at the root of code repository, it will do follow the command inside it.
From what I know now, it can specific the project name in side this file as well, but I don’t wanna use it since the file will also check-in to the source control which not helpful in to spefic project in there. But in case you need, just put following text in the file and check it in.
[config] project = src/WebProject/WebProject.csproj
OK. Now back to the point. When we customize the step to do build what we need it put the text below into .deployment file to let Kudu use our customized file.
[config] command = deploy.cmd
Then now create deploy.cmd in the same area with .deployment file. I beleive you we put it into subfolder if need. In deploy.cmd we can get it from several ways.
- Download generic from Kudu project on Github.
- Get file specific for your project from kudu dashboard.
I’ll talk about the second way. Every Azure website will get Kudu web setup and running. You can access it by go the that website. Which usually is [YouAzureWebsiteName].scm.azurewebsite.net
Which mean you just add .scm. in between your webname and the domain of MS azure website. If you have authorized to deploy, I beleive you also have authorized to get access to this kudu web dashboard.
From Kudu dashboard web, You can download the deploy.cmd script from Tool > Download Deployment Script. You will get the zip file which contain both .deployement and also script.
If you look at that script file, it is just look like batch file which contain many Environemnt variable. Now it’s your to customise what you need.
The script will be seperated in to few part, Prerequisites, Setup, Deployment, Post deployement.
What I found which very useful to me is below.
Change the project to be dynamic from Application Settings (like default of kudu)
IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" ( call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\%PROJECT%" /nologo /verbosity:m /t:Build /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="%DEPLOYMENT_TEMP%";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release;UseSharedCompilation=false /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\" %SCM_BUILD_ARGS% ) ELSE ( call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\%PROJECT%" /nologo /verbosity:m /t:Build /p:AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release;UseSharedCompilation=false /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\" %SCM_BUILD_ARGS% )
Prepare node.js env (put before Deployment section in script)
:: Utility Functions :: ----------------- :SelectNodeVersion IF DEFINED KUDU_SELECT_NODE_VERSION_CMD ( :: The following are done only on Windows Azure Websites environment call %KUDU_SELECT_NODE_VERSION_CMD% "%DEPLOYMENT_SOURCE%" "%DEPLOYMENT_TARGET%" "%DEPLOYMENT_TEMP%" IF !ERRORLEVEL! NEQ 0 goto error IF EXIST "%DEPLOYMENT_TEMP%\__nodeVersion.tmp" ( SET /p NODE_EXE=<"%DEPLOYMENT_TEMP%\__nodeVersion.tmp" IF !ERRORLEVEL! NEQ 0 goto error ) IF EXIST "%DEPLOYMENT_TEMP%\__npmVersion.tmp" ( SET /p NPM_JS_PATH=<"%DEPLOYMENT_TEMP%\__npmVersion.tmp" IF !ERRORLEVEL! NEQ 0 goto error ) IF NOT DEFINED NODE_EXE ( SET NODE_EXE=node ) SET NPM_CMD="!NODE_EXE!" "!NPM_JS_PATH!" ) ELSE ( SET NPM_CMD=npm SET NODE_EXE=node )
Install Node pacakge specificed in package.json and execute gulp build tasks
pushd [Path Web Project Folder] IF EXIST "package.json" ( call :ExecuteCmd !NPM_CMD! install --production IF !ERRORLEVEL! NEQ 0 goto error ) IF EXIST "Gulpfile.js" ( call .\node_modules\.bin\gulp build IF !ERRORLEVEL! NEQ 0 goto error call .\node_modules\.bin\gulp build-release-env-const IF !ERRORLEVEL! NEQ 0 goto error ) popd
Install third party components with bower at output folder.
if EXIST "%DEPLOYMENT_TARGET%\bower.json" ( pushd "%DEPLOYMENT_TARGET%" call :ExecuteCmd bower install IF !ERRORLEVEL! NEQ 0 goto error popd )
Hope you can pick some of above to help your job done. 🙂
The kudu website also have many great tools such as
- All Environment variables
- Dubug console both Cmd and Powershell !!!
- Process Explorer
- Web Hooks !!!
- Web Job Dashboard
- Rest Api to get data about deployment
Incase you interest in what is the difference between Visual Studio Team Services (VSTS) build and Kudu, please look at this https://github.com/projectkudu/kudu/wiki/VSTS-vs-Kudu-deployments
Have a nice day 🙂