-
Notifications
You must be signed in to change notification settings - Fork 0
196 lines (192 loc) · 7.82 KB
/
Copy pathtests.yml
File metadata and controls
196 lines (192 loc) · 7.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
---
name: Tests
on:
push:
branches: [main, 'v[0-9]+.[0-9]+.[0-9]+*']
paths-ignore:
- '**.md'
- docs/**
- assets/**
- .github/workflows/**
pull_request:
branches: [main, 'v[0-9]+.[0-9]+.[0-9]+*']
paths-ignore:
- '**.md'
- docs/**
- assets/**
- .github/workflows/**
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
# renovate: datasource=python-version depName=python
PYTHON_VERSION: 3.13.11
COVERAGE_THRESHOLD: 80
ARTIFACT_RETENTION_DAYS: 7
jobs:
changes:
name: File Detection
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
python: ${{ steps.python_changes.outputs.any_changed }}
tests: ${{ steps.test_changes.outputs.any_changed }}
# Only run tests when Python source code changes (not test files or workflow files)
any: ${{ steps.python_changes.outputs.any_changed == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
fetch-depth: 0
- name: Check Python
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47
id: python_changes
with:
files: |
**/*.py
pyproject.toml
uv.lock
files_ignore: |
tests/**/*.py
**/tests/**/*.py
**/migrations/**/*.py
src/tux/database/migrations/**/*.py
- name: Check Tests
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47
id: test_changes
with:
files: |
tests/**
conftest.py
test:
name: Run All Tests
runs-on: ubuntu-latest
timeout-minutes: 60
needs: [changes]
if: needs.changes.outputs.any || github.event_name == 'workflow_dispatch'
permissions:
contents: read
pull-requests: write
# Required for Codecov OIDC authentication
# Allows the action to authenticate with Codecov using OpenID Connect
# instead of requiring a CODECOV_TOKEN secret
id-token: write
strategy:
fail-fast: false
matrix:
python-version: [3.13.11]
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
fetch-depth: 0
- name: Setup Python
uses: ./.github/actions/setup-python
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
- name: Create Test Environment
uses: ./.github/actions/create-test-env
with:
additional-vars: |
BOT_TOKEN=test_token_for_ci
DEBUG=True
- name: Install Coverage Tools
run: |
uv sync --group docs --group test --no-dev
- name: Run All Tests with Coverage
id: run_tests
continue-on-error: true # Continue even if tests fail to upload results
env:
# Disable bytecode generation for faster test execution
PYTHONDONTWRITEBYTECODE: 1
run: |
echo "Running all tests with unified coverage..."
echo "Working directory: $(pwd)"
echo "Python version: $(python --version)"
echo "Pytest version: $(uv run pytest --version || echo 'pytest not found')"
# Run all test types with combined coverage
# Coverage report formats are defined in pyproject.toml (xml, json, lcov, term-missing)
# Use junit_family=legacy for pretty-printed test names in Codecov UI
# Note: --cov-fail-under may cause pytest to exit with error, but coverage.xml should still be generated
uv run pytest \
--junitxml=junit.xml \
-o junit_family=legacy \
--cov-fail-under=${{ env.COVERAGE_THRESHOLD }} \
tests/ | tee pytest-coverage.txt || true
echo "Pytest exit code: $?"
echo "Checking for coverage files..."
ls -la coverage.xml 2>&1 || echo "coverage.xml not found"
ls -la junit.xml 2>&1 || echo "junit.xml not found"
echo "All tests completed with unified coverage"
# Verify coverage file exists and contains data before uploading
# Only verify if tests completed (coverage.xml may not exist if tests failed)
- name: Verify Coverage File
id: verify_coverage
if: ${{ !cancelled() }}
continue-on-error: true
run: |
echo "Checking for coverage.xml..."
echo "Current directory: $(pwd)"
echo "Files in current directory (first 20):"
find . -maxdepth 1 -type f 2>/dev/null | head -20
if [ ! -f coverage.xml ]; then
echo "⚠️ Warning: coverage.xml not found"
echo "Checking if tests actually ran..."
if [ -f pytest-coverage.txt ]; then
echo "pytest-coverage.txt exists, showing last 50 lines:"
tail -50 pytest-coverage.txt
else
echo "pytest-coverage.txt also not found - tests may not have run"
fi
echo "coverage_exists=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "✅ Coverage file exists"
echo "File size: $(wc -c < coverage.xml) bytes"
echo "First 30 lines of coverage.xml:"
head -30 coverage.xml
echo "coverage_exists=true" >> "$GITHUB_OUTPUT"
# Upload coverage to Codecov (requires GitHub OIDC)
# Note: OIDC authentication requires GitHub Actions environment and won't work with act (local testing)
# The step will fail gracefully due to fail_ci_if_error: false, allowing tests to pass in act
- name: Upload Coverage to Codecov
if: ${{ !cancelled() && steps.verify_coverage.outputs.coverage_exists == 'true' }}
continue-on-error: true
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
with:
# Explicitly specify the coverage XML file to upload (generated by pytest)
files: coverage.xml
# Custom upload name visible in Codecov UI
name: tux
# Don't fail CI if Codecov upload fails (coverage is optional, tests are required)
fail_ci_if_error: false
# Enable verbose logging for troubleshooting upload issues
verbose: true
# Use OIDC (OpenID Connect) for authentication instead of CODECOV_TOKEN
# Requires id-token: write permission (configured in job permissions)
use_oidc: true
# Upload test results to Codecov for Test Analytics
# Provides insights into test run times, failure rates, and flaky tests
# Test Analytics features:
# - Overview of test run times and failure rates
# - List of failed tests in PR comments with stack traces
# - Identification of flaky tests that failed on your PR
- name: Upload Test Results to Codecov
if: ${{ !cancelled() }}
continue-on-error: true # Don't fail CI if test results upload fails
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1
with:
# JUnit XML file generated by pytest (with junit_family=legacy for pretty names)
file: junit.xml
# Note: If this step fails with authentication errors, the action may not support OIDC.
# In that case, uncomment the token line below and add CODECOV_TOKEN to repository secrets.
# token: ${{ secrets.CODECOV_TOKEN }}
# Optimize cache for CI: Remove pre-built wheels, keep source-built wheels
# This improves cache efficiency by only keeping wheels that take time to build
# Docs: https://docs.astral.sh/uv/concepts/cache/#caching-in-continuous-integration
- name: Prune uv cache for CI
if: always()
run: uv cache prune --ci