2121 OKTA_DUMMY_CI_PW : ${{ secrets.OKTA_DUMMY_CI_PW }}
2222
2323jobs :
24+ setup :
25+ name : Setup
26+ runs-on : ubuntu-latest
27+ outputs :
28+ dry-run : ${{ steps.check-dry-run.outputs.enabled }}
29+ steps :
30+ - name : Checkout code
31+ uses : actions/checkout@v5
32+ with :
33+ fetch-depth : 2
34+
35+ - name : Check for dry-run mode
36+ id : check-dry-run
37+ run : |
38+ # For PRs, check the actual HEAD commit (not the merge commit)
39+ # For push events, check the latest commit
40+ if [[ "${{ github.event_name }}" == "pull_request" ]]; then
41+ # Get the actual branch HEAD commit message (not the merge commit)
42+ COMMIT_MSG=$(git log -1 --pretty=%B HEAD^2 2>/dev/null || git log -1 --pretty=%B)
43+ PR_TITLE="${{ github.event.pull_request.title }}"
44+ else
45+ COMMIT_MSG=$(git log -1 --pretty=%B)
46+ PR_TITLE=""
47+ fi
48+
49+ echo "Event: ${{ github.event_name }}"
50+ echo "Commit message: $COMMIT_MSG"
51+ echo "PR title: $PR_TITLE"
52+
53+ # Check if [dry-run] appears in commit message or PR title
54+ if [[ "$COMMIT_MSG" == *"[dry-run]"* ]] || [[ "$PR_TITLE" == *"[dry-run]"* ]]; then
55+ echo "enabled=true" >> $GITHUB_OUTPUT
56+ echo "🏃 DRY-RUN MODE ENABLED"
57+ else
58+ echo "enabled=false" >> $GITHUB_OUTPUT
59+ fi
60+
2461 check_formatting :
2562 name : Check Formatting
2663 runs-on : ubuntu-latest
@@ -46,25 +83,13 @@ jobs:
4683 dotnet tool restore
4784 dotnet csharpier check ${{ steps.changed-files.outputs.all_changed_files }}
4885
49- integration-tests :
50- name : Run Integration Tests
86+ unit-tests :
87+ name : Unit Tests
88+ needs : [setup]
5189 runs-on : ubuntu-latest
52- strategy :
53- fail-fast : false
54- matrix :
55- server :
56- - 1.31.20
57- - 1.32.17
58- - 1.33.5
59- - 1.34.0
60-
90+ permissions :
91+ contents : read
6192 steps :
62- - name : Check for required secrets
63- run : |
64- if [ -z "${{ secrets.DOCKER_USERNAME }}" ]; then echo "Warning: DOCKER_USERNAME is not set"; fi
65- if [ -z "${{ secrets.DOCKER_PASSWORD }}" ]; then echo "Warning: DOCKER_PASSWORD is not set"; fi
66- if [ -z "${{ secrets.NUGET_APIKEY }}" ]; then echo "Warning: NUGET_APIKEY is not set"; fi
67-
6893 - name : Checkout code
6994 uses : actions/checkout@v5
7095
@@ -77,72 +102,152 @@ jobs:
77102 uses : actions/cache@v4
78103 with :
79104 path : ~/.nuget/packages
80- key : ${{ runner.os }}-nuget-${{ hashFiles('**/.*proj') }}
105+ key : ${{ runner.os }}-nuget-${{ hashFiles('**/* .*proj') }}
81106 restore-keys : |
82107 ${{ runner.os }}-nuget-
83108
84109 - name : Restore dependencies
85110 run : dotnet restore
86111
87- - name : Run unit tests
88- run : dotnet test --no-restore --filter "FullyQualifiedName~Weaviate.Client.Tests.Unit" --logger "trx;LogFileName=test-unit-results.trx"
112+ - name : Run unit tests with coverage (or dry-run)
113+ run : |
114+ if [[ "${{ needs.setup.outputs.dry-run }}" == "true" ]]; then
115+ echo "🏃 DRY-RUN MODE: Skipping actual test execution"
116+ echo "Would run: dotnet test --no-restore --filter \"FullyQualifiedName~Weaviate.Client.Tests.Unit\" --logger \"trx;LogFileName=test-unit-results.trx\" --collect:\"XPlat Code Coverage\" --results-directory ./test-results"
117+
118+ # Create dummy test results and coverage files
119+ mkdir -p ./test-results
120+ mkdir -p ./test-results/coverage
121+ echo '<?xml version="1.0" encoding="utf-8"?><coverage line-rate="0.85" branch-rate="0.75"><packages><package name="Weaviate.Client" line-rate="0.85" branch-rate="0.75"><classes></classes></package></packages></coverage>' > ./test-results/coverage/coverage.cobertura.xml
122+ echo '<?xml version="1.0" encoding="utf-8"?><TestRun><ResultSummary outcome="Completed"><Counters total="42" executed="42" passed="42" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" /></ResultSummary></TestRun>' > ./test-results/test-unit-results.trx
123+ else
124+ dotnet test --no-restore \
125+ --filter "FullyQualifiedName~Weaviate.Client.Tests.Unit" \
126+ --logger "trx;LogFileName=test-unit-results.trx" \
127+ --collect:"XPlat Code Coverage" \
128+ --results-directory ./test-results
129+ fi
89130
90- - name : Upload unit test results on failure
131+ - name : Upload test results
132+ uses : actions/upload-artifact@v4
91133 if : failure()
134+ with :
135+ name : test-results-unit
136+ path : ./test-results/*.trx
137+ retention-days : 7
138+
139+ - name : Upload coverage data
92140 uses : actions/upload-artifact@v4
141+ if : always()
93142 with :
94- name : test-results- unit-${{ matrix.server }}
95- path : src/Weaviate.Client.Tests/TestResults/ test-unit- results.trx
96- retention-days : 3
143+ name : coverage- unit
144+ path : ./ test-results/**/coverage.cobertura.xml
145+ retention-days : 7
97146
98- - name : Login to Docker Hub
99- uses : docker/login-action@v3
100- if : ${{ !github.event.pull_request.head.repo.fork && github.triggering_actor != 'dependabot[bot]' }}
147+ # =============================================================================
148+ # Integration Tests - All Weaviate Versions
149+ # To add a new version: Add it to the matrix.version array below
150+ # =============================================================================
151+ test-weaviate-versions :
152+ name : Test on Weaviate v${{ matrix.version }}
153+ permissions :
154+ contents : read
155+ needs : [unit-tests, setup]
156+ strategy :
157+ fail-fast : false
158+ matrix :
159+ version : ["1.31.16", "1.32.11", "1.33.0", "1.34.0-rc.0"]
160+ uses : ./.github/workflows/test-on-weaviate-version.yml
161+ secrets : inherit
162+ with :
163+ weaviate-version : ${{ matrix.version }}
164+ dry-run : ${{ needs.setup.outputs.dry-run == 'true' }}
165+ run-slow-tests : ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && !github.event.pull_request.draft && !contains(github.event.pull_request.body, '[skip-slow]')) }}
166+
167+ test-summary :
168+ name : Test Summary
169+ needs :
170+ - setup
171+ - unit-tests
172+ - test-weaviate-versions
173+ runs-on : ubuntu-latest
174+ if : always()
175+ permissions :
176+ pull-requests : write
177+ steps :
178+ - name : Checkout code
179+ uses : actions/checkout@v5
180+
181+ - name : Setup .NET
182+ uses : actions/setup-dotnet@v5
101183 with :
102- username : ${{secrets.DOCKER_USERNAME}}
103- password : ${{secrets.DOCKER_PASSWORD}}
184+ dotnet-version : ${{ env.DOTNET_VERSION }}
185+
186+ - name : Download all coverage artifacts
187+ uses : actions/download-artifact@v4
188+ with :
189+ pattern : coverage-*
190+ path : ./all-coverage
191+ merge-multiple : true
104192
105- - name : start weaviate
106- run : /bin/bash ci/start_weaviate.sh ${{ matrix.server }}
193+ - name : Install ReportGenerator
194+ run : dotnet tool install -g dotnet-reportgenerator-globaltool
107195
108- - name : Run quick integration tests
196+ - name : Generate coverage report
109197 run : |
110- dotnet test --no-restore --filter "(Category!=Slow&FullyQualifiedName~Weaviate.Client.Tests.Integration)" --logger "trx;LogFileName=test-integration-quick-results.trx"
198+ reportgenerator \
199+ -reports:"./all-coverage/**/coverage.cobertura.xml" \
200+ -targetdir:"./coveragereport" \
201+ -reporttypes:"Html;MarkdownSummary;Cobertura" \
202+ -title:"Weaviate C# Client Coverage"
111203
112- - name : Upload integration test results on failure
113- if : failure()
204+ - name : Upload HTML coverage report
114205 uses : actions/upload-artifact@v4
115206 with :
116- name : test-results-integration-quick-${{ matrix.server }}
117- path : src/Weaviate.Client.Tests/TestResults/test-integration-quick-results.trx
118- retention-days : 3
119-
120- - name : Run slow integration tests
121- run : |
122- dotnet test --no-restore --filter "(Category=Slow&FullyQualifiedName~Weaviate.Client.Tests.Integration)" --logger "trx;LogFileName=test-integration-slow-results.trx"
207+ name : coverage-report-html
208+ path : ./coveragereport
209+ retention-days : 30
123210
124- - name : Upload integration test results on failure
125- if : failure()
126- uses : actions/upload-artifact@v4
211+ - name : Add coverage to PR comment
212+ uses : marocchino/sticky-pull-request-comment@v2
213+ if : github.event_name == 'pull_request'
127214 with :
128- name : test-results-integration-slow-${{ matrix.server }}
129- path : src/Weaviate.Client.Tests/TestResults/test-integration-slow-results.trx
130- retention-days : 3
131-
132- - name : stop weaviate
133- if : always()
134- run : /bin/bash ci/stop_weaviate.sh ${{ matrix.server }}
215+ header : coverage
216+ path : ./coveragereport/Summary.md
135217
136- - name : Test Report
218+ - name : Download all test results
219+ uses : actions/download-artifact@v4
137220 continue-on-error : true
138- if : always()
221+ with :
222+ pattern : test-results-*
223+ path : ./all-test-results
224+
225+ - name : Generate test summary
226+ run : |
227+ if [[ "${{ needs.setup.outputs.dry-run }}" == "true" ]]; then
228+ echo "🏃 DRY-RUN MODE: Skipping test summary generation"
229+ elif [ -d "./all-test-results" ] && [ -n "$(find ./all-test-results -name "*.trx" 2>/dev/null)" ]; then
230+ echo "📊 Generating test summary from TRX files..."
231+ dotnet tool update -g dotnet-trx
232+ find ./all-test-results -name "*.trx" -exec trx {} \;
233+ else
234+ echo "✅ No test failures - all tests passed!"
235+ fi
236+
237+ - name : Check test status
139238 run : |
140- dotnet tool update -g dotnet-trx
141- trx
239+ if [ "${{ needs.unit-tests.result }}" != "success" ]; then
240+ echo "Unit tests failed"
241+ exit 1
242+ fi
243+ if [ "${{ needs.test-weaviate-versions.result }}" != "success" ]; then
244+ echo "Integration tests failed on one or more Weaviate versions"
245+ exit 1
246+ fi
142247
143248 build-and-publish :
144249 name : Build and Publish to NuGet
145- needs : [integration-tests ]
250+ needs : [test-summary ]
146251 runs-on : ubuntu-latest
147252 if : startsWith(github.ref, 'refs/tags')
148253 permissions :
0 commit comments