A couple of weeks ago, I wrote about deploying multiple applications to Azure virtual directories from a single Git repository to Azure. That method works well. However, it by default only supports building and deploying a single .NET project. This was fine in my previously example in which only one of the deployment projects I had was .NET based. Using a custom KUDU script, it’s possible to deploy multiple .NET applications to the virtual directories from a single git repository.
Using the Azure CLI, you can create a default KUDU script. Install Azure CLI with NPM, and then run it get a script for an arbitrary project/solution.
1 2 3 | npm install azure-cli -g azure config mode asm azure site deploymentscript --aspWAP solutionFolder/ProjectFolder/Project.csproj -s solutionFolder/Solution.sln |
For a Windows system, this will output a Windows batch file called “deploy.cmd.” As I detailed in my other post, this deploy.cmd can be used in conjunction with submerge folders to pull multiple projects into a single git repository.
The script, though, only will build and deploy a single project. However, it’s a Windows batch file, so we can modify it to deploy multiple projects to our virtual directories. What I did with the default script was modify it to have iterate over an array of projects/solutions and deploy them. This iterating simply calls the default deployment bits with specific variables from the iterated parameters.
Here’s my custom script. You can see that I specify (2) projects/solutions and these two projects get deployed appropriately. To achieve this, I put the default deployment functionality into a Windows batch function and call it during the looping over the project names.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | @if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off :: ---------------------- :: KUDU Deployment Script :: Version: 1.0.9 :: ---------------------- :: Prerequisites :: ------------- :: Verify node.js installed where node 2>nul >nul IF %ERRORLEVEL% NEQ 0 ( echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment. goto error ) :: Setup :: ----- setlocal enabledelayedexpansion SET ARTIFACTS=%~dp0%..\artifacts IF NOT DEFINED DEPLOYMENT_SOURCE ( SET DEPLOYMENT_SOURCE=%~dp0%. ) IF NOT DEFINED DEPLOYMENT_TARGET ( SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot ) IF NOT DEFINED NEXT_MANIFEST_PATH ( SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest IF NOT DEFINED PREVIOUS_MANIFEST_PATH ( SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest ) ) IF NOT DEFINED KUDU_SYNC_CMD ( :: Install kudu sync echo Installing Kudu Sync call npm install kudusync -g --silent IF !ERRORLEVEL! NEQ 0 goto error :: Locally just running "kuduSync" would also work SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd ) IF NOT DEFINED DEPLOYMENT_TEMP ( SET DEPLOYMENT_TEMP=%temp%\___deployTemp%random% SET CLEAN_LOCAL_DEPLOYMENT_TEMP=true ) IF DEFINED CLEAN_LOCAL_DEPLOYMENT_TEMP ( IF EXIST "%DEPLOYMENT_TEMP%" rd /s /q "%DEPLOYMENT_TEMP%" mkdir "%DEPLOYMENT_TEMP%" ) IF DEFINED MSBUILD_PATH goto MsbuildPathDefined SET MSBUILD_PATH=%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe :MsbuildPathDefined SET "projects[0]=dir1\Project1\Project1.csproj" SET "solutions[0]=dir1\Solution1.sln" SET "solutiondirs[0]=dir1" SET "projects[1]=dir2\Project2\Project2.csproj" SET "solutions[1]=dir2\Solution2.sln" SET "solutiondirs[1]=dir2" SET len=0 :SymLoop if defined projects[%len%] ( SET /a "len+=1" GOTO :SymLoop ) echo "The length of the array is" %len% SET /a "len-=1" FOR /L %%A IN (0,1,%len%) DO ( echo !projects[%%A]! !solutions[%%A]! !solutiondirs[%%A]! call :deploy !projects[%%A]! !solutions[%%A]! !solutiondirs[%%A]! ) :deploy :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: Deployment :: ---------- SHIFT IF (%0)==() GOTO error SET "PROJECT_PATH=%~0" SET "SOLUTION_PATH=%~1" SET "SOLUTION_DIR=%~2" echo Handling .NET Web Application deployment. :: 1. Restore NuGet packages IF /I "%SOLUTION_PATH%" NEQ "" ( call :ExecuteCmd nuget restore "%DEPLOYMENT_SOURCE%\%SOLUTION_PATH%" 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%\%PROJECT_PATH%" /nologo /verbosity:m /t:Build /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="%DEPLOYMENT_TEMP%";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release;UseSharedCompilation=false /p:SolutionDir="%DEPLOYMENT_SOURCE%\%SOLUTION_DIR%\\" %SCM_BUILD_ARGS% ) ELSE ( call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\%PROJECT_PATH%" /nologo /verbosity:m /t:Build /p:AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release;UseSharedCompilation=false /p:SolutionDir="%DEPLOYMENT_SOURCE%\%SOLUTION_DIR%\\" %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%\%SOLUTION_DIR%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd" IF !ERRORLEVEL! NEQ 0 goto error ) EXIT /B :: Execute command routine that will echo out when error :ExecuteCmd setlocal set _CMD_=%* call %_CMD_% if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_% exit /b %ERRORLEVEL% :error endlocal echo An error has occurred during web site deployment. call :exitSetErrorLevel call :exitFromFunction 2>nul :exitSetErrorLevel exit /b 1 :exitFromFunction () :end endlocal echo Finished successfully. |