|
1 | 1 | <# |
2 | 2 | .SYNOPSIS |
3 | | - Filters test projects for CI workflows. |
| 3 | + Filters test projects based on changed files to optimize CI workflow execution. |
4 | 4 |
|
5 | 5 | .DESCRIPTION |
6 | | - Receives test project objects from the pipeline and returns them. |
7 | | - Currently, all projects are passed through unchanged. |
| 6 | + Analyzes changed files and determines which test projects need to run. Protected |
| 7 | + branches and global repository changes run all tests. Other branches run only |
| 8 | + affected modules. |
| 9 | +
|
| 10 | + .EXAMPLE |
| 11 | + # Test protected branch (runs all tests): |
| 12 | + $env:GITHUB_REF_NAME="main"; $env:ALL_CHANGED_FILES="README.md"; $input | Filter-TestProjects |
| 13 | +
|
| 14 | + .EXAMPLE |
| 15 | + # Test core library changes (runs all tests): |
| 16 | + $env:GITHUB_REF_NAME="1/merge"; $env:ALL_CHANGED_FILES="src/Testcontainers/Testcontainers.csproj"; $input | Filter-TestProjects |
| 17 | +
|
| 18 | + .EXAMPLE |
| 19 | + # Test module-specific changes (runs only affected module): |
| 20 | + $env:GITHUB_REF_NAME="2/merge"; $env:ALL_CHANGED_FILES="src/Testcontainers.Redis/RedisBuilder.cs"; $input | Filter-TestProjects |
8 | 21 | #> |
9 | 22 |
|
10 | | -Param ( |
11 | | - [Parameter(ValueFromPipeline)] |
12 | | - $InputObject |
| 23 | +$PROTECTED_BRANCHES = @( |
| 24 | + "main", |
| 25 | + "develop" |
| 26 | +) |
| 27 | + |
| 28 | +$GLOBAL_PATTERNS = @( |
| 29 | + "^\.github/scripts/", |
| 30 | + "^\.github/workflows/", |
| 31 | + "^build/", |
| 32 | + "^Directory\.Build\.props$", |
| 33 | + "^Directory\.Packages\.props$", |
| 34 | + "^src/Testcontainers/" |
| 35 | +) |
| 36 | + |
| 37 | +$DATABASE_MODULES = @( |
| 38 | + "Testcontainers.Cassandra", |
| 39 | + "Testcontainers.ClickHouse", |
| 40 | + "Testcontainers.CockroachDb", |
| 41 | + "Testcontainers.Db2", |
| 42 | + "Testcontainers.FirebirdSql", |
| 43 | + "Testcontainers.MariaDb", |
| 44 | + "Testcontainers.MsSql", |
| 45 | + "Testcontainers.MySql", |
| 46 | + "Testcontainers.Oracle", |
| 47 | + "Testcontainers.PostgreSql", |
| 48 | + "Testcontainers.Xunit", |
| 49 | + "Testcontainers.XunitV3" |
13 | 50 | ) |
14 | 51 |
|
15 | | -Process { |
16 | | - # Return test projects unchanged. |
17 | | - $InputObject |
| 52 | +$ORACLE_MODULES = @( |
| 53 | + "Testcontainers.Oracle", |
| 54 | + "Testcontainers.Oracle11", |
| 55 | + "Testcontainers.Oracle18", |
| 56 | + "Testcontainers.Oracle21", |
| 57 | + "Testcontainers.Oracle23" |
| 58 | +) |
| 59 | + |
| 60 | +$XUNIT_MODULES = @( |
| 61 | + "Testcontainers.Xunit", |
| 62 | + "Testcontainers.XunitV3" |
| 63 | +) |
| 64 | + |
| 65 | +function Should-RunTests { |
| 66 | + param ([string]$ModuleName) |
| 67 | + |
| 68 | + # Rule 1: Protected branches always run all tests. |
| 69 | + # Ensures main/develop branches have full test coverage. |
| 70 | + If ($script:branch -In $PROTECTED_BRANCHES) { |
| 71 | + Write-Host "Running '$ModuleName': protected branch '$script:branch'." |
| 72 | + return $True |
| 73 | + } |
| 74 | + |
| 75 | + # Rule 2: Global changes affect all modules. |
| 76 | + ForEach ($pattern In $GLOBAL_PATTERNS) { |
| 77 | + If ($script:allChangedFiles | Where-Object { $_ -Match $pattern }) { |
| 78 | + Write-Host "Running '$ModuleName': global changes detected ($pattern)." |
| 79 | + return $True |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + # Rule 3: Module-specific changes. |
| 84 | + If ($script:allChangedFiles | Where-Object { $_ -Match "^(src|tests)/$ModuleName" }) { |
| 85 | + Write-Host "Running '$ModuleName': module-specific changes detected." |
| 86 | + return $True |
| 87 | + } |
| 88 | + |
| 89 | + # Rule 4: Shared database tests for ADO.NET compatible modules. |
| 90 | + If ($ModuleName -In $DATABASE_MODULES -And ($script:allChangedFiles | Where-Object { $_ -Match '^tests/Testcontainers\.Databases\.Tests' })) { |
| 91 | + Write-Host "Running '$ModuleName': database test changes detected." |
| 92 | + return $True |
| 93 | + } |
| 94 | + |
| 95 | + # Rule 5: Oracle integration variants. |
| 96 | + If ($ModuleName -In $ORACLE_MODULES -And ($script:allChangedFiles | Where-Object { $_ -Match '^(src|tests)/Testcontainers\.Oracle' })) { |
| 97 | + Write-Host "Running '$ModuleName': Oracle module changes detected." |
| 98 | + return $True |
| 99 | + } |
| 100 | + |
| 101 | + # Rule 6: xUnit integration variants. |
| 102 | + If ($ModuleName -In $XUNIT_MODULES -And ($script:allChangedFiles | Where-Object { $_ -Match '^(src|tests)/Testcontainers\.Xunit(V3)?' })) { |
| 103 | + Write-Host "Running '$ModuleName': xUnit module changes detected." |
| 104 | + return $True |
| 105 | + } |
| 106 | + |
| 107 | + Write-Host "Skipping '$ModuleName': no relevant changes detected." |
| 108 | + return $False |
| 109 | +} |
| 110 | + |
| 111 | +function Filter-TestProjects { |
| 112 | + [CmdletBinding()] |
| 113 | + Param ( |
| 114 | + [Parameter(ValueFromPipeline = $True)] |
| 115 | + $TestProject |
| 116 | + ) |
| 117 | + |
| 118 | + Begin { |
| 119 | + $script:branch = $env:GITHUB_REF_NAME |
| 120 | + $script:allChangedFiles = $env:ALL_CHANGED_FILES -Split "`n" |
| 121 | + $script:filteredModules = @() |
| 122 | + |
| 123 | + Write-Host "Filtering test projects for branch '$script:branch'." |
| 124 | + Write-Host "Analyzing $($script:allChangedFiles.Count) changed file(s)." |
| 125 | + } |
| 126 | + |
| 127 | + Process { |
| 128 | + If (Should-RunTests $TestProject.name) { |
| 129 | + $script:filteredModules += $TestProject |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + End { |
| 134 | + Write-Host "Filtered $($script:filteredModules.Count) module(s) will run." |
| 135 | + $script:filteredModules |
| 136 | + } |
18 | 137 | } |
| 138 | + |
| 139 | +$input | Filter-TestProjects |
0 commit comments