Fix spec gaps #528
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
| # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples | |
| # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| name: test-coverage.yaml | |
| permissions: read-all | |
| jobs: | |
| test-coverage: | |
| runs-on: ubuntu-latest | |
| env: | |
| GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: r-lib/actions/setup-r@v2 | |
| with: | |
| use-public-rspm: true | |
| extra-repositories: "https://stan-dev.r-universe.dev" | |
| - uses: r-lib/actions/setup-r-dependencies@v2 | |
| with: | |
| extra-packages: | | |
| any::covr | |
| any::xml2 | |
| any::jsonlite | |
| any::rstudioapi | |
| any::DT | |
| any::htmltools | |
| needs: coverage | |
| - name: Test coverage | |
| run: | | |
| cov <- covr::package_coverage( | |
| quiet = FALSE, | |
| clean = FALSE, | |
| install_path = file.path( | |
| normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), | |
| "package" | |
| ) | |
| ) | |
| print(cov) | |
| saveRDS(cov, "cov.rds") | |
| # Write cobertura report for Codecov | |
| covr::to_cobertura(cov) | |
| # ------------------------------------------------------------ | |
| # HTML coverage report (artifact) | |
| # ------------------------------------------------------------ | |
| pct <- covr::percent_coverage(cov) | |
| cat(sprintf("Coverage: %.2f%%\n", pct)) | |
| covr::report(cov, file = "covr.html", browse = FALSE) | |
| # Optional: write to GitHub Actions summary | |
| summ <- Sys.getenv("GITHUB_STEP_SUMMARY") | |
| if (nzchar(summ)) { | |
| cat(sprintf("\n## Coverage\n\n- Total: **%.2f%%**\n", pct), file = summ, append = TRUE) | |
| cat("- HTML report uploaded as artifact: `covr-report`\n", file = summ, append = TRUE) | |
| } | |
| # ------------------------------------------------------------ | |
| # Uncovered line reporting (structured CSV + readable MD) | |
| # ------------------------------------------------------------ | |
| z_all <- covr::zero_coverage(cov) | |
| # Restrict to R source files | |
| z_r <- z_all[grepl("^R/.*\\.R$", z_all$filename), , drop = FALSE] | |
| # Write a tidy CSV: one row per uncovered line | |
| cols <- intersect(c("filename", "functions", "line", "value"), names(z_r)) | |
| if (length(cols) < 2) { | |
| utils::write.csv(z_r, "uncovered_lines.csv", row.names = FALSE) | |
| } else { | |
| utils::write.csv(z_r[, cols, drop = FALSE], "uncovered_lines.csv", row.names = FALSE) | |
| } | |
| collapse_ranges <- function(x) { | |
| x <- sort(unique(as.integer(x))) | |
| if (length(x) == 0) return(character()) | |
| runs <- split(x, cumsum(c(1, diff(x) != 1))) | |
| vapply(runs, function(r) { | |
| if (length(r) == 1) as.character(r) | |
| else paste0(min(r), "-", max(r)) | |
| }, character(1)) | |
| } | |
| md <- c("# Uncovered line ranges (covr::zero_coverage)", "") | |
| if (nrow(z_r) == 0) { | |
| md <- c(md, "_No uncovered lines found in `R/` files._") | |
| } else { | |
| files <- sort(unique(z_r$filename)) | |
| for (f in files) { | |
| sub <- z_r[z_r$filename == f, , drop = FALSE] | |
| line_ranges <- collapse_ranges(sub$line) | |
| md <- c(md, paste0("## ", f)) | |
| md <- c(md, "", paste0("**Lines:** ", paste(line_ranges, collapse = ", ")), "") | |
| md <- c(md, "```", paste(utils::capture.output(print(sub)), collapse = "\n"), "```", "") | |
| } | |
| } | |
| writeLines(md, "uncovered_lines.md") | |
| summ <- Sys.getenv("GITHUB_STEP_SUMMARY") | |
| if (nzchar(summ)) { | |
| cat("## Coverage: uncovered lines\n\n", file = summ, append = TRUE) | |
| cat("- Wrote `uncovered_lines.csv` (tidy rows) and `uncovered_lines.md` (grouped by file).\n", file = summ, append = TRUE) | |
| cat("- See artifact: `covr-uncovered-lines`.\n", file = summ, append = TRUE) | |
| } | |
| shell: Rscript {0} | |
| - uses: codecov/codecov-action@v5 | |
| with: | |
| fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} | |
| files: ./cobertura.xml | |
| plugins: noop | |
| disable_search: true | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload covr HTML report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: covr-report | |
| path: | | |
| covr.html | |
| covr_files/ | |
| if-no-files-found: warn | |
| - name: Upload uncovered lines report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: covr-uncovered-lines | |
| path: | | |
| uncovered_lines.md | |
| uncovered_lines.csv | |
| cov.rds | |
| - name: Show testthat output | |
| if: always() | |
| run: | | |
| ## -------------------------------------------------------------------- | |
| find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true | |
| shell: bash | |
| - name: Upload test results | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-test-failures | |
| path: ${{ runner.temp }}/package |