Skip to content

Bump actions/download-artifact from 4 to 5 #13

Bump actions/download-artifact from 4 to 5

Bump actions/download-artifact from 4 to 5 #13

Workflow file for this run

---
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.
#
# We use coverage to collect coverage data but we currently
# do not upload / use it because combining Windows and Linux
# coverage is challenging.
#
# We therefore have a few ``# pragma: no cover`` statements.
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 }}
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@v5
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