Scripts/SolutionChecker.ps1





function Start-SolutionChecker {
    Param(
        [string] [Parameter(Mandatory = $true)] $PipelinePath,
        [string] [Parameter(Mandatory = $true)] $SolutionPath,
        [string] [Parameter(Mandatory = $true)] $SolutionName,
        [string] [Parameter(Mandatory = $true)] $ClientId,
        [string] [Parameter(Mandatory = $false)] $ClientSecret = "",
        [string] [Parameter(Mandatory = $true)] $TenantId
    )


    try {

        ######################## SETUP
        . "$PSScriptRoot\..\Private\_SetupTools.ps1"
        Write-Host "Executing Powerapps Solution Checker"

        [string]$LogsDirectory = "$PipelinePath"
   
        if (Test-Path -Path $PipelinePath\SolutionChecker.json) {

            $settings = Get-Content "$PipelinePath\SolutionChecker.json" | ConvertFrom-Json

            Write-Host "Running Powerapps Solution Checker on $SolutionName"                        
            Write-Host $settings

            $ruleSetFilter = $settings.RuleSets -join ','
            $rulesets = Get-PowerAppsCheckerRulesets -Geography $settings.Geo
            $rulesetToUse = $rulesets | Where-Object Name -EQ $ruleSetFilter

            $overrides = @()
            if ($settings.RuleLevelOverrides.Length -gt 0) {
                Write-Host "Checking with Rule Overrides"

                foreach ($override in $settings.RuleLevelOverrides) {
                    $overrides += New-PowerAppsCheckerRuleLevelOverride -Id $($override.Rule) -OverrideLevel $override.Level
                }

                if ($settings.ExcludedFileNamePattern.Length -gt 0) {
                    $filePattern = $settings.ExcludedFileNamePattern 
                }
                else {
                    $filePattern = "*json*" #need to find a default file if none exist
                }
           
                $analyzeResult = Invoke-PowerAppsChecker -Geography $settings.Geo -ClientApplicationId $ClientId -TenantId $TenantId `
                    -Ruleset $rulesetToUse `
                    -FileUnderAnalysis $SolutionPath `
                    -OutputDirectory $LogsDirectory `
                    -ClientApplicationSecret (ConvertTo-SecureString -AsPlainText -Force -String $ClientSecret) `
                    -RuleLevelOverrides $overrides `
                    -ExcludedFileNamePattern "$filePattern"
            }
            else {
                Write-Host "Checking with Rule Sets"
                $analyzeResult = Invoke-PowerAppsChecker -Geography $settings.Geo -ClientApplicationId $ClientId -TenantId $TenantId `
                    -Ruleset $rulesetToUse `
                    -FileUnderAnalysis $SolutionPath `
                    -OutputDirectory $LogsDirectory `
                    -ClientApplicationSecret (ConvertTo-SecureString -AsPlainText -Force -String $ClientSecret)
            }

            Write-Host "Powerapps Solution Checker results"  

            Write-Output $analyzeResult.Status 
            Write-Output $analyzeResult.IssueSummary 
            Write-Output $analyzeResult.DownloadedResultFiles
            Write-Output $analyzeResult.ResultFileUris 

            if ($analyzeResult.IssueSummary.HighIssueCount -gt 0) {
                $errorCount = $analyzeResult.IssueSummary.HighIssueCount
                $errorMessage = @"
            You have $errorCount High Issues in $SolutionName
            You can review the results by getting the output from $PipelinePath in the Pipeline Artifacts. Results can be analysed using https://microsoft.github.io/sarif-web-component/
"@

                Write-Host "##[error] $errorMessage"
                Write-Host "##vso[task.logissue type=error;] $errorMessage"    
            }
        
            if ($analyzeResult.IssueSummary.CriticalIssueCount -gt 0) {
                $errorCount = $analyzeResult.IssueSummary.CriticalIssueCount
                $errorMessage = @"
            You have $errorCount Critical Issues in $SolutionName
            You can review the results by getting the output from $PipelinePath in the Pipeline Artifacts. Results can be analysed using https://microsoft.github.io/sarif-web-component/
"@

                Write-Host "##[error] $errorMessage"
                Write-Host "##vso[task.logissue type=error;] $errorMessage"
            }
        }
        else {
            Write-Host "Skipping Powerapps Solution Checker on $SolutionName - check valid SolutionChecker.json settings file exist"          
        }
    }
    catch {
        Write-Host "##[error]:$($_)"
        Write-Host "##[section] Skipping PowerApps Solution Checker"
    }
}