Timeline Azure DevOps Integration #144
Replies: 3 comments 1 reply
|
To be honest, I am still considering how best to align the TFM with the AL compiler. At the moment, starting with AL Language v16.0 the compiler targets My initial idea was to determine the matching TFM automatically from the Business Central artifact URL used in the pipeline. However, scenarios such as the ALOps App Compiler v3 now rely on the Business Central DevTools distributed through NuGet rather than BC artifacts. At the moment I see three relevant scenarios: A) Compiling inside a Docker container using Business Central artifacts In all three cases the correct TFM can be derived if the package type and version are known. The remaining question is how to implement this detection cleanly within an Azure DevOps extension. If anyone has experience with similar setups or ideas on how this could be approached, suggestions would be appreciated.
|
|
Hi @Arthurvdv, I'm not sure if I can help here, but since you asked for input, I can tell you what I played around with last year to match the LinterCop version to the actual BC version. I think the missing part is how to get the actual compiler version. I did the following steps:
I think this could also work for your points A) and B) Here is the script I created for this. Maybe it can help. # Define necessary variables
$workDir = "C:\temp"
$artifactCountry = "de"
$artifactType = "Sandbox"
$artifactVersion = "25"
# Get Artifact URL
$command = "Get-BCArtifactUrl"
$arguments = @("-type", $artifactType, "-country", $artifactCountry, "-version", $artifactVersion, "-select", "Latest")
$argumentString = $arguments -join " "
Write-Host "Invoke-Expression: $command $argumentString"
$artifactUrl = Invoke-Expression "$command $argumentString"
Write-Host "Artifact URL: $artifactUrl"
# Download Artifact
Download-Artifacts -artifactUrl $artifactUrl -includePlatform -basePath "C:\bcartifacts.cache"
$urlParts = $artifactUrl -split "/"
$typePart = $urlParts | Where-Object { $_ -match "onprem|sandbox" }
$version = $urlParts[$urlParts.IndexOf($typePart) + 1]
$artifactPath = Get-ChildItem -Path "C:\bcartifacts.cache\$typePart" -Filter "$version" -Recurse | Select-Object -First 1
Write-Host "Artifact Downloaded to $($artifactPath.FullName)"
# Search for vsix file
$vsixFile = Get-ChildItem -Path $artifactPath.FullName -Filter "*.vsix" -Recurse | Select-Object -First 1
Write-Host "Vsix File: $($vsixFile.FullName)"
# Copy vsix file to working directory
$alcZipPath = "$workDir\alc.zip"
Copy-Item -Path $vsixFile.FullName -Destination $alcZipPath
# Define the alc directory path
$alcDirPath = "$workDir\alc"
# Check if alc directory already exists
if (-Not (Test-Path -Path $alcDirPath)) {
# Extract alc.exe from vsix file only if alc directory does not exist
New-Item -Path $alcDirPath -ItemType Directory -Force
Expand-Archive -Path $alcZipPath -DestinationPath $alcDirPath -Force
Write-Host "Extracted $alcZipPath to $alcDirPath"
}
else {
Write-Host "ALC directory already exists. Skipping extraction."
}
# Define the path to alc.exe
$compilerPath = "$alcDirPath\extension\bin\alc.exe"
# Read package.json to get the version
$packageJsonPath = "$alcDirPath\extension\package.json"
$packageJson = Get-Content -Path $packageJsonPath | ConvertFrom-Json
$alVersion = $packageJson.version
Write-Host "AL Version: $alVersion"
# Define the base directory for LinterCop DLLs
$linterCopBaseDir = "$workDir\lintercop"
# Get the highest version directory
$highestVersionDir = Get-ChildItem -Path $linterCopBaseDir -Directory | Where-Object { $_.Name -notmatch "-prerelease$|-draft$" } | Sort-Object -Property Name -Descending | Select-Object -First 1
if ($highestVersionDir) {
Write-Host "Highest version directory: $($highestVersionDir.FullName)"
# Extract major and minor version from AL version
$alMajorMinorVersion = $alVersion.Split('.')[0..1] -join '.'
# Get all LinterCop DLLs in the highest version directory
$linterCopDlls = Get-ChildItem -Path $highestVersionDir.FullName -Filter "BusinessCentral.LinterCop.AL-*.dll"
# Filter DLLs by major and minor version
$filteredDlls = $linterCopDlls | Where-Object { $_.Name -match "BusinessCentral.LinterCop.AL-$alMajorMinorVersion" }
if ($filteredDlls.Count -gt 0) {
# Sort by version and select the highest
$selectedDll = $filteredDlls | Sort-Object { [version]($_.Name -replace 'BusinessCentral.LinterCop.AL-', '' -replace '\.dll$', '') } -Descending | Select-Object -First 1
Write-Host "Found LinterCop DLL: $($selectedDll.FullName)"
}
else {
Write-Host "No matching LinterCop DLL found for AL version $alMajorMinorVersion."
}
}
else {
Write-Host "No version directories found in $linterCopBaseDir."
}
|
|
Good news! I now have a working solution for Azure DevOps, see details on https://alcops.dev/docs/getting-started/cicd/azure-devops. The challenge for me was keeping the solution as generic as possible so it can fit into the wide range of Azure DevOps setups out there. I think I've achieved this, but could use your help to confirm whether this holds up across different pipeline setups. As this is a first release, there may still be issues or bugs. Feedback is very welcome and best place is on the repo: https://github.com/ALCops/azure-devops-extension I still need to look into the compatibility with existing tooling such as ALOps, Alpaca and maybe others. Ideas or experience integrating with these would be helpful. I'll try to add some more examples on https://dev.azure.com/Arthurvdv/ALCops/_build. |
Uh oh!
There was an error while loading. Please reload this page.
Hi @Arthurvdv,
thanks for all the effort you put into the linter cop and now this project. Is there any timeline for the Azure DevOps integration? It only says "Coming Soon". Is there any way to contribute here?
https://alcops.dev/docs/getting-started/cicd/azure-devops/
All reactions