Skip to content

Commit 593912e

Browse files
authored
chore: Add script to detect which tests to run in CI (#1563)
1 parent 4a72cb3 commit 593912e

File tree

4 files changed

+141
-10
lines changed

4 files changed

+141
-10
lines changed

.github/scripts/Collect-TestProjects.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ If ($runsOnNotFound) {
2626
}
2727

2828
# Filter projects and output as compressed JSON.
29-
$testProjects | & (Join-Path $PSScriptRoot 'Filter-TestProjects.ps1') | ConvertTo-Json -Compress
29+
$filteredTestProjects = $testProjects | & (Join-Path $PSScriptRoot 'Filter-TestProjects.ps1') | ConvertTo-Json -AsArray -Compress
30+
$filteredTestProjects ?? "[]"
Lines changed: 130 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,139 @@
11
<#
22
.SYNOPSIS
3-
Filters test projects for CI workflows.
3+
Filters test projects based on changed files to optimize CI workflow execution.
44
55
.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
821
#>
922

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"
1350
)
1451

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+
}
18137
}
138+
139+
$input | Filter-TestProjects

.github/workflows/cicd.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,20 @@ jobs:
3939
with:
4040
lfs: true
4141

42+
- id: get-all-changed-files
43+
name: Collect Changed Files
44+
uses: tj-actions/changed-files@v47
45+
4246
- id: set-test-projects
4347
name: Collect Test Projects
4448
shell: pwsh
4549
run: echo "test-projects=$(.github/scripts/Collect-TestProjects.ps1)" >> $env:GITHUB_OUTPUT
50+
env:
51+
ALL_CHANGED_FILES: ${{ steps.get-all-changed-files.outputs.all_changed_files }}
4652

4753
ci:
54+
if: ${{ needs.collect-test-projects.outputs.test-projects != '[]' }}
55+
4856
needs: collect-test-projects
4957

5058
strategy:

.github/workflows/test-report.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ jobs:
3939
use-actions-summary: false
4040
list-suites: failed
4141
list-tests: failed
42+
fail-on-empty: false

0 commit comments

Comments
 (0)