ALC.EXE output formatting for TFS/VSTS

Hi all,

I am sure that you are right now working on some build system for your Dynamics 365 Business Central App. May be you already solved how to get the vsix from container, how to unpack it to have alc.exe. How to run alc.exe which will "compile" the app from the sources (and you found out that there is /packagecachepath parameter in alc.exe). And now, you have put this into some scripts and you are running it from TFS build agent. 

Because alc.exe will put all output to standard output stream, you will see it in the TFS console, but if there is some error, it will fail just because alc.exe ends with return code <> 0. But you want to see the errors/warnings like if it another standard compile tool. 

No problem!

You can use the TFS Logging command, which are GREAT tools to do something during the build by just outputting command to console. See https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md.

By "filtering" the output of ALC.exe you can easilly format the output as you wish. There is my function to format it:

function Convert-ALCOutputToTFS {
    foreach ($_ in $input) {
        switch -regex ($_) {
            "^warning (\w{2}\d{4}):(.*('.*').*|.*)$" {
                if (Test-Path $Matches[3]) {
                    Write-Host "##vso[task.logissue type=warning;sourcepath=$($Matches[3]);code=$($Matches[1]);]$($Matches[2])"
                } else {
                    Write-Host "##vso[task.logissue type=warning;code=$($Matches[1]);]$($Matches[2])"
                }

            }
            "^(.*)\((\d+),(\d+)\): error (\w{2}\d{4}): (.*)$"
            #Objects\codeunit\Cod50130.NRMGetInfoCommand.al(62,30): error AL0118: The name '"Parent Object"' does not exist in the current context        
            {
                Write-Host "##vso[task.logissue type=error;sourcepath=$($Matches[1]);linenumber=$($Matches[2]);columnnumber=$($Matches[3]);code=$($Matches[4]);]$($Matches[5])"
            }
            "^(.*)\((\d+),(\d+)\): warning (\w{2}\d{4}): (.*)$"
            #Prepared for unified warning format
            #Objects\codeunit\Cod50130.NRMGetInfoCommand.al(62,30): warning AL0118: The name '"Parent Object"' does not exist in the current context        
            {
                Write-Host "##vso[task.logissue type=warning;sourcepath=$($Matches[1]);linenumber=$($Matches[2]);columnnumber=$($Matches[3]);code=$($Matches[4]);]$($Matches[5])"
            }
            default {
                Write-Host $_
            }
        }
    }
}

You can use it like this:

& $ALC --% /project:.\ /packagecachepath:.\.alpackages | Convert-ALCOutputToTFS

And your build will have the errors and warnings like from other languages!

Feel free to use other logging commands to e.g. attach files, log details, set variables, change build name, add tags to the build etc.

Thanks the ALC.EXE I was able to create Branch policy in TFS allowing to merge Pull Request only when the result is successfully compiled. Whole compilation takes around 2-4 minutes, depending on how fast the container is started (when downloading image, it takes more).

Anonymous