Business Central Build Pipeline on Microsoft Hosted Agent

Published on 26 August 2023 at 07:00

Introduction

CI/CD (Continuous Integration/Continuous Deployment) is a set of practices and principles used in software development to ensure a streamlined and efficient workflow. It involves the automation of various stages in the software development lifecycle, from code integration and testing (CI) to deployment and delivery (CD).

Continuous Integration refers to the practice of frequently integrating code changes from multiple developers into a shared repository. This is accompanied by an automated testing process that helps catch bugs and conflicts early, ensuring code quality remains high and issues are addressed promptly.

Continuous Deployment, on the other hand, extends the CI process by automatically deploying successfully tested code changes to production environments. This approach accelerates the delivery of new features, enhancements, and bug fixes, making the software development cycle more agile and responsive to user needs.

CI/CD is crucial in software development because it offers several benefits. First, it reduces the risk of integration issues and bugs by catching them early in the development process. Second, it enhances collaboration among developers by ensuring a steady integration of code changes and a consistent feedback loop. Third, it allows for faster and more reliable software releases, enabling organizations to deliver value to users more frequently. Lastly, it promotes a culture of automation and efficiency, which leads to higher developer productivity and software quality.

The same approach applies to the development of applications for Microsoft Dynamics 365 Business Central.

CICD.yml

In your app create yml file

Source code:

trigger:
  branches:
    include:
      - feature/*
      - release/*
      - main

pool:
  name: Azure Pipelines
  vmImage: 'windows-latest'

workspace:
  clean: all

steps:
- checkout: self

- task: DockerInstaller@0
  displayName: Docker Installer
  inputs:
    dockerVersion: 17.09.0-ce
    releaseType: stable

- task: PowerShell@2
  displayName: 'Build AL application'
  inputs:
    targetType: filePath
    filePath: 'CompileApp.ps1'
    workingDirectory: '$(Build.SourcesDirectory)'
            
- task: PublishBuildArtifacts@1
  inputs:
    pathtoPublish: '$(Build.StagingDirectory)'
    artifactName: Artifacts

CompileApp.ps1

Create power shell script for compiling app

Source code:

#install bccontainerhelper
Write-Host "##[command]Installing BcContainerHelper"
Install-Module -Name bccontainerhelper -Force
$module = Get-InstalledModule -Name bccontainerhelper -ErrorAction Ignore
$versionStr = $module.Version.ToString()
Write-Host "##[section]BcContainerHelper $VersionStr installed"
#install bccontainerhelper

#creating container
$RepositoryDirectory = Get-Location

$ContainerName = 'Sandbox'
$password = ConvertTo-SecureString 'SecurePassword123$' -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ('admin', $password)

$artifactUrl = Get-BCArtifactUrl -country at -select Latest -storageAccount bcartifacts -type Sandbox

$AdditionalParameters = @()
$AdditionalParameters += '--volume "{0}:{1}"' -f $RepositoryDirectory, 'c:\sources'

$Params = @{}
$Params += @{ accept_eula = $true }
$Params += @{ artifactUrl = $artifactUrl }
$Params += @{ containerName = $ContainerName }
$Params += @{ auth = 'NavUserPassword' }
$Params += @{ credential = $Credential }
$Params += @{ isolation = 'process' }
$Params += @{ accept_outdated = $true }
$Params += @{ useBestContainerOS = $true }
$Params += @{ additionalParameters = $AdditionalParameters }

New-BcContainer @Params -shortcuts None
#creating container

#increase app version
$app = (Get-Content "app.json" -Encoding UTF8 | ConvertFrom-Json)
$existingVersion = $app.version -as [version]
$versionBuild = Get-Date -Format "yyyyMMdd"
$versionRevision = Get-Date -Format "HHmmss"
$nextVersion = [version]::new($existingVersion.Major, $existingVersion.Minor, $versionBuild, $versionRevision)
$app.version = "$nextVersion"
$app | ConvertTo-Json | Set-Content app.json
write-host "##[section]Version increased to $nextVersion"
#increase app version

#compile app
write-host "##[command]Compiling app" $app.Name $app.Version
Compile-AppInBcContainer -appProjectFolder $RepositoryDirectory -containerName $ContainerName -credential $Credential -GenerateReportLayout Yes -ReportSuppressedDiagnostics
#compile app

#copy app to build staging directory
write-host "##[section]Moving app to build staging directory"
Copy-Item -Path (Join-Path $RepositoryDirectory -ChildPath("\output\" + $app.publisher + "_" + $app.Name + "_" + $app.Version + ".app")) -Destination $env:Build_StagingDirectory
Copy-Item -Path (Join-Path $RepositoryDirectory -ChildPath("PublishApp.ps1")) -Destination $env:Build_StagingDirectory
write-host "##[section]Staging directory $env:Build_StagingDirectory"
#copy app to build staging directory

#updating build pipeline number
Write-Host "##vso[build.updatebuildnumber]$nextVersion"
#updating build pipeline number

Build pipeline of your app

  • Pipelines -> New pipeline
  • Azure Repos Git
  • Select repository
  • Existing Azure Pipelines YAML file
  • Select CICD.yml

Building App

 

After every push/pull request to defined branches in CICD.yml build pipeline is triggered

and artifacts is ready to use in release pipeline


Conclusion

This blog post has demonstrated how a build pipeline on Azure DevOps can be utilized to build applications for Microsoft Dynamics 365 Business Central using the Microsoft Hosted Agent. The next post will provide an explanation of how artifacts from the build pipeline can be used, including creating a Release for Sandbox and Production environments.



Add comment

Comments

There are no comments yet.