Scripts/ExportSolution.ps1

#
# ExportSolution.ps1
#

function Get-DataverseSolution {
    Param(
        [string] [Parameter(Mandatory = $true)] $StartPath,
        [string] [Parameter(Mandatory = $true)] $SelectedSolution
    )
    try {
        
        $SolutionName = $SelectedSolution
        Remove-Item (Join-Path $StartPath "\dataverse_*patch*") -Force -Recurse -ErrorAction Ignore        
        ######################## EXPORT SOLUTION

        ##Export Patches if they Exist
        foreach ($PatchSolution in $PatchQuery.CrmRecords) {
            $SolutionId = $PatchSolution.solutionid
            $SolutionName = $PatchSolution.uniquename
            $SolutionVersion = $PatchSolution.version
            
            ##### Deprecated - Replacing with PAC ######
            #$message = "Exporting Unmanaged Solution for $SolutionName"
            #Write-Host $message

            #Export-CrmSolution -SolutionName $SolutionName -SolutionZipFileName "$SolutionName.zip" -conn $conn -ErrorAction Stop

            #$message = "Exporting Managed Solution for $SolutionName"
            #Write-Host $message

            #Export-CrmSolution -SolutionName $SolutionName -Managed -SolutionZipFileName $SolutionName"_managed.zip" -conn $conn -ErrorAction Stop

            ######################## EXTRACT SOLUTION
            # $ErrorActionPreference = "SilentlyContinue"
            
            #$message = "Unpacking Solution $SolutionName"
            #Write-Host $message
            #Remove-Item (Join-Path $StartPath "\dataverse_$SolutionName\") -Recurse -Force -ErrorAction Ignore
            #& $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe solution unpack --folder (Join-Path $StartPath "\dataverse_$SolutionName\") --zipfile "$SolutionName.zip" --packagetype Both --allowDelete $false --clobber --useUnmanagedFileForMissingManaged
            

            #$canvasApps = Get-ChildItem -Path (Join-Path $StartPath "\dataverse_$SolutionName\") -Filter *.msapp -Recurse
            #try {
            # unpack canvas apps
            #$canvasApps | ForEach-Object {
            #Write-Host "Unpacking Canvas App $($_.name)";
            #& $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe canvas unpack --msapp $_.FullName --sources "$($_.DirectoryName)\$($_.BaseName)"
            #Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
            #}
            #}
            #catch {
            #Write-Host "Error in Unpacking Canvas App"
            #Write-Host $_
            #}
            # Trigger Clone or Sync
            $pacexepath = "$env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe"
            $unpackfolderpath = (Join-Path $StartPath "pac_$SolutionName")
            $cdsProjPath = (Join-Path $StartPath "pac_$SolutionName\$SolutionName\$SolutionName.cdsproj")
            $cdsProjFolderPath = (Join-Path $StartPath "pac_$SolutionName")
            # If .cds project file exists (i.e., Clone performed already) trigger Sync
            if (Test-Path "$cdsProjPath") {
                Write-Host "Cloned solution available; Triggering Solution Sync"
                $cdsProjfolderPath = [System.IO.Path]::GetDirectoryName("$cdsProjPath")
                Write-Host "Pointing to cdsproj folder path - " $cdsProjfolderPath
                Set-Location -Path $cdsProjfolderPath
                $syncCommand = "solution sync --processCanvasApps true --packagetype Both --async"
                Write-Host "Triggering Sync - $syncCommand"
                Invoke-Expression -Command "$pacexepath $syncCommand"
            }
            else {
                # Trigger Clone
                $cloneCommand = "solution clone -n $SolutionName --processCanvasApps true --outputDirectory ""$unpackfolderpath"" --packagetype Both --async"
                Write-Host "Clone Command - $pacexepath $cloneCommand"
                Invoke-Expression -Command "$pacexepath $cloneCommand"
            }

            $gitStatus = iex "git status --porcelain"
            if ($gitStatus) {
                Set-DataverseSolutionVersion  

                Write-Host "Cloned solution available; Triggering Solution Sync"
                $cdsProjfolderPath = [System.IO.Path]::GetDirectoryName("$cdsProjPath")
                Write-Host "Pointing to cdsproj folder path - " $cdsProjfolderPath
                Set-Location -Path $cdsProjfolderPath

                $syncCommand = "solution sync --processCanvasApps true --packagetype Both --async"
                Write-Host "Triggering Sync - $syncCommand"
                Invoke-Expression -Command "$pacexepath $syncCommand"
                
                # Move items from SolutionPackage/Solution folder to SolutionPackage
                $legacyFolder = (Join-Path $StartPath "dataverse_$SolutionName")
                Write-Host "Copying items from $unpackfolderpath\$SolutionName\src to Legacy Folder ($LegacyFolder)"
                Remove-Item (Join-Path $StartPath "dataverse_$SolutionName") -Recurse -Force -ErrorAction Ignore
                Copy-Item "$unpackfolderpath\$SolutionName\src" -Destination (Join-Path $StartPath "dataverse_$SolutionName") -Recurse -Container -Force
          
                Get-FlowsToBeDeployed "$StartPath" $SelectedSolution

                Get-ExportDataValid

                # git add -A
                # git commit -m "Updated unpack of solution $SolutionName"
                # $tagVersion = $global:devops_newVersion.Replace(".", "_")
                # git tag "$($SolutionName)_v_$tagVersion"
                # if ($global:devops_FullTool) {
                # git push origin "$($SolutionName)_v_$tagVersion"
                # }
            }

        }
    
        ## No Patches
        If (!$PatchQuery.CrmRecords) {

            ##### Deprecated - Replacing with PAC ######
            #$message = "Exporting Unmanaged Solution for $SolutionName"
            #Write-Host $message

            # Export-CrmSolution -SolutionName $SolutionName -SolutionZipFileName "$SolutionName.zip" -conn $conn -ErrorAction Stop

            # $message = "Exporting Managed Solution for $SolutionName"
            # Write-Host $message

            # Export-CrmSolution -SolutionName $SolutionName -Managed -SolutionZipFileName $SolutionName"_managed.zip" -conn $conn -ErrorAction Stop
        
            ######################## EXTRACT SOLUTION
            # $ErrorActionPreference = "SilentlyContinue"


            # $message = "Unpacking Solution $SolutionName"
            # Write-Host $message
            # Remove-Item (Join-Path $StartPath "\dataverse_$SolutionName\") -Recurse -Force -ErrorAction Ignore
            # & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe solution unpack --folder (Join-Path $StartPath "\dataverse_$SolutionName\") --zipfile "$SolutionName.zip" --packagetype Both --allowDelete $false --clobber --useUnmanagedFileForMissingManaged
            # $canvasApps = Get-ChildItem -Path (Join-Path $StartPath "\dataverse_$SolutionName\") -Filter *.msapp -Recurse
    
            # # unpack canvas apps
            # $canvasApps | ForEach-Object {
            # Write-Host "Unpacking Canvas App $($_.name)";
            # & $env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe canvas unpack --msapp $_.FullName --sources "$($_.DirectoryName)\$($_.BaseName)"
            # Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
            # }

            # Trigger Clone or Sync
            $pacexepath = "$env:APPDATA\Microsoft.PowerPlatform.DevOps\PACTools\tools\pac.exe"
            $unpackfolderpath = (Join-Path $StartPath "pac_$SolutionName")
            $cdsProjPath = (Join-Path $StartPath "pac_$SolutionName\$SolutionName\$SolutionName.cdsproj")
            $cdsProjFolderPath = (Join-Path $StartPath "pac_$SolutionName")
            # If .cds project file exists (i.e., Clone performed already) trigger Sync
            if (Test-Path "$cdsProjPath") {
                Write-Host "Cloned solution available; Triggering Solution Sync"
                $cdsProjfolderPath = [System.IO.Path]::GetDirectoryName("$cdsProjPath")
                Write-Host "Pointing to cdsproj folder path - " $cdsProjfolderPath
                Set-Location -Path $cdsProjfolderPath
                $syncCommand = "solution sync --processCanvasApps true --packagetype Both --async"
                Write-Host "Triggering Sync - $syncCommand"
                Invoke-Expression -Command "$pacexepath $syncCommand"
            }
            else {
                # Trigger Clone
                $cloneCommand = "solution clone -n $SolutionName --processCanvasApps true --outputDirectory ""$unpackfolderpath"" --packagetype Both --async"
                Write-Host "Clone Command - $pacexepath $cloneCommand"
                Invoke-Expression -Command "$pacexepath $cloneCommand"
            }
         
            $gitStatus = iex "git status --porcelain"
            if ($gitStatus) {
                Set-DataverseSolutionVersion  
         
                Write-Host "Cloned solution available; Triggering Solution Sync"
                $cdsProjfolderPath = [System.IO.Path]::GetDirectoryName("$cdsProjPath")
                Write-Host "Pointing to cdsproj folder path - " $cdsProjfolderPath
                Set-Location -Path $cdsProjfolderPath
         
                $syncCommand = "solution sync --processCanvasApps true --packagetype Both --async"
                Write-Host "Triggering Sync - $syncCommand"
                Invoke-Expression -Command "$pacexepath $syncCommand"

                # Move items from SolutionPackage/Solution folder to SolutionPackage
                $legacyFolder = (Join-Path $StartPath "dataverse_$SolutionName")
                Write-Host "Copying items from $unpackfolderpath\$SolutionName\src to Legacy Folder ($LegacyFolder)"
                Remove-Item (Join-Path $StartPath "dataverse_$SolutionName") -Recurse -Force -ErrorAction Ignore
                #Get-ChildItem -Path "$unpackfolderpath\$SolutionName\src" |
                Copy-Item "$unpackfolderpath\$SolutionName\src" -Destination (Join-Path $StartPath "dataverse_$SolutionName") -Recurse -Container -Force
 
                Get-FlowsToBeDeployed "$StartPath" $SelectedSolution

                Get-ExportDataValid

                # git add -A
                # git commit -m "Updated unpack of solution $SolutionName"
                # $tagVersion = $global:devops_newVersion.Replace(".", "_")
                # git tag "$($SolutionName)_v_$tagVersion"
                # if ($global:devops_FullTool) {
                # git push origin "$($SolutionName)_v_$tagVersion"
                # }
            }
        
        }
    
    }
    catch {
        Write-Host $_
        pause
    }
    finally {

    }
}

function Get-FlowsToBeDeployed {
    Param(
        [string] [Parameter(Mandatory = $true)] $StartPath,
        [string] [Parameter(Mandatory = $true)] $SelectedSolution
    )
    try {
        Write-Host "Generating Flows_Default.json to Support Flow Activation"
        $SolutionName = $SelectedSolution
        $SolutionPath = (Join-Path $StartPath "\dataverse_$SolutionName\Workflows")

        $Workflows = Get-ChildItem -Path $SolutionPath -Filter *.json -ErrorAction SilentlyContinue
        if ($Workflows) {
            $Workflows | ForEach-Object {
                $FlowName = $_.BaseName.SubString(0, $_.BaseName.Length - 36)
                $FlowID = $_.BaseName.Replace($FlowName, '')
                $FlowJSON += @([ordered]@{FlowID = $FlowID; FlowName = $FlowName; ActivateAsUser = ""; })
            }
            ConvertTo-Json -Depth 3 $FlowJSON | Format-Json | Out-FileUtf8NoBom $StartPath\Flows_Default.json            
        }

    }
    catch {
        Write-Host $_
        pause
    }
}