Compare Business Central versions easily with Azure Devops

In preparation for a What’s New webinar (organized by COSMO CONSULT) I wanted to compare the code of BC19 with BC20. This task is a challenge for most comparison tools. However, not for the GIT comparison tools which are integrated in Azure DevOps.

I had the idea to generate a pipeline which copies the current code from BC into a GIT repo.

Get the current code of Business Central

The first challenge was to find a way to access the current code via Powershell.

For this challenge I used the Get-ArtifactUrl function of Azure DevOps

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $artifact =  Get-BCArtifactUrl -type  $(type) -country  $(country) -select $(select)
          
          Write-Host Download Artifact $artifact 
          $ProgressPreference = 'SilentlyContinue'
          Invoke-WebRequest -Uri $artifact -OutFile artifact.zip

          Write-Host Expand Archive $artifact 
          Expand-Archive -Path artifact.zip -DestinationPath $(Pipeline.Workspace)\artifact
      displayName: Get BC Artifact   

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          Write-Host Expand Archive $artifact 
          Expand-Archive -Path "$(Pipeline.Workspace)\artifact\Applications\BaseApp\Source\Base Application.Source.zip" -DestinationPath $(Pipeline.Workspace)\BC\BaseApp
      displayName: Expand Base App

Commit the code to a GIT repo

To commit the code you need to first check it out with

    - checkout: BC
      clean: true
      path: BC
      persistCredentials: true

And then add all files and commit

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          Write-Host Update Repo BCVersion Comparison $artifact 
          $appJson = Get-Content $(Pipeline.Workspace)\BC\BaseApp\app.json | ConvertFrom-Json 
          cd $(Pipeline.Workspace)\BC
          git config --global user.email "pipeline@cosmoconsult.com"
          git config --global user.name "CI Test Pipeline"
          git add *
          git commit -m "Update Version $appJson.Version"
          git push -u origin master
          git tag $appJson.Version
          git push -u origin $appJson.Version
      displayName: Update Repo

Compare the Version

Using the Pipeline now we have created a tag for the current BC Version

The whole pipeline

The pipeline also includes a schedule and a job to start my build agent via Azure API. For security reasons I removed the subscription ID and the name of the virtual machine. To use the API you also need to add a service connection

schedules:
  - cron: 0 0 * * Sun  
    branches:
      include:
      - master

trigger: none


variables:
- name: country
  value: at
- name: type
  value: OnPrem
- name: select
  value: latest

resources:
 repositories:
   - repository: BC
     type: git
     name: BCVersionComparison



jobs:
  - job: StartVM
    pool: server
    steps:
      - task: InvokeRESTAPI@1
        inputs:
          connectionType: "connectedServiceNameARM"
          azureServiceConnection: "Azure"
          method: "POST"
          urlSuffix: "subscriptions/{subscriptionid}/resourceGroups/AzureDevOps/providers/Microsoft.Compute/virtualMachines/{VMName}/start?api-version=2020-12-01"
          waitForCompletion: "false"
        displayName: Start Agent

  - job: UpdateRepo
    pool: default
    workspace:
      clean: all
    steps:
    - checkout: self
      clean: true
      path: CI
      persistCredentials: true

    - checkout: BC
      clean: true
      path: BC
      persistCredentials: true
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          Install-Module BCContainerHelper -Scope CurrentUser -Force 
          Import-Module BCContainerHelper -Force
      displayName: Import BCContainerHelper

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $artifact =  Get-BCArtifactUrl -type  $(type) -country  $(country) -select $(select)
          
          Write-Host Download Artifact $artifact 
          $ProgressPreference = 'SilentlyContinue'
          Invoke-WebRequest -Uri $artifact -OutFile artifact.zip

          Write-Host Expand Archive $artifact 
          Expand-Archive -Path artifact.zip -DestinationPath $(Pipeline.Workspace)\artifact
      displayName: Get BC Artifact

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          cd $(Pipeline.Workspace)\BC
          git checkout master
          
          Remove-Item -Recurse $(Pipeline.Workspace)\BC\* -Exclude .git    
      displayName: Cleanup Repo

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          Write-Host Expand Archive $artifact 
          Expand-Archive -Path "$(Pipeline.Workspace)\artifact\Applications\BaseApp\Source\Base Application.Source.zip" -DestinationPath $(Pipeline.Workspace)\BC\BaseApp
      displayName: Expand Base App

    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          Write-Host Update Repo BCVersion Comparison $artifact 
          $appJson = Get-Content $(Pipeline.Workspace)\BC\BaseApp\app.json | ConvertFrom-Json 
          cd $(Pipeline.Workspace)\BC
          git config --global user.email "pipeline@cosmoconsult.com"
          git config --global user.name "CI Test Pipeline"
          git add *
          git commit -m "Update Version $appJson.Version"
          git push -u origin master
          git tag $appJson.Version
          git push -u origin $appJson.Version
      displayName: Update Repo

Leave a Reply