Modules/businessdev.ALbuild.Apps/Public/Invoke-BcValidation.ps1

function Invoke-BcValidation {
    <#
    .SYNOPSIS
        Validates an AL app by compiling it against one or more Business Central versions (licensed).
 
    .DESCRIPTION
        For each target Business Central artifact, creates a temporary container, compiles the app
        (optionally with analyzers/ruleset such as AppSourceCop for AppSource submissions), records
        the outcome, and removes the container. This catches version-compatibility and analyzer
        issues before submission. A valid ALbuild license is required.
 
        Symbols are expected in the project's .alpackages (resolve them first with
        Resolve-BcDependencies). Analyzer assemblies must be passed by path via -Analyzer.
 
    .PARAMETER ProjectFolder
        The AL project folder.
 
    .PARAMETER ArtifactUrl
        Explicit artifact URLs to validate against. If omitted, -Select determines them.
 
    .PARAMETER Country
        Country for artifact resolution. Default 'w1'.
 
    .PARAMETER Select
        Artifact selectors to validate against when -ArtifactUrl is omitted (Current/NextMinor/NextMajor).
 
    .PARAMETER Credential
        Container admin credential.
 
    .PARAMETER Analyzer
        Analyzer assembly paths (e.g. AppSourceCop.dll).
 
    .PARAMETER RuleSet
        Ruleset file.
 
    .PARAMETER DockerExecutable
        The Docker executable to use (default 'docker').
 
    .OUTPUTS
        PSCustomObject with Success and per-version Results.
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ProjectFolder,
        [string[]] $ArtifactUrl,
        [string] $Country = 'w1',
        [ValidateSet('Current', 'NextMinor', 'NextMajor')] [string[]] $Select = @('Current'),
        [pscredential] $Credential,
        [string[]] $Analyzer = @(),
        [string] $RuleSet,
        [string] $DockerExecutable = 'docker'
    )

    Assert-ALbuildLicensed -Feature 'Validation'
    Test-BcPlatform -Require | Out-Null

    $urls = @($ArtifactUrl)
    if (-not $urls -or $urls.Count -eq 0) {
        $urls = foreach ($selector in $Select) {
            Find-BcArtifactUrl -Country $Country -Select $selector -AcceptInsiderEula:($selector -ne 'Current')
        }
        $urls = @($urls | Where-Object { $_ })
    }
    if (-not $urls -or $urls.Count -eq 0) { throw 'No artifacts to validate against were resolved.' }

    $results = @()
    foreach ($url in $urls) {
        $containerName = "albuild-val-$([guid]::NewGuid().ToString('N').Substring(0, 8))"
        Write-ALbuildLog "Validating against $url ..."
        try {
            New-BcContainer -Name $containerName -ArtifactUrl $url -Credential $Credential -DockerExecutable $DockerExecutable | Out-Null
            $compile = Invoke-BcCompiler -ProjectFolder $ProjectFolder -Engine Container -ContainerName $containerName `
                -Analyzer $Analyzer -RuleSet $RuleSet -DockerExecutable $DockerExecutable
            $results += [PSCustomObject]@{ ArtifactUrl = $url; Success = $compile.Success; ExitCode = $compile.ExitCode }
        }
        catch {
            $results += [PSCustomObject]@{ ArtifactUrl = $url; Success = $false; ExitCode = -1; Error = $_.Exception.Message }
        }
        finally {
            Remove-BcContainer -Name $containerName -DockerExecutable $DockerExecutable -Confirm:$false -ErrorAction SilentlyContinue
        }
    }

    $allOk = @($results | Where-Object { -not $_.Success }).Count -eq 0
    if ($allOk) { Write-ALbuildLog -Level Success "Validation passed for all $($results.Count) version(s)." }
    else { Write-ALbuildLog -Level Error 'Validation failed for one or more versions.' }

    return [PSCustomObject]@{ Success = $allOk; Results = $results }
}