Skip to content

docs: Update README.md #42

docs: Update README.md

docs: Update README.md #42

Workflow file for this run

name: "Tests"
description: "Build and test Python package"
on:
push:
branches: [main]
pull_request:
types:
[opened, synchronize, reopened]
workflow_dispatch:
inputs:
ref:
description: 'Git ref to scan'
required: false
type: string
default: 'main'
test-filepath:
description: 'Filepath to testsets'
required: true
type: string
default: 'tests/'
python-version:
description: 'Python version'
required: true
type: string
default: '3.13'
permissions:
contents: read
pull-requests: read
jobs:
build_and_test:
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.labels.*.name, 'version-bump')"
steps:
- name: Checkout Repository
id: checkout-repo
uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.ref || github.ref }}
- name: Set up Python
id: setup_python
uses: actions/setup-python@v5
with:
python-version: ${{ github.event.inputs.ref || '3.13' }}
cache: 'pip'
- name: Install Python Build Tools
id: install-dependencies
run: |
python -m pip install --upgrade pip
pip install build pytest pytest-cov
# Install the package itself in editable mode
if [ -f "pyproject.toml" ] || [ -f "setup.py" ]; then
pip install -e '.[dev,mcp]'
fi
# Install additional requirements if they exist
if [ -f "requirements.txt" ]; then
pip install -r requirements.txt
fi
if [ -f "requirements-dev.txt" ]; then
pip install -r requirements-dev.txt
fi
- name: Install specific FFmpeg version
id: install-ffmpeg
shell: bash
run: |
sudo apt update
sudo apt install -y ffmpeg
- name: Run Tests on Candidate Branch
id: run-tests
run: |
# Determine test path (use input if workflow_dispatch, otherwise use default)
TEST_PATH="${{ github.event.inputs.test-filepath || 'tests/' }}"
echo "Running tests from: $TEST_PATH"
# Run pytest with coverage
pytest "$TEST_PATH" \
-v \
--cov \
--cov-report=term-missing \
--cov-report=xml:coverage.xml \
--cov-report=html:htmlcov \
--junitxml=pytest-results.xml \
| tee pytest-output.log
# Capture exit code but don't fail yet
PYTEST_EXIT_CODE=$?
echo "pytest_exit_code=$PYTEST_EXIT_CODE" >> $GITHUB_OUTPUT
exit $PYTEST_EXIT_CODE
- name: Parse Test Results
if: always()
id: parse-results
run: |
python <<'EOF'
import xml.etree.ElementTree as ET
import os
try:
# Parse coverage
cov_tree = ET.parse("coverage.xml")
cov_root = cov_tree.getroot()
coverage = round(float(cov_root.attrib["line-rate"]) * 100, 2)
except Exception as e:
print(f"Warning: Could not parse coverage: {e}")
coverage = 0.0
try:
# Parse test results
test_tree = ET.parse("pytest-results.xml")
test_root = test_tree.getroot()
suite = test_root.find("testsuite") or test_root
total = int(suite.attrib.get("tests", 0))
failures = int(suite.attrib.get("failures", 0))
errors = int(suite.attrib.get("errors", 0))
skipped = int(suite.attrib.get("skipped", 0))
passed = total - failures - errors - skipped
pass_rate = round((passed / total * 100) if total > 0 else 0, 2)
except Exception as e:
print(f"Error parsing test results: {e}")
total = passed = failures = errors = skipped = 0
pass_rate = 0.0
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"coverage={coverage}\n")
f.write(f"total_tests={total}\n")
f.write(f"passed_tests={passed}\n")
f.write(f"failed_tests={failures + errors}\n")
f.write(f"skipped_tests={skipped}\n")
f.write(f"pass_rate={pass_rate}\n")
print(f"✓ Coverage: {coverage}%")
print(f"✓ Tests: {passed}/{total} passed ({pass_rate}%)")
EOF
- name: Generate Markdown Summary
if: always()
run: |
cat >> $GITHUB_STEP_SUMMARY <<EOF
## Test Results
- **Total Tests:** ${{ steps.parse-results.outputs.total_tests }}
- **Passed:** ✅ ${{ steps.parse-results.outputs.passed_tests }}
- **Failed:** ❌ ${{ steps.parse-results.outputs.failed_tests }}
- **Skipped:** ⏭️ ${{ steps.parse-results.outputs.skipped_tests }}
- **Pass Rate:** ${{ steps.parse-results.outputs.pass_rate }}%
- **Coverage:** ${{ steps.parse-results.outputs.coverage }}%
EOF
- name: Upload Test Results
id: upload-results
uses: actions/upload-artifact@v4
with:
name: pytest-results
path: |
pytest-results.xml
pytest-output.log
coverage.xml
htmlcov/
retention-days: 30
- name: Upload Coverage Reports to Codecov
id: upload-coverage-codecov
if: always()
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.xml
fail_ci_if_error: false
continue-on-error: true
- name: Fail If Tests Failed
id: test-status
if: always() && steps.parse-results.outputs.failed_tests != '0'
run: |
echo "::error::${{ steps.parse-results.outputs.failed_tests }} test(s) failed"
echo "::error::Pass rate: ${{ steps.parse-results.outputs.pass_rate }}%"
echo "::error::Passed: ${{ steps.parse-results.outputs.passed_tests }}/${{ steps.parse-results.outputs.total_tests }}"
exit 1