microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3a3a0fdf923d96a9e8a9ac734c73f24433b525e8

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/tests/Get-ChangedTestFiles.ps1

152lines · modecode

1#!/usr/bin/env pwsh
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4#
5# Get-ChangedTestFiles.ps1
6#
7# Purpose: Detect changed PowerShell files and resolve corresponding Pester test paths
8# Author: HVE Core Team
9
10#Requires -Version 7.0
11
12[CmdletBinding()]
13param(
14 [Parameter(Mandatory = $false)]
15 [string]$BaseBranch,
16
17 [Parameter(Mandatory = $false)]
18 [string[]]$FileFilter = @('*.ps1', '*.psm1'),
19
20 [Parameter(Mandatory = $false)]
21 [string]$SkillsRoot = '.github/skills',
22
23 [Parameter(Mandatory = $false)]
24 [string]$TestRoot = 'scripts/tests'
25)
26
27$ErrorActionPreference = 'Stop'
28
29# Import CI helpers for output writing
30Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force
31
32#region Functions
33
34function Get-ChangedTestFilesCore {
35 <#
36 .SYNOPSIS
37 Detects changed PowerShell files and resolves corresponding Pester test paths.
38 .DESCRIPTION
39 Runs git diff against the specified base branch to find changed .ps1/.psm1 files,
40 then maps each changed source file to its corresponding test file by searching
41 test directories including skill test folders at depth 1 and 2.
42 .PARAMETER BaseBranch
43 The base branch to diff against (e.g., 'main').
44 .PARAMETER FileFilter
45 File extensions to include in the diff (default: *.ps1, *.psm1).
46 .PARAMETER SkillsRoot
47 Root directory for skill packages containing test folders.
48 .PARAMETER TestRoot
49 Root directory for script tests.
50 #>
51 [CmdletBinding()]
52 [OutputType([PSCustomObject])]
53 param(
54 [Parameter(Mandatory = $true)]
55 [string]$BaseBranch,
56
57 [string[]]$FileFilter = @('*.ps1', '*.psm1'),
58
59 [string]$SkillsRoot = '.github/skills',
60
61 [string]$TestRoot = 'scripts/tests'
62 )
63
64 # Get changed files from git diff
65 $diffOutput = git diff --name-only "origin/$BaseBranch...HEAD" -- @FileFilter 2>&1
66 if ($LASTEXITCODE -ne 0) {
67 Write-Warning "git diff failed with exit code $LASTEXITCODE"
68 return [PSCustomObject]@{
69 HasChanges = $false
70 TestPaths = @()
71 ChangedFiles = @()
72 }
73 }
74
75 $changedFiles = @($diffOutput | Where-Object { $_ -and $_.Trim() })
76 if ($changedFiles.Count -eq 0) {
77 return [PSCustomObject]@{
78 HasChanges = $false
79 TestPaths = @()
80 ChangedFiles = @()
81 }
82 }
83
84 Write-Host "Changed PowerShell files:"
85 $changedFiles | ForEach-Object { Write-Host " - $_" }
86
87 # Build test search directories
88 $testDirs = @($TestRoot)
89 if (Test-Path $SkillsRoot) {
90 foreach ($depth in @('*', '*/*')) {
91 $pattern = Join-Path $SkillsRoot $depth 'tests'
92 Get-Item -Path $pattern -ErrorAction SilentlyContinue |
93 Where-Object { $_.PSIsContainer -and (Test-Path (Join-Path $_.Parent.FullName 'scripts')) } |
94 ForEach-Object { $testDirs += $_.FullName }
95 }
96 }
97
98 # Map changed source files to test files
99 $testPaths = @()
100 foreach ($file in $changedFiles) {
101 # Include directly changed test files
102 if ($file -like '*.Tests.ps1') {
103 $fullPath = Join-Path (Get-Location) $file
104 if (Test-Path $fullPath) {
105 $testPaths += $fullPath
106 }
107 continue
108 }
109
110 # Map source file to test file by name convention
111 $fileName = [System.IO.Path]::GetFileNameWithoutExtension($file)
112 $testFileName = "$fileName.Tests.ps1"
113
114 foreach ($dir in $testDirs) {
115 $candidates = Get-ChildItem -Path $dir -Filter $testFileName -Recurse -ErrorAction SilentlyContinue
116 foreach ($candidate in $candidates) {
117 $testPaths += $candidate.FullName
118 }
119 }
120 }
121
122 # Deduplicate
123 $testPaths = @($testPaths | Select-Object -Unique)
124
125 if ($testPaths.Count -eq 0) {
126 Write-Host "No matching test files for changed PowerShell files"
127 }
128 else {
129 Write-Host "Found $($testPaths.Count) test file(s) to run:"
130 $testPaths | ForEach-Object { Write-Host " - $_" }
131 }
132
133 return [PSCustomObject]@{
134 HasChanges = ($testPaths.Count -gt 0)
135 TestPaths = $testPaths
136 ChangedFiles = $changedFiles
137 }
138}
139
140#endregion
141
142# Script guard: only execute CI output when run directly, not when dot-sourced
143if ($MyInvocation.InvocationName -ne '.') {
144 if (-not $BaseBranch) {
145 throw 'BaseBranch parameter is required when running directly.'
146 }
147 $result = Get-ChangedTestFilesCore -BaseBranch $BaseBranch -FileFilter $FileFilter -SkillsRoot $SkillsRoot -TestRoot $TestRoot
148
149 # Write CI environment variables using injection-safe helpers
150 Set-CIEnv -Name 'HAS_CHANGES' -Value ([string]$result.HasChanges)
151 Set-CIEnv -Name 'TEST_PATHS' -Value ($result.TestPaths -join ';')
152}
153