Publish/Publish-BcContainerAppWithCheck.ps1

<#
.SYNOPSIS
Function to publish apps to a Microsoft Dynamics 365 Business Central environment with version check on SaaS environment.
 
.DESCRIPTION
The `Publish-BcContainerAppWithCheck` function is a full clone of `Publish-BcContainerApp` but includes additional checks for the installed version on a SaaS environment. It ensures that the app is only published if the version is different or not installed.
 
.PARAMETER appFile
Specifies the path to the app file to be published.
 
.PARAMETER skipVerification
Skips the verification step if specified.
 
.PARAMETER ignoreIfAppExists
Ignores the app if it already exists.
 
.PARAMETER syncMode
Specifies the synchronization mode. Valid values are 'Add', 'Clean', 'Development', 'ForceSync'.
 
.PARAMETER install
Installs the app if specified.
 
.PARAMETER upgrade
Upgrades the app if specified.
 
.PARAMETER useDevEndpoint
Uses the development endpoint if specified.
 
.PARAMETER credential
Specifies the credentials to use for authentication.
 
.PARAMETER replacePackageId
Replaces the package ID if specified.
 
.PARAMETER bcAuthContext
Specifies the Business Central authentication context.
 
.PARAMETER environment
Specifies the environment in which to publish the app.
 
.PARAMETER checkAlreadyInstalled
Checks if the app is already installed.
 
.PARAMETER excludeRuntimePackages
Excludes runtime packages if specified.
 
.EXAMPLE
Publish-BcContainerAppWithCheck -appFile "C:\path\to\appfile.app" -environment "Production" -bcAuthContext $bcAuthContext
 
.NOTES
This function is designed to work with Microsoft Dynamics 365 Business Central SaaS environments.
#>


function Publish-BcContainerAppWithCheck {
    Param (
        [Parameter(Mandatory=$true)]
        $appFile,
        [switch] $skipVerification,
        [switch] $ignoreIfAppExists,
        [Parameter(Mandatory=$false)]
        [ValidateSet('Add','Clean','Development','ForceSync')]
        [string] $syncMode,
        [switch] $install,
        [switch] $upgrade,
        [switch] $useDevEndpoint,
        [pscredential] $credential,
        [switch] $replacePackageId,
        [Hashtable] $bcAuthContext,
        [string] $environment,
        [switch] $checkAlreadyInstalled,
        [switch] $excludeRuntimePackages
    )
    
    $installedExtensions = Get-BcInstalledExtensions -bcAuthContext $bcAuthContext -environment $environment
    $sortApps = Sort-AppFilesByDependencies -appFiles $appFile 3> $null

    foreach ($appPath in $sortApps) {
        $appJson = Get-AppJsonFromAppFile -appFile $appPath
        $appName = $appJson.name
        $appVersion = $appJson.version

        $installedExtension = $installedExtensions | Where-Object { $_.displayName -eq $appName }

        if ($null -ne $installedExtension) {
            $installedVersion = "$($installedExtension.versionMajor).$($installedExtension.versionMinor).$($installedExtension.versionBuild).$($installedExtension.versionRevision)"
            if ($installedVersion -eq $appVersion -and $installedExtension.isInstalled) {
                Write-Output "Application $appName is already installed with this version $appVersion"
                continue
            } elseif ($installedVersion -eq $appVersion -and -not $installedExtension.isInstalled ) {
                Write-Output "Application $appName is already published with this version $appVersion . Installing..."
                $replacePackageId = $true
            } else {
                Write-Host "Publishing to tenant"
            }
        } else {
            Write-Output "Application $appName not found among installed extensions"
        }

        Publish-BcContainerApp `
        -appFile $appPath `
        -skipVerification:$skipVerification `
        -ignoreIfAppExists:$ignoreIfAppExists `
        -syncMode $syncMode `
        -install:$install `
        -upgrade:$upgrade `
        -useDevEndpoint:$useDevEndpoint `
        -credential $credential `
        -replacePackageId:$replacePackageId `
        -bcAuthContext $bcAuthContext `
        -environment $environment `
        -checkAlreadyInstalled:$checkAlreadyInstalled `
        -excludeRuntimePackages:$excludeRuntimePackages
    }
}