Are you tired of the confusing of manual downloads, half-baked scripts, and undocumented requirements every time you need to build a Business Central AL extension? Same.
That’s why I built BCBuildTasks — a clean, pipeline-native Azure DevOps extension that does the hard stuff for you.
- AL compiler? Downloaded.
- Dependencies? Handled.
- Build
.app
? Wrapped. - Documentation? Actually exists and is up to date!
Let me show you how it works — and how to use it.
What Is BCBuildTasks?
BCBuildTasks is an Azure DevOps extension for building AL projects for Dynamics 365 Business Central.
It:
- Uses PowerShell under the hood (because it actually works)
- Uses some Javascript under the hood (because Microsoft, for some reason)
- Integrates with pipeline variables and Azure secrets
- Authenticates with Business Central via Microsoft Entra
- Compiles your extension using the latest AL compiler (by default) or a selected compiler version
Note: It’s Windows-agent only. That’s Microsoft’s fault, not mine. For now, at least...
Tasks Included
Here’s what you get:
Get AL Compiler
Downloads the latest (or a specific version) AL VSIX, unpacks it, and sets up your build agent with alc.exe
.
Get AL Dependencies
Authenticates to your BC sandbox and downloads all .app
dependencies defined in app.json
.
Build AL Package
Wraps alc.exe
with all the folder and versioning logic you shouldn’t have to think about.
Get List of Companies
Gets a list of the companies in the Business Central tenant.
Get List of Modules
Gets a list of modules installed on the Business Central tenant, with the ability to exclude Microsoft modules.
Publish
(experimental)
Actually publishes the module on the target Business Central tenant (for PTEs.) Note this is currently experimental because this is a really finicky routine...
Authentication: You Need Entra
To use this extension, you need to register an app in Microsoft Entra (formerly Azure AD). Why? Because the BC APIs won’t talk to your pipeline without it.
You’ll need:
TenantId
ClientId
ClientSecret
- Permissions to
API.ReadWrite.All
on Business Central (to compile) - Permissions to
API.Automation.All
on Business Central (to deploy) - Admin consent (yes, that button that always gets skipped)
Sample Pipeline
- task: EGGetALCompiler@0
displayName: "Get AL compiler"
inputs:
DownloadDirectory: $(Build.SourcesDirectory)\compiler
Version: 'latest'
ExpansionDirectory: 'expanded'
- task: EGGetALDependencies@0
displayName: "Get AL dependencies"
inputs:
ClientId: "<your client id>"
ClientSecret: "<your client secret>"
EnvironmentName: '<your environment name>'
PathToAppJson: $(Build.SourcesDirectory)\CodeModule
PathToPackagesDirectory: $(Build.SourcesDirectory)\.alpackages
TenantId: "<your tenant id>"
- task: EGBuildALPackage@0
displayName: "Compile AL package"
inputs:
ALEXEPathFolder: $(Build.SourcesDirectory)/compiler/expanded/extension/bin/win32/alc.exe
EntireAppName: "TestApp.1.1.1.app"
OutAppFolder: $(Build.ArtifactStagingDirectory)
PackageCachePath: $(Build.SourcesDirectory)\.alpackages
ProjectPath: $(Build.SourcesDirectory)\CodeModule
- task: PublishBuildArtifacts@1
displayName: "Publish artifact"
inputs:
ArtifactName: "drop"
PathtoPublish: $(Build.ArtifactStagingDirectory)
- task: EGDeployBCModule@0
displayName: "Deploy module to Business Central"
inputs:
TenantId: "<target tenant id>"
EnvironmentName: "<target environment name>"
ClientId: "<target-capable client id>"
ClientSecret: "<target-capable client secret>"
CompanyId: "<company id>"
AppFilePath: "$(Build.ArtifactStagingDirectory)\\TestApp.1.1.1.app"
- task: EGGetBCCompanies@0
displayName: "Getting list of companies"
inputs:
TenantId: "<target tenant id>"
EnvironmentName: "<target environment name>"
ClientId: "<target-capable client id>"
ClientSecret: "<target-capable client secret>"
- task: EGGetBCModules@0
displayName: "Getting list of modules installed"
inputs:
TenantId: "<target tenant id>"
EnvironmentName: "<target environment name>"
ClientId: "<target-capable client id>"
ClientSecret: "<target-capable client secret>"
CompanyId: "<company id>"
Pro Tips (for Dummies)
- Store secrets in Azure Pipelines Library → Variable Groups
- To that end, you can even integrate Azure Key Vault onto your variable groups, but that's beyond scope of this document
- Use a dedicated Entra app per environment
- Don’t check secrets into appsettings.json — seriously
- Pin the AL compiler version if you don’t trust Microsoft’s “latest”
Full Docs
The github repo is at: GitHub repo
Included are:
- Screenshots of the entire required Entra and Business Central configuration
- Detailed task input/output reference
- License and support info
Problems?
I'd say best bet is open a GitHub issue. This is an ongoing side project so I intend to keep it up to date for a bit...
Wanna Know How it Was Done?
Feel free to ask, again using a GitHub issue.