We have moved!

You are currently looking at documentation for Umbraco 8 and older versions.
An automated guess is that docs.umbraco.com/umbraco-deploy/installing-deploy/cicd-pipeline/ci-cd-azure-dev-ops could be the link to the new documentation for Umbraco 9 and newer versions.

    Setting up CI/CD build server with Azure DevOps

    In this section we provide a full example on how Umbraco Deploy running on Umbraco 8 can be utilized as part of a build and deployment pipeline using Azure DevOps, which you can use or adapt for your needs.

    Discussion on the Provided Example

    We have defined a two-stage build process, divided into a build and a deploy stage, configured in YAML format. Although initially, this isn’t as easy to read as the drag and drop list of tasks, it does have the benefit of being managed in source control.

    We then have a number of variables defined, that are used in the build configuration below. By using variables we have the ability to modify the script easily for use on other web applications.

    Build Stage

    Each stage - the first of which being the build stage - consists of a number of tasks. The majority of these are standard things that will be used in any .NET web application release, such as the first steps:

    #1 Install of the NuGet tooling,

    #2 Restore of NuGet dependencies,

    #3 And the project build.

    The build uses a publish profile named ToFileSys.pubxml in order to output the published web application to a temporary disk location, from where it can be packaged up for deployment. This publish profile should be added to your web application project in the \Properties\PublishProfiles\ folder.

    Step #4 is the first Deploy specific step. The Umbraco Deploy license file needs to live in the bin folder, which here we have checked into source control, but not defined as part of the .csproj file. In this step, we copy it to the bin folder of the published web application using the values defined in the variables.

    There is then a similar step for the schema data files (#5). They are checked into source control and need to be part of the build output so they are deployed to the destination site.

    The last steps in the build stage (#6, #7, #8) prepares the build artifacts, of which there are two. One being the zipped-up, published website along with schema data and license files. The other being the Powershell script, provided with Umbraco Deploy, that will be used to trigger the extraction of the schema files and update of the target environment in the deploy stage.

    Deploy Stage

    The deploy stage consists of two steps. Firstly a web deployment (#1), taking the packaged build artifact and deploying it, in this case, to an Azure web app.

    The second step (#2) is Umbraco Deploy specific - to call a function defined in the Powershell script and trigger the extraction. We provide the API key to authenticate this operation, either from a variable, or in order to add a layer of security, from an Azure secret defined within Azure DevOps.

    Full Example

    trigger:
    - main
    
    pool:
      vmImage: 'windows-latest'
    
    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'
      buildConfiguration: 'Release'
    
      # The Visual Studio .sln name
      vsSolutionName: DeployOnPremSite
    
      # The Visual Studio .csproj Web App name
      vsProjectName: DeployOnPremSite
    
      # The umbraco deploy trigger reason
      umbracoDeployReason: AzureDeployment
    
      # The umbraco deploy data folder path
      umbracoDeployData: $(Build.SourcesDirectory)\$(vsSolutionName)\data
    
      # The umbraco deploy license folder path
      deployLicense: $(Build.SourcesDirectory)\$(vsSolutionName)\bin
    
      # The TriggerDeploy.ps1 file path
      umbracoDeployTriggerDeploy: $(Build.SourcesDirectory)\$(vsSolutionName)\TriggerDeploy.ps1
    
      # The file system folder to publish the web app build
      publishDir: '$(Build.ArtifactStagingDirectory)\_Publish'
    
      # The zip file location of the zipped build output
      zipDir: '$(Build.ArtifactStagingDirectory)\_Zip'
    
      # The name of the target Azure web application
      azureWebAppName: deploy-on-prem-live
    
      # The Azure subscription to deploy to
      azureSubscription: 'Microsoft Azure Sponsorship(5ffea398-7922-451b-bd72-fbe725185cbf)'
    
      # The upstream environment URL
      deployBaseUrl: https://deploy-on-prem-live.azurewebsites.net/
    
    # Stage 1: Build
    stages:
    - stage: Build
      variables:
        Release.EnvironmentName: '$(buildConfiguration)'
      jobs:
      - job: RestoreBuildPublish
        steps:
    
        #1 NuGet Tool Install
        - task: NuGetToolInstaller@1
          displayName: Install NuGet
    
        #2 NuGet Restore
        - task: NuGetCommand@2
          displayName: Restore NuGet
          inputs:
            restoreSolution: '$(solution)'
            feedsToUse: 'config'
            nugetConfigPath: 'Nuget.config'
    
        #3 Build the VS Solution and publish the output to a directory
        - task: VSBuild@1
          displayName: Build
          inputs:
            solution: '$(solution)'
            msbuildArgs: /p:UseWPP_CopyWebApplication=True /p:PipelineDependsOnBuild=False /p:PublishProfile=ToFileSys.pubxml /p:DeployOnBuild=true /p:AutoParameterizationWebConfigConnectionStrings=False /p:PublishOutDir=$(publishDir) /p:MarkWebConfigAssistFilesAsExclude=false /p:TransformWebConfigEnabled=false
            platform: '$(buildPlatform)'
            configuration: '$(buildConfiguration)'
            clean: true
    
        #4 Copy the deploy .lic file as they are not part of the csproj/msbuild
        - task: CopyFiles@2
          displayName: Copy Deploy license
          enabled: true
          inputs:
            sourceFolder: $(deployLicense)
            targetFolder: '$(publishDir)\bin'
            Contents: '*.lic'
    
        #5 Copy the deploy (data) files since they are not part of the csproj/msbuild
        - task: CopyFiles@2
          displayName: Copy data files
          enabled: true
          inputs:
            sourceFolder: $(umbracoDeployData)
            targetFolder: '$(publishDir)'
    
        #6 Zip the output
        - task: ArchiveFiles@2
          displayName: Zip build output
          inputs:
            rootFolderOrFile: '$(publishDir)'
            includeRootFolder: false
            archiveType: 'zip'
            archiveFile: '$(zipDir)/$(Build.BuildId).zip'
            replaceExistingArchive: true
    
        #7 Publish the zipped website as a build artifact
        - task: PublishBuildArtifacts@1
          displayName: Publish website artifact
          inputs:
            PathtoPublish: '$(zipDir)'
            ArtifactName: 'zip'
            publishLocation: 'Container'
    
        #8 Publish the TriggerDeploy.ps1 file as a build artifact
        - task: PublishBuildArtifacts@1
          displayName: Publish deploy trigger script
          inputs:
            pathtoPublish: '$(umbracoDeployTriggerDeploy)'
            artifactName: 'triggerDeploy'
            publishLocation: 'Container'
    
    # Stage 2: Deploy
    - stage: Deploy
      variables:
        Release.EnvironmentName: '$(buildConfiguration)'
      condition: succeeded('Build')
      jobs:
      - deployment: DeployToAzureWebsites
        environment: $(azureWebAppName)-azurewebsites-net
        strategy:
          runOnce:
            deploy:
              steps:
    
              #1 Deploy web application
              - task: AzureRmWebAppDeployment@4
                displayName: Deploy web application
                inputs:
                  ConnectionType: 'AzureRM'
                  azureSubscription: 'Microsoft Azure Sponsorship'
                  appType: 'webApp'
                  WebAppName: '$(azureWebAppName)'
                  packageForLinux: '$(Agent.BuildDirectory)\zip\*.zip'
                  enableCustomDeployment: true
                  DeploymentType: 'webDeploy'
                  enableXmlTransform: true
    
              #2 Trigger schema update
              - powershell: $(Agent.BuildDirectory)\triggerDeploy\TriggerDeploy.ps1 -InformationAction:Continue -Action TriggerWithStatus -ApiKey $(deployApiKey) -BaseUrl $(deployBaseUrl) -Reason $(umbracoDeployReason) -Verbose
                displayName: Umbraco Deploy extraction
                failOnStderr: true
                enabled: true

    Publish Profile

    <?xml version="1.0" encoding="utf-8" ?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <DeleteExistingFiles>False</DeleteExistingFiles>
        <ExcludeApp_Data>True</ExcludeApp_Data>
        <PublishUrl>$(PublishOutDir)</PublishUrl>
        <WebPublishMethod>FileSystem</WebPublishMethod>
      </PropertyGroup>
    </Project>