Not able to get Run-AlValidation to work with main and library app
I tried to validate a new release against latest 18 and current 17 builds for some hours now. I always get the following error for library and the main app:
AppSourceCop.json(1,1): error AS0003: The version '16.0.6.36' of the extension with publisher 'EvilCompany' and name 'Evil Library App' could not be found in the baseline package cache folder. If you do not want to validate breaking changes, remove the property 'version' from the AppSourceCop.json.
I have confirmed, that the previous apps are in the folder /packagecachepath and also confirmed, that the path is accessible from host and container.
I am lost now. Any idea or suggestions?
Scripts used to create container and cause the issue
Run-AlValidation `
-containerName 'myApp' `
-licenseFile "$licenseFile `
-credential $containerCredential `
-validateCurrent `
-sasToken "***" `
-affixes "EVL" `
-countries 'de' `
-previousApps $previousApps `
-apps $apps;
Full output of scripts
Container name myApp
Image name
Credential Specified
License file Specified
MemoryLimit 8G
validateVersion
validateCurrent True
validateNextMinor False
validateNextMajor False
SasToken Specified
countries de
validateCountries de
affixes EVL
supportedCountries
vsixFile
Install Apps
- None
Previous Apps
- C:\Temp\AlPipeline\previousApps\EvilCompany_Evil Main App_16.0.1.27.app
- C:\Temp\AlPipeline\previousApps\EvilCompany_Evil Library App_16.0.6.36.app
Apps
- C:\Temp\AlPipeline\apps\EvilCompany_Evil Main App_17.0.21032301.0.app
- C:\Temp\AlPipeline\apps\EvilCompany Evil Library App 17.0.21030301.21032301.app
PULLING GENERIC IMAGE
Pulling mcr.microsoft.com/businesscentral:10.0.19042.867
Pulling generic image took 1 seconds
DETERMINE ARTIFACTS
Found https://bcartifacts.azureedge.net/sandbox/17.5.22499.23535/de
Using https://bcartifacts.azureedge.net/sandbox/17.5.22499.23535/de
CREATING CONTAINER
Creating container for country de
BcContainerHelper is version 2.0.7
BcContainerHelper is running as administrator
Host is Microsoft Windows 10 Enterprise - 20H2
Docker Client Version is 19.03.14
Docker Server Version is 19.03.14
Downloading application artifact /sandbox/17.5.22499.23535/de
Downloading C:\Temp\User\6f397036-3805-4514-984d-cef1603ff420.zip
Unpacking application artifact to tmp folder using 7zip
Downloading platform artifact /sandbox/17.5.22499.23535/platform
Downloading C:\Temp\User\bfcd0331-23c6-4f6e-a629-eb9cb4b51467.zip
Unpacking platform artifact to tmp folder using 7zip
Downloading Prerequisite Components
Downloading c:\bcartifacts.cache\sandbox\17.5.22499.23535\platform\Prerequisite Components\Open XML SDK 2.5 for Microsoft Office\OpenXMLSDKv25.msi
Downloading c:\bcartifacts.cache\sandbox\17.5.22499.23535\platform\Prerequisite Components\IIS URL Rewrite Module\rewrite_2.0_rtw_x64.msi
Downloading c:\bcartifacts.cache\sandbox\17.5.22499.23535\platform\Prerequisite Components\DotNetCore\DotNetCore.1.0.4_1.1.1-WindowsHosting.exe
Fetching all docker images
Fetching all docker volumes
Using image mcr.microsoft.com/businesscentral:10.0.19042.867
Creating Container myApp
Version: 17.5.22499.23535-DE
Style: sandbox
Multitenant: No
Platform: 17.0.22463.23443
Generic Tag: 1.0.1.4
Container OS Version: 10.0.19042.867 (20H2)
Host OS Version: 10.0.19042.867 (20H2)
Using process isolation
Using locale de-DE
Disabling the standard eventlog dump to container log every 2 seconds (use -dumpEventLog to enable)
Using license file C:\EvilCompany\License\DemoDev_BC17.flf
Additional Parameters:
--env customNavSettings=EnableTaskScheduler=True
Files in C:\ProgramData\BcContainerHelper\Extensions\myApp\my:
- AdditionalOutput.ps1
- license.flf
- MainLoop.ps1
- SetupVariables.ps1
- updatehosts.ps1
Creating container myApp from image mcr.microsoft.com/businesscentral:10.0.19042.867
d310ad3b0917e7d97587881e51a70b8514c2370a9e524d0bb9cda3de7f5d8868
Waiting for container myApp to be ready
Using artifactUrl https://bcartifacts.azureedge.net/sandbox/17.5.22499.23535/de
Using installer from C:\Run\150-new
Installing Business Central
Installing from artifacts
Starting Local SQL Server
Starting Internet Information Server
Copying Service Tier Files
Copying PowerShell Scripts
Copying dependencies
Copying ReportBuilder
Importing PowerShell Modules
Determining Database Collation from c:\dl\sandbox\17.5.22499.23535\de\BusinessCentral-DE.bak
Restoring CRONUS Demo Database
Setting CompatibilityLevel for CRONUS on localhost\SQLEXPRESS
Modifying Business Central Service Tier Config File for Docker
Creating Business Central Service Tier
Installing SIP crypto provider: 'C:\Windows\System32\NavSip.dll'
Copying Web Client Files
Copying Client Files
Copying ModernDev Files
Copying additional files
Copying ConfigurationPackages
Copying Test Assemblies
Copying Extensions
Copying Applications
Copying Applications.DE
Starting Business Central Service Tier
Importing license file
Stopping Business Central Service Tier
Installation took 118 seconds
Installation complete
Initializing...
Setting host.containerhelper.internal to 172.22.208.1 in container hosts file
Starting Container
Hostname is myApp
PublicDnsName is myApp
Using NavUserPassword Authentication
Creating Self Signed Certificate
Self Signed Certificate Thumbprint 2EFC433733E6F03E0B29D12D57CB7908C24262FC
Modifying Service Tier Config File with Instance Specific Settings
Modifying Service Tier Config File with settings from environment variable
Setting EnableTaskScheduler to True
Starting Service Tier
Registering event sources
Creating DotNetCore Web Server Instance
Enabling Financials User Experience
Using license file 'c:\run\my\license.flf'
Import License
Creating http download site
Setting SA Password and enabling SA
Creating admin as SQL User and add to sysadmin
Creating SUPER user
WARNING: The password that you entered does not meet the minimum requirements.
It should be at least 8 characters long and contain at least one uppercase
letter, one lowercase letter, and one number.
Container IP Address: 172.22.210.94
Container Hostname : myApp
Container Dns Name : myApp
Web Client : http://myApp/BC/
Dev. Server : http://myApp
Dev. ServerInstance : BC
Setting myApp to 172.22.210.94 in host hosts file
Files:
http://myApp:8080/ALLanguage.vsix
Container Total Physical Memory is 31.8Gb
Container Free Physical Memory is 13.5Gb
Initialization took 50 seconds
Ready for connections!
Reading CustomSettings.config from myApp
Creating Desktop Shortcuts for myApp
Container myApp successfully created
Use:
Get-BcContainerEventLog -containerName myApp to retrieve a snapshot of the event log from the container
Get-BcContainerDebugInfo -containerName myApp to get debug information about the container
Enter-BcContainer -containerName myApp to open a PowerShell prompt inside the container
Remove-BcContainer -containerName myApp to remove the container again
docker logs myApp to retrieve information about URL's again
Creating container took 301 seconds
RUNNING APPSOURCECOP
Copying previous apps to packages folder
Extracting C:\ProgramData\BcContainerHelper\c5d9cf28-3539-4146-8ec9-217aed54fb2d\EvilCompany_Evil Library App_16.0.6.36.app
EvilCompany_Evil Library App = 16.0.6.36
Extracting C:\ProgramData\BcContainerHelper\c5d9cf28-3539-4146-8ec9-217aed54fb2d\EvilCompany_Evil Main App_16.0.1.27.app
EvilCompany_Evil Main App = 16.0.1.27
Extracting C:\ProgramData\BcContainerHelper\a66e332c-18fd-42d4-a80d-7159c20828af\EvilCompany Evil Library App 17.0.21030301.21032301.app
Analyzing: EvilCompany Evil Library App 17.0.21030301.21032301.app
Using affixes: EVL
Using previous app: EvilCompany_Evil Library App_16.0.6.36.app
Downloading C:\ProgramData\BcContainerHelper\e4c03860-c30c-45f3-8fd2-3e3ac351a8c1\appsource.default.ruleset.json
AppSourceCop.json content:
{
"Publisher": "EvilCompany",
"Name": "Evil Library App",
"mandatoryAffixes": [
"EVL"
],
"Version": "16.0.6.36"
}
Ruleset.json content:
{
"name": "Run-AlCops RuleSet",
"description": "Generated by Run-AlCops",
"includedRuleSets": [
{
"path": "C:\\ProgramData\\BcContainerHelper\\e4c03860-c30c-45f3-8fd2-3e3ac351a8c1\\appsource.default.ruleset.json",
"action": "Default"
}
]
}
Using Symbols Folder: C:\ProgramData\BcContainerHelper\c5d9cf28-3539-4146-8ec9-217aed54fb2d
Copying System.app from Container
Copying Microsoft_Application_17.5.22499.23535.app from Container
Copying Microsoft_Base Application_17.5.22499.23535.app from Container
Copying Microsoft_System Application_17.5.22499.23535.app from Container
Compiling...
.\alc.exe /project:"C:\ProgramData\BcContainerHelper\e4c03860-c30c-45f3-8fd2-3e3ac351a8c1" /packagecachepath:"C:\ProgramData\BcContainerHelper\c5d9cf28-3539-4146-8ec9-217aed54fb2d" /out:"C:\ProgramData\BcContainerHelper\e4c03860-c30c-45f3-8fd2-3e3ac3
51a8c1\EvilCompany_Evil Library App_17.0.21030301.21032301.app" /analyzer:C:\build\vsix\extension\bin\Analyzers\Microsoft.Dynamics.Nav.AppSourceCop.dll /ruleset:C:\ProgramData\BcContainerHelper\e4c03860-c30c-45f3-8fd2-3e3ac351a8c1\ruleset
.json /assemblyprobingpaths:"C:\Program Files (x86)\Microsoft Dynamics NAV\170\RoleTailored Client","C:\Program Files\Microsoft Dynamics NAV\170\Service","C:\Program Files (x86)\Open XML SDK\V2.5\lib","c:\Windows\Microsoft.NET\Assembly","C:\Test Assemblies\Mock Assemblies"
Microsoft (R) AL Compiler version 6.5.6.33494
Copyright (C) Microsoft Corporation. All rights reserved
Compilation started for project 'Evil Library App' containing '59' files at '13:43:19.283'.
[WARNINGS REMOVED]
C:\ProgramData\BcContainerHelper\e4c03860-c30c-45f3-8fd2-3e3ac351a8c1\AppSourceCop.json(1,1): error AS0003: The version '16.0.6.36' of the extension with publisher 'EvilCompany' and name 'Evil Library App' could not be found in the baseline package cache folder. If you do not want to validate breaking changes, remove the property 'version' from the AppSourceCop.json.
Additional context
This happens independent of the BC build. Never tested it before.
Looks like a bug
could you create a .zip file with the files (C:TempAlPipeline), and email me a secure URL where I can download the zip file.
Then I can run a repro and find the issue and either fix it.
I have a repro of this that I have given to the moderndev team - I don't think this is a docker issue.
Stay tuned.
This was also my impression, as the paths passed to alc seem to be correct. Let's see.
We have found that this was a bug in the compiler when creating the baseline apps.
More precisely, the version number in the manifest and the symbolreference inside the .app file doesn't match.
This code will extract the app, fix the issue and write the app in a new name.
$path = "C:\ProgramData\BcContainerHelper\previousApps\appname.app"
Invoke-ScriptInBCContainer -containerName $containerName -scriptBlock { Param($path, $destination)
add-type -path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service\system.io.packaging.dll").FullName
$memoryStream = $null
$fs = $null
try {
$fs = [System.IO.File]::OpenRead($Path)
$binaryReader = [System.IO.BinaryReader]::new($fs)
$magicNumber1 = $binaryReader.ReadUInt32()
$metadataSize = $binaryReader.ReadUInt32()
$metadataVersion = $binaryReader.ReadUInt32()
$packageId = [Guid]::new($binaryReader.ReadBytes(16))
$contentLength = $binaryReader.ReadInt64()
$magicNumber2 = $binaryReader.ReadUInt32()
if ($magicNumber1 -ne 0x5856414E -or
$magicNumber2 -ne 0x5856414E -or
$metadataVersion -gt 2 -or
$fs.Position + $contentLength -gt $fs.Length)
{
throw "Unsupported package format"
}
$memoryStream = [System.IO.MemoryStream]::new()
$fs.Seek($metadataSize, [System.IO.SeekOrigin]::Begin) | Out-Null
$fs.CopyTo($memoryStream)
$memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
$memoryStream.SetLength($contentLength)
$fs.Close()
$fs.Dispose()
$fs = $null
$changes = $false
$package = [System.IO.Packaging.Package]::Open($memoryStream, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
$manifestPart = $package.GetPart('/NavxManifest.xml')
$manifest = [xml]([System.IO.StreamReader]::new($manifestPart.GetStream())).ReadToEnd()
$symbolReferencePart = $package.GetPart('/SymbolReference.json')
$symbolReference = ([System.IO.StreamReader]::new($symbolReferencePart.GetStream())).ReadToEnd() | ConvertFrom-Json
if ($symbolReference.Version -ne $manifest.package.app.version) {
$symbolReference.version = $manifest.package.app.version
$changes = $true
}
if ($changes) {
$partStream = $symbolReferencePart.GetStream([System.IO.FileMode]::Create)
$sw = New-Object System.IO.StreamWriter -argumentList $partStream
$sw.Write(($symbolReference | ConvertTo-Json -Depth 99))
$partStream.Flush()
$package.Close()
$fs = [System.IO.FileStream]::new($Destination, [System.IO.FileMode]::Create)
$binaryWriter = [System.IO.BinaryWriter]::new($fs)
$binaryWriter.Write([UInt32](0x5856414E))
$binaryWriter.Write([UInt32](40))
$binaryWriter.Write([UInt32](2))
$binaryWriter.Write($packageId.ToByteArray())
$binaryWriter.Write([UInt64]($memoryStream.Length))
$binaryWriter.Write([UInt32](0x5856414E))
$memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
$memoryStream.CopyTo($fs)
$fs.Close()
$fs.Dispose()
$fs = $null
}
else {
if ($Path -ne $Destination) {
Copy-Item -Path $Path -Destination $Destination -Force
}
}
}
finally {
if ($fs) {
$fs.Close()
}
}
} -argumentList (Get-BCContainerPath -containerName $containerName -path $path -throw), (Get-BCContainerPath -containerName $containerName -path $path.Replace('.app','.new.app') -throw)
It works like a charm. I needed to update the script to work outside of a container, because of a "docker inspect" issue. Attaching my version.
function Invoke-BcSymbolVersionFix
{
param
(
[Parameter(Mandatory = $true)]
[System.IO.FileInfo]$path,
[System.IO.FileInfo]$destination = $path.FullName.Replace('.app','.fixed.app')
)
begin
{
$systemIoPackagingDll = Get-Item -Path "$($env:USERPROFILE)\.vscode\extensions\ms-dynamics-smb.al-*\bin\System.IO.Packaging.dll";
if (!$systemIoPackagingDll)
{
throw "VSCode AL Language Extension and/or System.IO.Packaging.dll not found.";
}
$memoryStream = $null
$fs = $null
Add-Type -Path $systemIoPackagingDll.FullName;
try
{
$fs = [System.IO.File]::OpenRead($path);
$binaryReader = [System.IO.BinaryReader]::new($fs);
$magicNumber1 = $binaryReader.ReadUInt32();
$metadataSize = $binaryReader.ReadUInt32();
$metadataVersion = $binaryReader.ReadUInt32();
$packageId = [Guid]::new($binaryReader.ReadBytes(16));
$contentLength = $binaryReader.ReadInt64();
$magicNumber2 = $binaryReader.ReadUInt32();
if (($magicNumber1 -ne 0x5856414e) -or ($magicNumber2 -ne 0x5856414e) -or ($metadataVersion -gt 2) -or (($fs.Position + $contentLength) -gt $fs.Length))
{
throw "File $($path) has an unsopported package format.";
}
$memoryStream = [System.IO.MemoryStream]::new();
$fs.Seek($metadataSize, [System.IO.SeekOrigin]::Begin) | Out-Null;
$fs.CopyTo($memoryStream);
$memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;
$memoryStream.SetLength($contentLength);
}
finally
{
if ($fs)
{
$fs.Close();
$fs.Dispose();
$fs = $null;
}
}
}
process
{
try
{
$package = [System.IO.Packaging.Package]::Open($memoryStream, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite);
$manifestPart = $package.GetPart('/NavxManifest.xml');
$manifest = [xml]([System.IO.StreamReader]::new($manifestPart.GetStream())).ReadToEnd();
$symbolReferencePart = $package.GetPart('/SymbolReference.json');
$symbolReference = ([System.IO.StreamReader]::new($symbolReferencePart.GetStream())).ReadToEnd() | ConvertFrom-Json;
if ($symbolReference.Version -ne $manifest.package.app.version) {
$symbolReference.version = $manifest.package.app.version;
$partStream = $symbolReferencePart.GetStream([System.IO.FileMode]::Create);
$sw = New-Object System.IO.StreamWriter -argumentList $partStream;
$sw.Write(($symbolReference | ConvertTo-Json -Depth 99));
$partStream.Flush();
$package.Close();
$fs = [System.IO.FileStream]::new($destination, [System.IO.FileMode]::Create);
$binaryWriter = [System.IO.BinaryWriter]::new($fs);
$binaryWriter.Write([UInt32](0x5856414e));
$binaryWriter.Write([UInt32](40));
$binaryWriter.Write([UInt32](2));
$binaryWriter.Write($packageId.ToByteArray());
$binaryWriter.Write([UInt64]($memoryStream.Length));
$binaryWriter.Write([UInt32](0x5856414e));
$memoryStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;
$memoryStream.CopyTo($fs);
}
else
{
if ($path -ne $destination)
{
Copy-Item -Path $path -Destination $destination -Force;
}
}
}
finally
{
if ($fs)
{
$fs.Close();
$fs.Dispose();
$fs = $null;
}
}
}
}
Tak Freddy for din perfekte og hurtige hj忙lp!
Most helpful comment
We have found that this was a bug in the compiler when creating the baseline apps.
More precisely, the version number in the manifest and the symbolreference inside the .app file doesn't match.
This code will extract the app, fix the issue and write the app in a new name.