diff --git a/.Rbuildignore b/.Rbuildignore index e06c843..8051313 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -3,6 +3,7 @@ ^\.Rproj\.user$ ^\.git$ ^\.github$ +^codecov\.yml$ ^LICENSE\.md$ ^\.claude$ ^CLAUDE\.md$ diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000..0b00e9f --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,74 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Test coverage via covr, uploaded to Codecov. Python is provided the same way +# R-CMD-check.yaml does -- through reticulate's managed miniconda -- so coverage +# exercises the same kind of interpreter nat.python is designed to manage. +on: + push: + branches: [main, master] + pull_request: + workflow_dispatch: + +name: test-coverage + +permissions: read-all + +jobs: + test-coverage: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr, any::xml2 + needs: coverage + + - name: Provision Python (reticulate miniconda) and install nat.python + # Mirrors R-CMD-check.yaml's default leg: reticulate's own miniconda, + # numpy + pandas installed, then pin RETICULATE_PYTHON to that exact + # interpreter for the coverage run. + shell: Rscript {0} + run: | + reticulate::install_miniconda() + reticulate::py_install(c("numpy", "pandas")) + pak::local_install() + cat(sprintf("RETICULATE_PYTHON=%s\n", reticulate::py_config()$python), + file = Sys.getenv("GITHUB_ENV"), append = TRUE) + + - name: Test coverage + shell: Rscript {0} + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + covr::to_cobertura(cov) + + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: false + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + shell: bash + run: | + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/DESCRIPTION b/DESCRIPTION index c9f8a3d..c242a9b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -32,7 +32,8 @@ Suggests: arrow, tibble, testthat (>= 3.0.0), - withr + withr, + covr Config/testthat/edition: 3 Roxygen: list(markdown = TRUE) URL: https://github.com/flyconnectome/nat.python diff --git a/README.md b/README.md index 4dcd211..55a278e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) [![R-CMD-check](https://github.com/flyconnectome/nat.python/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/flyconnectome/nat.python/actions/workflows/R-CMD-check.yaml) +[![Codecov test coverage](https://codecov.io/gh/flyconnectome/nat.python/graph/badge.svg)](https://app.codecov.io/gh/flyconnectome/nat.python) > **⚠️ Design-phase package.** nat.python is being extracted from diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..bfdc987 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,8 @@ +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true