Skip to content

Commit fca0cfc

Browse files
committed
feat: Implement CI workflows for integration testing and add dry-run support
test: Adjust cancellation delay in GetMeta_CancellationDuringDelay test Potential fix for code scanning alert no. 7: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Potential fix for code scanning alert no. 11: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Potential fix for code scanning alert no. 6: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> fix: Add missing permissions for integration test jobs in CI workflow fix: Add missing permissions for test-weaviate-versions job in CI workflow
1 parent ef802a9 commit fca0cfc

File tree

6 files changed

+345
-59
lines changed

6 files changed

+345
-59
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Integration Test Template
2+
permissions:
3+
contents: read
4+
5+
on:
6+
workflow_call:
7+
inputs:
8+
test-category:
9+
description: 'Test category (quick, slow, or rbac)'
10+
required: true
11+
type: string
12+
test-filter:
13+
description: 'dotnet test filter expression'
14+
required: true
15+
type: string
16+
weaviate-version:
17+
description: 'Single Weaviate version to test'
18+
required: true
19+
type: string
20+
dry-run:
21+
description: 'Skip actual test execution (for testing workflow)'
22+
required: false
23+
type: boolean
24+
default: false
25+
26+
jobs:
27+
integration-test:
28+
name: Integration Tests (${{ inputs.test-category }}) - Weaviate ${{ inputs.weaviate-version }}
29+
runs-on: ubuntu-latest
30+
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v5
34+
35+
- name: Setup .NET
36+
uses: actions/setup-dotnet@v5
37+
with:
38+
dotnet-version: ${{ env.DOTNET_VERSION }}
39+
40+
- name: Cache NuGet packages
41+
uses: actions/cache@v4
42+
with:
43+
path: ~/.nuget/packages
44+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.*proj') }}
45+
restore-keys: |
46+
${{ runner.os }}-nuget-
47+
48+
- name: Restore dependencies
49+
run: dotnet restore
50+
51+
- name: Login to Docker Hub
52+
uses: docker/login-action@v3
53+
if: ${{ !github.event.pull_request.head.repo.fork && github.triggering_actor != 'dependabot[bot]' }}
54+
with:
55+
username: ${{ secrets.DOCKER_USERNAME }}
56+
password: ${{ secrets.DOCKER_PASSWORD }}
57+
58+
- name: Start Weaviate
59+
if: ${{ !inputs.dry-run }}
60+
run: /bin/bash ci/start_weaviate.sh ${{ inputs.weaviate-version }}
61+
62+
- name: Run integration tests with coverage
63+
run: |
64+
if [[ "${{ inputs.dry-run }}" == "true" ]]; then
65+
echo "🏃 DRY-RUN MODE: Skipping actual test execution"
66+
echo "Would run: dotnet test --no-restore --filter \"${{ inputs.test-filter }}\" --logger \"trx;LogFileName=test-integration-${{ inputs.test-category }}-${{ inputs.weaviate-version }}.trx\" --collect:\"XPlat Code Coverage\" --results-directory ./test-results"
67+
68+
# Create dummy test results and coverage files for workflow validation
69+
mkdir -p ./test-results
70+
mkdir -p ./test-results/coverage
71+
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
72+
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-integration-${{ inputs.test-category }}-${{ inputs.weaviate-version }}.trx
73+
else
74+
dotnet test --no-restore \
75+
--filter "${{ inputs.test-filter }}" \
76+
--logger "trx;LogFileName=test-integration-${{ inputs.test-category }}-${{ inputs.weaviate-version }}.trx" \
77+
--collect:"XPlat Code Coverage" \
78+
--results-directory ./test-results
79+
fi
80+
81+
- name: Stop Weaviate
82+
if: always() && !inputs.dry-run
83+
run: /bin/bash ci/stop_weaviate.sh ${{ inputs.weaviate-version }}
84+
85+
- name: Upload test results
86+
uses: actions/upload-artifact@v4
87+
if: failure()
88+
with:
89+
name: test-results-integration-${{ inputs.test-category }}-${{ inputs.weaviate-version }}
90+
path: ./test-results/*.trx
91+
retention-days: 7
92+
93+
- name: Upload coverage data
94+
uses: actions/upload-artifact@v4
95+
if: always()
96+
with:
97+
name: coverage-integration-${{ inputs.test-category }}-${{ inputs.weaviate-version }}
98+
path: ./test-results/**/coverage.cobertura.xml
99+
retention-days: 7
100+
101+
- name: Test Report
102+
uses: dorny/test-reporter@v1
103+
if: always() && !inputs.dry-run
104+
with:
105+
name: ${{ inputs.test-category }} Integration Tests - Weaviate ${{ inputs.weaviate-version }}
106+
path: ./test-results/*.trx
107+
reporter: dotnet-trx
108+
fail-on-error: false

.github/workflows/main.yaml

Lines changed: 162 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,43 @@ env:
2121
OKTA_DUMMY_CI_PW: ${{ secrets.OKTA_DUMMY_CI_PW }}
2222

2323
jobs:
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

Comments
 (0)