Public/Get-ChangedALFiles.ps1

function Get-ChangedALFiles {
    <#
    .SYNOPSIS
    Get list of changed AL files using native git
     
    .DESCRIPTION
    Detects changed .al files in the current branch compared to a base branch.
    Auto-detects PR context in Azure DevOps pipelines.
     
    .PARAMETER BaseBranch
    Base branch for comparison (default: origin/master).
    In PR builds, auto-detects from SYSTEM_PULLREQUEST_TARGETBRANCH environment variable.
     
    .EXAMPLE
    Get-ChangedALFiles
    Returns all changed .al files compared to origin/master
     
    .EXAMPLE
    Get-ChangedALFiles -BaseBranch "origin/development"
    Compare against specific branch
     
    .OUTPUTS
    System.String[] - Array of file paths relative to repository root
     
    .NOTES
    Author: waldo
    Version: 1.0.0
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $false)]
        [string]$BaseBranch = "origin/master"
    )
    
    begin {
        Write-Verbose "Starting $($MyInvocation.MyCommand.Name)"
    }
    
    process {
        try {
            # Auto-detect base branch in PR context
            if ($env:SYSTEM_PULLREQUEST_TARGETBRANCH) {
                $branchName = $env:SYSTEM_PULLREQUEST_TARGETBRANCH -replace '^refs/heads/', ''
                $BaseBranch = "origin/$branchName"
                Write-Host "PR detected - comparing against $BaseBranch"
            }
            
            Write-Verbose "Getting changed AL files using git diff against $BaseBranch"
            
            # Ensure we have latest remote refs
            Write-Verbose "Fetching latest from origin..."
            git fetch origin --quiet 2>&1 | Out-Null
            
            # Get list of changed .al files
            # --name-only: just file names
            # --diff-filter=ACMR: Added, Copied, Modified, Renamed (skip Deleted)
            $changedFiles = git diff --name-only --diff-filter=ACMR "$BaseBranch...HEAD" 2>&1 |
                Where-Object { $_ -match '\.al$' }
            
            if (-not $changedFiles) {
                Write-Host "No AL files changed"
                return @()
            }
            
            $changedFiles = @($changedFiles)  # Ensure array
            Write-Host "✅ Found $($changedFiles.Count) changed AL file(s):"
            foreach ($file in $changedFiles) {
                Write-Host " - $file"
            }
            
            return $changedFiles
        }
        catch {
            Write-Error "Error in $($MyInvocation.MyCommand.Name): $_"
            throw
        }
    }
    
    end {
        Write-Verbose "Completed $($MyInvocation.MyCommand.Name)"
    }
}