diff --git a/.CLAUDE.md b/.CLAUDE.md index 76de5c0d..8d9da08d 100644 --- a/.CLAUDE.md +++ b/.CLAUDE.md @@ -152,7 +152,26 @@ tinytest::run_test_file("inst/tinytest/test-legend.R") All contributions should go through a pull request. PRs against `main` automatically trigger GitHub Actions CI, which runs `R CMD check` (including the full test suite) on Ubuntu with both R-release and R-devel. Snapshot tests are included in this CI run, so even if you can't run them locally, CI will catch any regressions. ### CRAN Submissions -The test suite (snapshot SVGs in particular) adds significant size to the installed package. Tests are only intended to run locally and on CI — not on CRAN. Before a CRAN submission, uncomment the `inst/tinytest/` line in `.Rbuildignore` to exclude the test directory from the built tarball. Remember to re-comment it after submission so that CI continues to pick up the tests. +The test suite (snapshot SVGs in particular) adds significant size to the installed package. Tests are only intended to run locally and on CI — not on CRAN. + +**Pre-submission checklist:** +1. Create a new branch `cran_v` from main +2. Verify version is updated and aligned in both `DESCRIPTION` and `NEWS.md` +3. Verify `Date` field in `DESCRIPTION` matches the submission date +4. Update `cran-comments.md` with new version and release type +5. Open a PR from the branch to main +6. Verify CI passes on the PR +7. Run reverse dependency checks: push a `revdep-v` branch to trigger the revdep workflow +8. Uncomment the `inst/tinytest/` line in `.Rbuildignore` to exclude tests from tarball +9. Run `devtools::check_win_devel()` and wait for results +10. Run `R CMD check --as-cran` locally +11. Fix any issues / notes and update cran-comments.md as necessary +12. Submit to CRAN + +**Post-acceptance:** +1. Re-comment the `inst/tinytest/` line in `.Rbuildignore` and push to PR so CI continues to pick up tests +2. Merge the PR to main +3. Create a new GitHub release tagged `v` ### Manual Testing Some features require manual testing, particularly: @@ -200,7 +219,7 @@ settings$legend_args[["pt.cex"]] = settings$legend_args[["pt.cex"]] %||% 3.5 - **Legend misalignment on resize**: Ensure coordinate-dependent calculations are inside `recordGraphics()`. See PRs #438, #540, #541. - **Layer alignment with grouped types**: When adding jitter/points on top of boxplot/violin, the layer needs access to `group_offsets` from `.tinyplot_env`. See PR #561. - **Theme hook corruption**: Always save and restore `before.plot.new` hooks when calling `plot.new()` in legend code. -- **R 4.0.0 compat**: No `|>` pipe, no `\()` lambda, no `%||%` (package defines its own for R <= 4.4.0). +- **R 4.0.0 compat**: No `|>` pipe, no `\()` lambda. ## Links diff --git a/.Rbuildignore b/.Rbuildignore index 26a6145c..03e6bbc2 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -27,3 +27,4 @@ Makefile ^.devcontainer Rplots.pdf ^\.CLAUDE\.md$ +^revdep$ diff --git a/.github/workflows/revdep.yaml b/.github/workflows/revdep.yaml new file mode 100644 index 00000000..d5c9dc9c --- /dev/null +++ b/.github/workflows/revdep.yaml @@ -0,0 +1,185 @@ +# This workflow creates many jobs, run only when a branch is created +on: + push: + branches: + - "revdep*" # never run automatically on main branch + +name: revdep + +jobs: + matrix: + runs-on: ubuntu-22.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + name: Collect revdeps + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + # prevent rgl issues because no X11 display is available + RGL_USE_NULL: true + steps: + - name: Check rate limits + run: | + curl -s --header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/rate_limit + shell: bash + + - uses: actions/checkout@v3 + + - id: set-matrix + run: | + package <- read.dcf("DESCRIPTION")[, "Package"][[1]] + deps <- tools:::package_dependencies(package, reverse = TRUE, which = c("Depends", "Imports", "LinkingTo", "Suggests"))[[1]] + json <- paste0( + '{"package":[', + paste0('"', deps, '"', collapse = ","), + ']}' + ) + writeLines(json) + writeLines(paste0("matrix=", json), Sys.getenv("GITHUB_OUTPUT")) + shell: Rscript {0} + + check-matrix: + runs-on: ubuntu-22.04 + needs: matrix + steps: + - name: Install json2yaml + run: | + sudo npm install -g json2yaml + + - name: Check matrix definition + run: | + matrix='${{ needs.matrix.outputs.matrix }}' + echo $matrix + echo $matrix | jq . + echo $matrix | json2yaml + + R-CMD-check: + needs: matrix + runs-on: ubuntu-22.04 + name: ${{ matrix.package }} + strategy: + fail-fast: false + matrix: ${{fromJson(needs.matrix.outputs.matrix)}} + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + # prevent rgl issues because no X11 display is available + RGL_USE_NULL: true + steps: + - name: Check rate limits + run: | + curl -s --header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/rate_limit + shell: bash + + - uses: actions/checkout@v3 + + - name: Use RSPM + run: | + mkdir -p /home/runner/work/_temp/Library + echo 'local({release <- system2("lsb_release", "-sc", stdout = TRUE); options(repos=c(CRAN = paste0("https://packagemanager.rstudio.com/all/__linux__/", release, "/latest")), HTTPUserAgent = sprintf("R/%s R (%s)", getRversion(), paste(getRversion(), R.version$platform, R.version$arch, R.version$os)))}); .libPaths("/home/runner/work/_temp/Library")' | sudo tee /etc/R/Rprofile.site + + - name: Install remotes + run: | + if (!requireNamespace("curl", quietly = TRUE)) install.packages("curl") + if (!requireNamespace("remotes", quietly = TRUE)) install.packages("remotes") + shell: Rscript {0} + + - uses: r-lib/actions/setup-pandoc@v2 + + - name: Install system dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update -y + Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "22.04")); package <- "${{ matrix.package }}"; deps <- tools::package_dependencies(package, which = "Suggests")[[1]]; lapply(c(package, deps), function(x) { writeLines(remotes::system_requirements("ubuntu", "22.04", package = x)) })' | sort | uniq > .github/deps.sh + cat .github/deps.sh + sudo sh < .github/deps.sh + + - name: Install package + run: | + package <- "${{ matrix.package }}" + install.packages(package, dependencies = TRUE) + remotes::install_cran("rcmdcheck") + shell: Rscript {0} + + - name: Session info old + run: | + options(width = 100) + if (!requireNamespace("sessioninfo", quietly = TRUE)) install.packages("sessioninfo") + pkgs <- installed.packages()[, "Package"] + sessioninfo::session_info(pkgs, include_base = TRUE) + shell: Rscript {0} + + - name: Check old + env: + _R_CHECK_CRAN_INCOMING_: false + _R_CHECK_SYSTEM_CLOCK_: false + _R_CHECK_FUTURE_FILE_TIMESTAMPS_: false + run: | + package <- "${{ matrix.package }}" + options(HTTPUserAgent = "gha") + path <- download.packages(package, destdir = ".github")[, 2] + print(path) + dir <- file.path("revdep", package) + dir.create(dir, showWarnings = FALSE, recursive = TRUE) + check <- rcmdcheck::rcmdcheck(path, args = c("--no-manual", "--as-cran"), error_on = "never", check_dir = file.path(dir, "check")) + file.rename(file.path(dir, "check"), file.path(dir, "old")) + saveRDS(check, file.path(dir, "old.rds")) + shell: Rscript {0} + + - name: Install local package + run: | + remotes::install_local(".", force = TRUE) + shell: Rscript {0} + + - name: Session info new + run: | + options(width = 100) + pkgs <- installed.packages()[, "Package"] + sessioninfo::session_info(pkgs, include_base = TRUE) + shell: Rscript {0} + + - name: Check new + env: + _R_CHECK_CRAN_INCOMING_: false + _R_CHECK_SYSTEM_CLOCK_: false + _R_CHECK_FUTURE_FILE_TIMESTAMPS_: false + run: | + package <- "${{ matrix.package }}" + path <- dir(".github", pattern = paste0("^", package), full.names = TRUE)[[1]] + print(path) + dir <- file.path("revdep", package) + check <- rcmdcheck::rcmdcheck(path, args = c("--no-manual", "--as-cran"), error_on = "never", check_dir = file.path(dir, "check")) + file.rename(file.path(dir, "check"), file.path(dir, "new")) + saveRDS(check, file.path(dir, "new.rds")) + shell: Rscript {0} + + - name: Compare + run: | + package <- "${{ matrix.package }}" + dir <- file.path("revdep", package) + old <- readRDS(file.path(dir, "old.rds")) + new <- readRDS(file.path(dir, "new.rds")) + compare <- rcmdcheck::compare_checks(old, new) + compare + cmp <- compare$cmp + if (!identical(cmp[cmp$which == "old", "output"], cmp[cmp$which == "new", "output"])) { + if (!requireNamespace("waldo", quietly = TRUE)) install.packages("waldo") + print(waldo::compare(old, new)) + stop("Check output differs.") + } + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@main + with: + name: ${{ matrix.package }}-results + path: revdep/${{ matrix.package }} + + - name: Check rate limits + if: always() + run: | + curl -s --header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/rate_limit + shell: bash diff --git a/.gitignore b/.gitignore index 792f123c..675bfaa6 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,5 @@ _quarto /.quarto/ -Rplots.pdf \ No newline at end of file +Rplots.pdf +revdep/ \ No newline at end of file diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index f06b380a..f4906211 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 0.6.0 -Date: 2025-11-26 21:36:13 UTC -SHA: 3080d0ab861e2cf1f6d463e4784a8d4f6653a6d4 +Version: 0.6.1 +Date: 2026-03-27 04:50:35 UTC +SHA: 65b5237fbbb6e59fab417f73b35232d62fe2b82b diff --git a/DESCRIPTION b/DESCRIPTION index bf04fdc9..4dc431ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: tinyplot Type: Package Title: Lightweight Extension of the Base R Graphics System -Version: 0.6.99 -Date: 2025-11-26 +Version: 0.6.1 +Date: 2026-03-28 Authors@R: c( person( diff --git a/NEWS.md b/NEWS.md index 1c816cc3..27402614 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ _If you are viewing this file on CRAN, please check the [latest NEWS](https://grantmcdermott.com/tinyplot/NEWS.html) on our website where the formatting is also better._ -## Development version +## v0.6.1 ### Aesthetic changes @@ -57,6 +57,8 @@ where the formatting is also better._ - Fix Makefile website target (remove circular dep, fix comment) - Enable parallel + freeze for faster local builds - Replace iconify extension with native Bootstrap icon for Bluesky +- Add GitHub Actions workflow for reverse dependency checks. Triggered by + pushing a `revdep*` branch. (#567 @grantmcdermott) ## v0.6.0 diff --git a/cran-comments.md b/cran-comments.md index 977b8a88..e89719f1 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,19 +1,18 @@ ## Overview -**tinyplot** v0.6.0 a minor release containing mostly bug fixes. - -_Note:_ This is a re-submission that fixes a regression discovered by CRAN's -revdep checks (specific to the **parttree** package). Apologies for missing it -the first time around. +**tinyplot** v0.6.1 is a patch release containing bug fixes. ## Test environments -Arch Linux (local) -GitHub Actions (ubuntu-22.04): release, devel +macOS (local) +GitHub Actions (ubuntu-24.04): release, devel Win Builder ## R CMD check results -0 errors | 0 warnings | 0 notes +0 errors | 0 warnings | 1 note + +Note: New maintainer email address (contact@grantmcdermott.com). This is the same +person, just a different email. P.S. We continue to run a comprehensive test suite comprising hundreds of test snapshots (i.e., SVG images) as part of our CI development workflow. See: