AL/Get-ALDependenciesFromAppJson.ps1

<#
 .Synopsis
  Gets the dependency apps that are defined in the app.json
 .Description
  If app.json has dependent apps defined, it will download and install the apps, if possible
 .Parameter SourcePath
  Path to the current project
 .Parameter devOpsToken
  Token to access Azure DevOps. Can be provided in settings.json
 .Parameter ContainerName
  If blank, the container name will be retrieved from settings.json
 .Parameter skipVerification
  Add this switch to skip app verification for dependency apps
 .Parameter Install
  Add this switch to install the dependency apps
 .Parameter TenantScope
  Add this switch to install the dependency apps in the tenant and not global scope
 .Example
  $dependencies = Get-ALDependenciesFromAppJson
#>

function Get-ALDependenciesFromAppJson {
    Param(
        [Parameter(Mandatory = $true)]
        $appJson,
        [Parameter(Mandatory = $true)]
        [string] $sourcePath,
        [Parameter(Mandatory = $true)]
        [string] $dependencyPath,
        [Parameter(Mandatory = $true)]
        [string] $devOpsToken,
        [Parameter(Mandatory = $false)]
        [string] $organization = "",
        [Parameter(Mandatory = $false)]
        [string] $feed = "",
        [Parameter(Mandatory = $false)]
        [string]$containerName,
        [Parameter(Mandatory = $false)]
        [switch] $skipVerification,
        [Parameter(Mandatory = $false)]
        [switch] $Install,
        [switch] $TenantScope
    )

    [version]$platform = Get-AppKeyValue -SourcePath $sourcePath -KeyName 'platform'
    $ContainerName = Get-NewContainerName -SourcePath $SourcePath -ContainerName $ContainerName

    foreach ($Dependency in $appJson.dependencies | Where-Object Name -NotLike '*Test*' | Where-Object Name -NotLike '*Runtime*' | Where-Object Name -NotLike 'Library Assert' | Where-Object Name -NotLike 'Any') {
        $dependencyAppJson = $null
        $version = ""
        $feed = ""

        $apps = @()

        if ($null -ne $Dependency) {
            Write-Host "Getting App Container Info from container $containerName"
            $appInfo = Get-BcContainerAppInfo -containerName $containerName -tenant default -tenantSpecificProperties
            Write-Host "Apps received from container"

            $installApps = $false
            if ($null -eq $appInfo) {
                $installApps = $true
            } else {
                if (Get-Member -InputObject $appInfo -name "AppId" -MemberType Properties) {
                    if (($appInfo.AppId -contains $Dependency.id)) {
                        Write-Host "Dependency $($Dependency.name) installed already"
                        $installApps = $false
                    }
                    else {
                        $installApps = $true
                    }
                }
                else {
                    $installApps = $true
                }
            }

            if ($installApps) {
                Write-Host "Dependency not installed yet"
                $envDependency = (Get-DependencyFromEnvironment -sourcePath $sourcePath -name $Dependency.name)

                # getting DevOps feed
                if ($feed -eq "") {
                    try {
                        $feed = $envDependency.devOpsFeed
                    }
                    catch {
                        $applicationVersion = [version](Get-AppKeyValue -sourcePath $SourcePath -KeyName "application")
                        $feed = "ISV_{0}.{1}" -f $applicationVersion.Major, $applicationVersion.Minor # hard coded to getting 3rd party apps
                    }
                }

                if ($null -ne $envDependency) {
                    Write-Output "Getting dependencies for $($envDependency.name)"
                    # getting version from app.json, if not in settings.json
                    try {
                        $version = $envDependency.version
                    }
                    catch {
                        $version = ""
                    }
                    if ($null -eq $version -or $version -eq "") {
                        $version = $Dependency.Version
                    }

                    # getting organization
                    if ($organization -eq "") {
                        try {
                            $organization = $envDependency.organization
                        }
                        catch {
                            $organization = Get-EnvironmentKeyValue -SourcePath $sourcePath -KeyName 'organization'
                        }
                    }

                    # getting artifact name
                    try {
                        $artifactName = $envDependency.devOpsArtifactName
                    }
                    catch {
                        $artifactName = $Dependency.Name.ToLower().Replace(' ', '_').Replace('.', '_').Replace('/','_').Replace('(','_').Replace(')','_').Replace('__','_')
                    }

                    Write-Host "Getting Artifact List"
                    $apps = Get-DevOpsArtifactList -devOpsOrganization $organization -devOpsFeed $feed -devOpsArtifactName $artifactName -version $version -devOpsToken $devOpsToken -destination (Join-Path $sourcePath ".alpackages")
                    Write-Host "After Getting Artifact List"
                    if ($null -ne $apps -and $apps -ne "") {
                        Write-Host "Apps: $apps"
                        $dependencyAppJson = Get-AppInfoFromContainer -containerName $containerName -appFile $apps
                    }
                }
                else {
                    if ($Dependency.publisher -eq 'Microsoft') {
                        $Apps = @()
                        $DependencyAppJson = $null
                    }
                    else {
                        Write-Host "Getting artifacts versopn"
                        # getting artifact name
                        $artifactName = $Dependency.Name.ToLower().Replace(" ", "_")
                        $version = Get-LatestArtifactVersion -devOpsOrganization $organization -devOpsToken $devOpsToken -feed $feed -packageName $artifactName
                        if ($version -eq "") {
                            $version = "*"
                        }
                        Write-Host "Getting artifact list 2"
                        $apps = Get-DevOpsArtifactList -devOpsOrganization $organization -devOpsFeed $feed -devOpsArtifactName $artifactName -version $version -devOpsToken $devOpsToken -destination (Join-Path $sourcePath ".alpackages")
                        Write-Host "After getting Artifact list 2"
                    }
                }

                # get dependencies for dependency app
                if ($null -ne $dependencyAppJson) {
                    Write-Host "Getting dependencies"
                    Get-ALDependenciesFromAppJson -AppJson $dependencyAppJson -sourcePath $sourcePath -dependencyPath $dependencyPath -devOpsToken $devOpsToken -containerName $containerName -skipVerification:$skipVerification -Install:$Install -feed $feed -organization $organization
                }

                if ($null -ne $apps -and $apps -ne "") {
                    # copy and install apps
                    foreach ($app in $apps) {
                        Write-Output "Processing artifact $app"

                        if ($Install.IsPresent) {
                            try {
                                $publishParameters = @{
                                    containerName = $containerName
                                    appFile       = $app
                                    install       = $true
                                    sync          = $true
                                }

                                if ($TenantScope.IsPresent) {
                                    $publishParameters.Add('scope', 'Tenant')
                                    $publishParameters.Add('tenant', 'Default')
                                }
                                else {
                                    if ($platform.Major -ge 15) {
                                        $publishParameters.Add('tenant', 'Default')
                                    }
                                }

                                $publishParameters.Add('skipVerification', $true)

                                Publish-BcContainerApp @publishParameters
                            }
                            catch {
                                if (!($_.Exception.Message.Contains('already published'))) {
                                    throw $_.Exception.Message
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}