diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 91fa442775..1af19857c1 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -38,6 +38,7 @@ post: # Disabled, causing timeouts # - func: "upload working dir" - func: "teardown system" + - func: "upload codecov" - func: "upload coverage" - func: "upload mo artifacts" - func: "upload test results" diff --git a/.evergreen/generated_configs/functions.yml b/.evergreen/generated_configs/functions.yml index bd983abb3e..6fcda5e985 100644 --- a/.evergreen/generated_configs/functions.yml +++ b/.evergreen/generated_configs/functions.yml @@ -252,6 +252,24 @@ functions: - TOOLCHAIN_VERSION type: test + # Upload coverage codecov + upload codecov: + - command: subprocess.exec + params: + binary: bash + args: + - .evergreen/scripts/upload-codecov.sh + working_dir: src + include_expansions_in_env: + - CODECOV_TOKEN + - build_variant + - task_name + - github_commit + - github_pr_number + - github_pr_head_branch + - github_author + type: test + # Upload coverage upload coverage: - command: ec2.assume_role diff --git a/.evergreen/scripts/generate_config.py b/.evergreen/scripts/generate_config.py index 04579c521f..6eb33741cc 100644 --- a/.evergreen/scripts/generate_config.py +++ b/.evergreen/scripts/generate_config.py @@ -318,7 +318,7 @@ def create_green_framework_variants(): def create_no_c_ext_variants(): host = DEFAULT_HOST tasks = [".test-standard"] - expansions = dict() + expansions = dict(COVERAGE=1) handle_c_ext(C_EXTS[0], expansions) display_name = get_variant_name("No C Ext", host) return [create_variant(tasks, display_name, host=host)] @@ -1077,6 +1077,24 @@ def create_upload_coverage_func(): return "upload coverage", [get_assume_role(), cmd] +def create_upload_coverage_codecov_func(): + # Upload the coverage xml report to codecov. + include_expansions = [ + "CODECOV_TOKEN", + "build_variant", + "task_name", + "github_commit", + "github_pr_number", + "github_pr_head_branch", + "github_author", + ] + args = [ + ".evergreen/scripts/upload-codecov.sh", + ] + upload_cmd = get_subprocess_exec(include_expansions_in_env=include_expansions, args=args) + return "upload codecov", [upload_cmd] + + def create_download_and_merge_coverage_func(): include_expansions = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"] args = [ diff --git a/.evergreen/scripts/upload-codecov.sh b/.evergreen/scripts/upload-codecov.sh new file mode 100755 index 0000000000..a7fdb03711 --- /dev/null +++ b/.evergreen/scripts/upload-codecov.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# shellcheck disable=SC2154 +# Upload a coverate report to codecov. +set -eu + +HERE=$(dirname ${BASH_SOURCE:-$0}) +ROOT=$(dirname "$(dirname $HERE)") + +pushd $ROOT > /dev/null +export FNAME=coverage.xml + +if [ -z "${github_pr_number:-}" ]; then + echo "This is not a PR, not running codecov" + exit 0 +fi + +if [ ! -f ".coverage" ]; then + echo "There are no XML test results, not running codecov" + exit 0 +fi + +echo "Uploading..." +printf 'pr: %s\n' "$github_pr_number" +printf 'sha: %s\n' "$github_commit" +printf 'branch: %s:%s\n' "$github_author" "$github_pr_head_branch" +printf 'flag: %s-%s\n' "$build_variant" "$task_name" +printf 'file: %s\n' "$FNAME" +uv tool run --with "coverage[toml]" coverage xml +uv tool run --from codecov-cli codecovcli upload-process \ + --report-type coverage \ + --disable-search \ + --fail-on-error \ + --git-service github \ + --token ${CODECOV_TOKEN} \ + --pr ${github_pr_number} \ + --sha ${github_commit} \ + --branch "${github_author}:${github_pr_head_branch}" \ + --flag "${build_variant}-${task_name}" \ + --file $FNAME +echo "Uploading...done." + +popd > /dev/null diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 086e22faec..5c0bbe08eb 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -79,6 +79,35 @@ jobs: - name: Run tests run: uv run --extra test pytest -v + coverage: + # This enables a coverage report for a given PR, which will be augmented by + # the combined codecov report uploaded in Evergreen. + runs-on: ubuntu-latest + + name: Coverage + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Install uv + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7 + with: + enable-cache: true + python-version: "3.10" + - id: setup-mongodb + uses: mongodb-labs/drivers-evergreen-tools@master + with: + version: "8.0" + - name: Install just + run: uv tool install rust-just + - name: Setup tests + run: COVERAGE=1 just setup-tests + - name: Run tests + run: just run-tests + - name: Generate xml report + run: uv tool run --with "coverage[toml]" coverage xml + - name: Upload test results to Codecov + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 doctest: runs-on: ubuntu-latest name: DocTest diff --git a/.gitignore b/.gitignore index 74ed0bbb70..cb4940a55e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ test/lambda/*.json # test results and logs xunit-results/ +coverage.xml server.log diff --git a/pyproject.toml b/pyproject.toml index 65cbeca8b4..acc9fa5b0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -239,7 +239,11 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$" [tool.coverage.run] branch = true -source = ["pymongo", "bson", "gridfs" ] +include = [ + "pymongo/*", + "bson/*", + "gridfs/*" +] relative_files = true [tool.coverage.report]