@rob_rich
by Rob Richardson
Rob Richardson is a local software craftsman building web properties in ASP.NET and Node, Angular, and React. He’s a Microsoft MVP, published author, frequent speaker at conferences, user groups, and community events, and a diligent teacher and student of high quality software development. You can find this and other talks on https://robrich.org/presentations and follow him on twitter at @rob_rich.
Azure Git Deploy | Visual Studio Team Services |
Free with Azure Web App (including free tier) | Separate Azure purchase |
Command-line tools and logs | Web-based GUI including test result charts |
Build Deploy |
Build Deploy Track work items Reporting |
Companion Code: https://github.com/robrich/HelloKudu
source: azure.microsoft.com/en-us/documentation/articles/azure-web-sites-web-hosting-plans-in-depth-overview
source: azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control
source: azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control
From within your git working directory:
git remote add azure https://[email protected]:443/NeedsMoreGit.git
git push azure master
git push azure master
source: datascienceandprogramming.azurewebsites.net/wp-content/uploads/2013/11/Capture-132.png
source: azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control
source: erikschlegel.com/2015/06/20/azure-continuous-deployment-using-git-private-repos
Install node
Install Azure CLI Tools
npm install azure-cli -g
azure site deploymentscript --aspWAP path/to/Project.csproj -s SolutionFile.sln
Docs: github.com/projectkudu/kudu/wiki/Customizing-deployments
For Node, PHP, ASP.NET Core, etc
azure site deploymentscript --node path/to/deploy/folder
Docs: github.com/projectkudu/kudu/wiki/Customizing-deployments
[config]
command = deploy.cmd
Docs: github.com/projectkudu/kudu/wiki/Customizing-deployments
Deployment script can be:
Powershell is a little weird:
[config]
command = powershell -NoProfile -NoLogo -ExecutionPolicy Unrestricted -Command "& "$pwd\deploy.ps1" 2>&1 | echo"
Docs: github.com/projectkudu/kudu/wiki/Customizing-deployments
... snip ...
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Deployment
:: ----------
echo Handling .NET Web Application deployment.
:: 1. Restore NuGet packages
IF /I "Hello.sln" NEQ "" (
call :ExecuteCmd nuget restore "%DEPLOYMENT_SOURCE%\Hello.sln"
IF !ERRORLEVEL! NEQ 0 goto error
)
:: 2. Build to the temporary path
IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" (
call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\src\Web\Web.csproj" /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%\src\Web\Web.csproj" /nologo /verbosity:m /t:Build /p:AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release;UseSharedCompilation=false /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\" %SCM_BUILD_ARGS%
)
IF !ERRORLEVEL! NEQ 0 goto error
:: 3. KuduSync
IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" (
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd"
IF !ERRORLEVEL! NEQ 0 goto error
)
... snip ...
git add .deployment
git add deploy.cmd
git commit -m "deployment files"
git push azure master
Add more steps to deploy.cmd
:: 2. Build test project
echo Building test project
"%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\Tests\Tests.csproj" /property:Configuration=Release
IF !ERRORLEVEL! NEQ 0 goto error
:: 3. Run tests
echo Running tests
"%DEPLOYMENT_SOURCE%\packages\xunit.runner.console.2.1.0\tools\xunit.console.exe" "%DEPLOYMENT_SOURCE%\Tests\bin\Release\Tests.dll"
IF !ERRORLEVEL! NEQ 0 goto error
If tests fail, deployment is aborted, current site is unaffected
source: blog.amitapple.com/post/51576689501/testsduringazurewebsitesdeployment
The easiest way is to add npm scripts to package.json
{
"name": "my-site",
"version": "1.0.0",
"scripts": {
"test": "eslint .",
"build": "gulp"
},
"devDependencies": {
"eslint": "^2.12.0",
"gulp": "^3.9.1",
"gulp-minify-css": "^1.2.4",
"gulp-uglify": "^1.5.3",
"mocha": "^2.5.3",
"chai": "^3.5.0"
}
}
If tasks fail, deployment is aborted, current site is unaffected
Add more steps to deploy.cmd
:: 3. Run ESLint and Gulp
:: upgrade npm
call npm cache clean
call npm install -g npm
pushd "%DEPLOYMENT_SOURCE%"
call npm install && npm test && npm run build
IF !ERRORLEVEL! NEQ 0 goto error
popd
If tasks fail, deployment is aborted, current site is unaffected
Add to AssemblyInfo.cs
[assembly: AssemblyInformationalVersion("GITHASH")] // Set to git hash in build file
Change GITHASH in deploy.cmd
call :ExecuteCmd PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "(Get-Content Web\Properties\AssemblyInfo.cs).replace('GITHASH', (git rev-parse --short HEAD)) | Set-Content Web\Properties\AssemblyInfo.cs"
Read value in C#
Assembly assembly = Assembly.GetExecutingAssembly();
AssemblyInformationalVersionAttribute desc = (
from a in assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)
select a as AssemblyInformationalVersionAttribute
).First();
gitHash = desc.InformationalVersion;
Add step after deploy in deploy.cmd
:: 9. Test website
:: https://www.amido.com/code/powershell-win32-internal-error-the-handle-is-invalid-0x6/
call :ExecuteCmd PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; exit ((invoke-webrequest -method head -uri 'http://%WEBSITE_HOSTNAME%/' -UseBasicParsing).statuscode - 200)"
IF !ERRORLEVEL! NEQ 0 goto error
Add more steps to deploy.cmd
:: 6. Migrate database
:: TODO: set %server%, %db%, %user%, %password%
pushd "%DEPLOYMENT_SOURCE%"
call tools\sqlcompare-11.2.3.12\sqlcompare.exe /scripts1:sql /server2:%server% /db2:%db% /username2:%user% /password2:%password% /sync /Include:Identical /exclude:role /exclude:user
IF !ERRORLEVEL! NEQ 0 goto error
call tools\sqldatacompare-11.2.3.12\sqldatacompare.exe /scripts1:sql /server2:%server% /db2:%db% /username2:%user% /password2:%password% /sync /Include:Identical /AbortOnWarnings
IF !ERRORLEVEL! NEQ 0 goto error
:: popd
If migrations fail, deployment is aborted, database may be in an unknown state
User steps to run it:
git push azure