Replace codecov with combined report #6
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
name: Test | |
on: | |
push: | |
branches: [main] | |
pull_request: | |
branches: [main] | |
schedule: | |
# * is a special character in YAML so you have to quote this string | |
# Run at 1:00 every day | |
- cron: 0 1 * * * | |
workflow_dispatch: {} | |
# We share Vuforia credentials and therefore Vuforia databases across | |
# workflows. We therefore want to run only one workflow at a time. | |
concurrency: vuforia_credentials | |
jobs: | |
# CI tests with matrix | |
ci-tests: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
python-version: ['3.13'] | |
ci_pattern: | |
- tests/mock_vws/test_query.py::TestContentType | |
- tests/mock_vws/test_query.py::TestSuccess | |
- tests/mock_vws/test_query.py::TestIncorrectFields | |
- tests/mock_vws/test_query.py::TestMaxNumResults | |
- tests/mock_vws/test_query.py::TestIncludeTargetData | |
- tests/mock_vws/test_query.py::TestAcceptHeader | |
- tests/mock_vws/test_query.py::TestActiveFlag | |
- tests/mock_vws/test_query.py::TestBadImage | |
- tests/mock_vws/test_query.py::TestMaximumImageFileSize | |
- tests/mock_vws/test_query.py::TestMaximumImageDimensions | |
- tests/mock_vws/test_query.py::TestImageFormats | |
- tests/mock_vws/test_query.py::TestProcessing | |
- tests/mock_vws/test_query.py::TestUpdate | |
- tests/mock_vws/test_query.py::TestDeleted | |
- tests/mock_vws/test_query.py::TestTargetStatusFailed | |
- tests/mock_vws/test_query.py::TestDateFormats | |
- tests/mock_vws/test_query.py::TestInactiveProject | |
- tests/mock_vws/test_add_target.py::TestContentTypes | |
- tests/mock_vws/test_add_target.py::TestMissingData | |
- tests/mock_vws/test_add_target.py::TestWidth | |
- tests/mock_vws/test_add_target.py::TestTargetName | |
- tests/mock_vws/test_add_target.py::TestImage | |
- tests/mock_vws/test_add_target.py::TestActiveFlag | |
- tests/mock_vws/test_add_target.py::TestUnexpectedData | |
- tests/mock_vws/test_add_target.py::TestApplicationMetadata | |
- tests/mock_vws/test_add_target.py::TestInactiveProject | |
- tests/mock_vws/test_authorization_header.py::TestAuthorizationHeader | |
- tests/mock_vws/test_authorization_header.py::TestMalformed::test_one_part_no_space | |
- tests/mock_vws/test_authorization_header.py::TestMalformed::test_one_part_with_space | |
- tests/mock_vws/test_authorization_header.py::TestMalformed::test_missing_signature | |
- tests/mock_vws/test_authorization_header.py::TestBadKey | |
- tests/mock_vws/test_content_length.py::TestIncorrect::test_not_integer | |
- tests/mock_vws/test_content_length.py::TestIncorrect::test_too_large | |
- tests/mock_vws/test_content_length.py::TestIncorrect::test_too_small | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_success | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_active_images | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_failed_images | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_inactive_images | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_inactive_failed | |
- tests/mock_vws/test_database_summary.py::TestDatabaseSummary::test_deleted | |
- tests/mock_vws/test_database_summary.py::TestProcessingImages | |
- tests/mock_vws/test_database_summary.py::TestQuotas | |
- tests/mock_vws/test_database_summary.py::TestRecos | |
- tests/mock_vws/test_database_summary.py::TestRequestUsage | |
- tests/mock_vws/test_database_summary.py::TestInactiveProject | |
- tests/mock_vws/test_date_header.py::TestFormat | |
- tests/mock_vws/test_date_header.py::TestMissing | |
- tests/mock_vws/test_date_header.py::TestSkewedTime::test_date_out_of_range_after | |
- tests/mock_vws/test_date_header.py::TestSkewedTime::test_date_out_of_range_before | |
- tests/mock_vws/test_date_header.py::TestSkewedTime::test_date_in_range_after | |
- tests/mock_vws/test_date_header.py::TestSkewedTime::test_date_in_range_before | |
- tests/mock_vws/test_delete_target.py | |
- tests/mock_vws/test_get_duplicates.py | |
- tests/mock_vws/test_get_target.py | |
- tests/mock_vws/test_invalid_given_id.py | |
- tests/mock_vws/test_invalid_json.py::TestInvalidJSON::test_invalid_json | |
- tests/mock_vws/test_invalid_json.py::TestInvalidJSON::test_invalid_json_with_skewed_time | |
- tests/mock_vws/test_target_list.py | |
- tests/mock_vws/test_target_raters.py | |
- tests/mock_vws/test_target_summary.py | |
- tests/mock_vws/test_unexpected_json.py | |
- tests/mock_vws/test_update_target.py::TestActiveFlag | |
- tests/mock_vws/test_update_target.py::TestApplicationMetadata::test_base64_encoded | |
- tests/mock_vws/test_update_target.py::TestApplicationMetadata::test_invalid_type | |
- tests/mock_vws/test_update_target.py::TestApplicationMetadata::test_not_base64_encoded_processable | |
- tests/mock_vws/test_update_target.py::TestApplicationMetadata::test_not_base64_encoded_not_processable | |
- tests/mock_vws/test_update_target.py::TestApplicationMetadata::test_metadata_too_large | |
- tests/mock_vws/test_update_target.py::TestImage::test_image_valid | |
- tests/mock_vws/test_update_target.py::TestImage::test_bad_image_format_or_color_space | |
- tests/mock_vws/test_update_target.py::TestImage::test_corrupted | |
- tests/mock_vws/test_update_target.py::TestImage::test_image_too_large | |
- tests/mock_vws/test_update_target.py::TestImage::test_not_base64_encoded_processable | |
- tests/mock_vws/test_update_target.py::TestImage::test_not_base64_encoded_not_processable | |
- tests/mock_vws/test_update_target.py::TestImage::test_not_image | |
- tests/mock_vws/test_update_target.py::TestImage::test_invalid_type | |
- tests/mock_vws/test_update_target.py::TestImage::test_rating_can_change | |
- tests/mock_vws/test_update_target.py::TestTargetName::test_name_valid | |
- tests/mock_vws/test_update_target.py::TestTargetName::test_name_invalid | |
- tests/mock_vws/test_update_target.py::TestTargetName::test_existing_target_name | |
- tests/mock_vws/test_update_target.py::TestTargetName::test_same_name_given | |
- tests/mock_vws/test_update_target.py::TestUnexpectedData | |
- tests/mock_vws/test_update_target.py::TestUpdate | |
- tests/mock_vws/test_update_target.py::TestWidth | |
- tests/mock_vws/test_update_target.py::TestInactiveProject | |
- tests/mock_vws/test_requests_mock_usage.py | |
- tests/mock_vws/test_flask_app_usage.py | |
- tests/mock_vws/test_docker.py | |
- README.rst | |
- docs/source/basic-example.rst | |
steps: | |
- uses: actions/checkout@v5 | |
- name: Install uv | |
uses: astral-sh/setup-uv@v6 | |
with: | |
enable-cache: true | |
cache-dependency-glob: '**/pyproject.toml' | |
- name: Set secrets file | |
run: | | |
# See the "CI Setup" document for details of how this was set up. | |
ci/decrypt_secret.sh | |
tar xvf "${HOME}"/secrets/secrets.tar | |
cp ./ci_secrets/vuforia_secrets_${{ strategy.job-index }}.env ./vuforia_secrets.env | |
env: | |
CI_PATTERN: ${{ matrix.ci_pattern }} | |
ENCRYPTED_FILE: secrets.tar.gpg | |
LARGE_SECRET_PASSPHRASE: ${{ secrets.PASSPHRASE_FOR_VUFORIA_SECRETS }} | |
# We have seen issues with running out of disk space on test_docker | |
- name: Free Disk Space (Ubuntu) | |
uses: jlumbroso/free-disk-space@main | |
if: matrix.ci_pattern == 'tests/mock_vws/test_docker.py' | |
with: | |
# All of these default to true (meaning they are removed). | |
docker-images: false | |
large-packages: false | |
swap-storage: false | |
tool-cache: false | |
android: true | |
dotnet: true | |
haskell: true | |
- name: Run tests | |
run: | | |
uv run --extra=dev \ | |
coverage run \ | |
--parallel-mode \ | |
--source=src/ \ | |
--source=tests/ \ | |
-m pytest \ | |
-s \ | |
-vvv \ | |
--showlocals \ | |
--exitfirst \ | |
${{ matrix.ci_pattern }} | |
env: | |
UV_PYTHON: ${{ matrix.python-version }} | |
- name: Sanitize pattern for artifact name | |
id: sanitize | |
run: | | |
SANITIZED_PATTERN=$(echo "${{ matrix.ci_pattern }}" | sed 's/::/-/g' | sed 's/:/-/g' | sed 's|/|-|g') | |
echo "name=coverage-data-ci-${{ matrix.python-version }}-${SANITIZED_PATTERN}" >> "$GITHUB_OUTPUT" | |
- name: Upload coverage data | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ steps.sanitize.outputs.name }} | |
path: .coverage.* | |
include-hidden-files: true | |
if-no-files-found: error | |
# Skip tests | |
skip-tests: | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
python-version: ['3.13'] | |
platform: [ubuntu-latest] | |
steps: | |
- uses: actions/checkout@v5 | |
- name: Install uv | |
uses: astral-sh/setup-uv@v6 | |
with: | |
enable-cache: true | |
cache-dependency-glob: '**/pyproject.toml' | |
- name: Set secrets file | |
run: | | |
cp ./vuforia_secrets.env.example ./vuforia_secrets.env | |
- name: Run tests | |
run: | | |
uv run --extra=dev \ | |
coverage run \ | |
--parallel-mode \ | |
--source=src/ \ | |
--source=tests/ \ | |
-m pytest \ | |
--skip-docker_build_tests \ | |
--skip-docker_in_memory \ | |
--skip-mock \ | |
--skip-real \ | |
--capture=no \ | |
-vvv \ | |
--exitfirst \ | |
. | |
env: | |
UV_PYTHON: ${{ matrix.python-version }} | |
- name: Upload coverage data | |
uses: actions/upload-artifact@v4 | |
with: | |
name: coverage-data-skip-tests-${{ matrix.python-version }} | |
path: .coverage.* | |
include-hidden-files: true | |
if-no-files-found: error | |
# Windows tests | |
windows-tests: | |
runs-on: windows-latest | |
strategy: | |
matrix: | |
python-version: ['3.13'] | |
steps: | |
- uses: actions/checkout@v5 | |
- name: Install uv | |
uses: astral-sh/setup-uv@v6 | |
with: | |
enable-cache: true | |
cache-dependency-glob: '**/pyproject.toml' | |
- name: Set secrets file | |
run: | | |
cp ./vuforia_secrets.env.example ./vuforia_secrets.env | |
- name: Run tests | |
shell: bash | |
run: | | |
# We use pytest-xdist to make this run much faster. | |
# The downside is that we cannot use -s / --capture=no. | |
uv run --extra=dev \ | |
coverage run \ | |
--parallel-mode \ | |
--source=src/ \ | |
--source=tests/ \ | |
-m pytest \ | |
--skip-real \ | |
-vvv \ | |
--exitfirst \ | |
-n auto \ | |
. | |
env: | |
UV_PYTHON: ${{ matrix.python-version }} | |
- name: Upload coverage data | |
uses: actions/upload-artifact@v4 | |
with: | |
name: coverage-data-windows-${{ matrix.python-version }} | |
path: .coverage.* | |
include-hidden-files: true | |
if-no-files-found: error | |
# Coverage combination and enforcement | |
coverage: | |
name: Combine & check coverage | |
needs: [ci-tests, skip-tests, windows-tests] | |
if: always() | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v5 | |
- name: Install uv | |
uses: astral-sh/setup-uv@v6 | |
with: | |
enable-cache: true | |
cache-dependency-glob: '**/pyproject.toml' | |
- uses: actions/download-artifact@v4 | |
with: | |
pattern: coverage-data-* | |
merge-multiple: true | |
- name: Require 100% Coverage | |
id: coverage | |
run: | | |
uv tool install 'coverage[toml]' | |
coverage combine | |
coverage html --skip-covered --skip-empty | |
# Report and write to summary. | |
coverage report --format=markdown >> "$GITHUB_STEP_SUMMARY" | |
# Report again and fail if under 100%. | |
coverage report --fail-under=100 | |
- name: Upload HTML report if check failed | |
uses: actions/upload-artifact@v4 | |
with: | |
name: html-report | |
path: htmlcov | |
if: ${{ failure() }} | |
# Final completion check | |
completion: | |
needs: [ci-tests, skip-tests, windows-tests, coverage] | |
runs-on: ubuntu-latest | |
if: always() | |
steps: | |
- name: Check all jobs status | |
run: |- | |
if ! ${{ needs.ci-tests.result == 'success' }}; then | |
echo "CI tests failed" | |
exit 1 | |
fi | |
if ! ${{ needs.skip-tests.result == 'success' }}; then | |
echo "Skip tests failed" | |
exit 1 | |
fi | |
if ! ${{ needs.windows-tests.result == 'success' }}; then | |
echo "Windows tests failed" | |
exit 1 | |
fi | |
if ! ${{ needs.coverage.result == 'success' }}; then | |
echo "Coverage check failed" | |
exit 1 | |
fi |