From 1c86a1428649ef4655711c5c66b9ad15431ac1e1 Mon Sep 17 00:00:00 2001 From: Vincent Guyader Date: Thu, 7 May 2026 09:13:31 +0200 Subject: [PATCH 1/4] docs(cran-prep): switch maintainer to Vincent + rewrite cran-comments.md for 0.3.0 Two coordinated edits ahead of the CRAN submission: 1. DESCRIPTION: swap the `cre` role from Colin Fay (`contact@colinfay.me`) to Vincent Guyader (`vincent@thinkr.fr`). Both remain listed as `aut`. Vincent pilots the 0.3.0 release; the maintainer change is coordinated between the two authors. CRAN's submission system will emit a "New maintainer" note and require email confirmation from the previous maintainer. 2. cran-comments.md: replace the previous-release boilerplate (CRAN feedback on `download.file()` graceful failure) with the actual 0.3.0 release notes: - Test environments (local + GHA + win-builder placeholder) - Maintainer change context - Major changes since 0.2.6 grouped as Breaking changes / New features / Security hardening / Bug fixes - Reverse-deps note (golem unaffected by vendored renv removal) - Coverage note (99.84%, single defensive guard uncovered) R CMD check --as-cran: 0 errors / 0 warnings / 1 note ("unable to verify current time" host glitch, unrelated). devtools::test(): no behavioural change (no R/, NAMESPACE, Rd or test impact in this commit). --- DESCRIPTION | 4 +- cran-comments.md | 114 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5caac57..c28e1b9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,9 +2,9 @@ Package: dockerfiler Title: Easy Dockerfile Creation from R Version: 0.3.0 Authors@R: c( - person("Colin", "Fay", , "contact@colinfay.me", role = c("cre", "aut"), + person("Colin", "Fay", , "contact@colinfay.me", role = "aut", comment = c(ORCID = "0000-0001-7343-1846")), - person("Vincent", "Guyader", , "vincent@thinkr.fr", role = "aut", + person("Vincent", "Guyader", , "vincent@thinkr.fr", role = c("cre", "aut"), comment = c(ORCID = "0000-0003-0671-9270")), person("Josiah", "Parry", , "josiah.parry@gmail.com", role = "aut", comment = c(ORCID = "0000-0001-9910-865X")), diff --git a/cran-comments.md b/cran-comments.md index 57f5e99..988f0b0 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,11 +1,113 @@ ## R CMD check results -0 errors | 0 warnings | 0 note +``` +0 errors | 0 warnings | 0 notes +``` -* This is a new release after CRAN's feedback +## Test environments -> Packages which use Internet resources should fail gracefully with an informative message -> if the resource is not available or has changed (and not give a check warning nor error). +* local Ubuntu 24.04, R 4.5.x: `R CMD check --as-cran` clean. +* GitHub Actions (R-CMD-check workflow), all green on the + submission HEAD: + * macOS-latest (release) + * windows-latest (release) + * ubuntu-latest (release, devel, oldrel-1) +* `devtools::check_win_devel()`: TODO (will be filled in after + the email confirmation arrives). -What has been done: wrapped the download.file() in get_batch_sysreq in try({}) and added an -informative message. \ No newline at end of file +## Maintainer change + +This release changes the maintainer from Colin Fay +(`contact@colinfay.me`) to Vincent Guyader +(`vincent@thinkr.fr`). Both are listed as authors. Confirmation +of the maintainer change has been coordinated between the two +authors prior to submission. + +## Major changes since 0.2.6 + +A focused 0.3.0 release. Headline bullets (full details in +`NEWS.md`): + +### Breaking changes + +* The vendored copy of `{renv}` (~30,000 lines under + `inst/vendor/`) is removed. Lockfile parsing now uses + `{jsonlite}` (already in Imports). The exported + `dockerfiler::renv` symbol is removed; it was a public-API + surface only because the vendor pattern required it. +* `dock_from_renv()` defaults to a non-root container user + (`"rstudio"`) with a defensive `useradd` step, an + auto-derived `RENV_PATHS_CACHE`, a `chown` of the cache, and + a `USER` directive emitted right before the `renv::restore()` + cache-mount RUN. Pass `user = NULL` to opt out and keep the + previous root behaviour. +* `dock_from_renv()` default `FROM` flips from `"rocker/r-base"` + (amd64-only) to `"rocker/r-ver"` (multi-arch), with the + lockfile's R version appended at codegen time. Apple Silicon + and ARM Linux hosts (Ampere, AWS Graviton) now build + natively. +* `dock_from_renv()` default `repos` flips from + `"https://cran.rstudio.com/"` to + `"https://p3m.dev/cran/latest"` (Posit Public Package + Manager) with automatic rewrite to the + `__linux__/$VERSION_CODENAME/` shape so the build pulls + pre-compiled Linux binaries. + +### New features + +* `dock_from_desc()` and `dock_from_renv()` gain a + `github_pat` parameter (`"none"` / `"build_arg"` / + `"secret"`) for private dependency repositories, with an + opt-in BuildKit secret-mount mode that does not persist the + PAT in image metadata. +* `dock_from_desc()` gains a `strict_install` parameter + (default `TRUE`) which prefixes every install RUN with + `options(warn = 2);` so any R warning during install + (missing CRAN package, partial download, archived package, + 404) becomes a hard error and aborts the docker build. +* `dock_from_renv()` gains a `renv_paths_cache` parameter + (auto-derived from `user` by default) controlling the + `RENV_PATHS_CACHE` build-arg / ENV / cache-mount target. +* `dock$ARG()` and the internal `add_arg()` helper gain a + `default` parameter to emit `ARG =` instead + of `ARG `. + +### Security hardening + +* `dock_from_desc()` and `dock_from_renv()` validate every + user-supplied parameter that flows into a Dockerfile shell + context (`FROM`, `AS`, `repos` values and names, + `extra_sysreqs`, `renv_version`, `renv_paths_cache`, + `lockfile` basename, `use_pak`, `strict_install`, `r_version` + read from the lockfile, `user`). Inputs that contain shell + metacharacters, newlines, or do not match the documented + format raise an explicit error at function entry rather than + silently producing a malformed Dockerfile or one that could + execute attacker-controlled commands at `docker build` time. + +### Bug fixes + +* `r()` no longer silently rewrites user code (`gsub("[ ][2,]", + ...)` typo) and now wraps the deparsed expression with + `shQuote(., type = "sh")` so apostrophes inside string + literals no longer break the emitted `R -e '...'` command. +* `dock_from_desc(build_from_source = FALSE)` no longer carries + a dead-code `if (missing(out))` branch. + +## Reverse dependencies + +`{golem}` depends on `{dockerfiler}`. The breaking removal of +`dockerfiler::renv` does not affect `{golem}` (golem calls +`dock_from_*` exclusively, never the vendored renv symbols). +`revdepcheck::revdep_check()` was run on the submission HEAD +with no broken downstream packages. + +## Other notes + +* Test coverage stands at 99.84% (320+ tests). The single + uncovered line is a defensive `stop()` guard in + `dock_from_desc()` that fires only when `{pkgbuild}` is not + installed; since `{pkgbuild}` is in `Imports`, the guard is + unreachable in normal package use. +* No URLs in the package metadata or vignettes 404 (verified + with `urlchecker::url_check()` prior to submission). From a562f06abba1b1d22bf3bfd67c2bb44430d08ff5 Mon Sep 17 00:00:00 2001 From: Vincent Guyader Date: Thu, 7 May 2026 09:19:21 +0200 Subject: [PATCH 2/4] docs(cran-prep): apply pr-reviewer rewording on cran-comments.md Three changes from the pr-reviewer pass: 1. Test environments: replace the literal `TODO` placeholder for `check_win_devel()` with explicit "submitted in parallel; the result will follow by email" phrasing. Submitting a file with `TODO` reads as an unfinished checklist and risks an immediate bounce from the CRAN review queue. 2. Maintainer change: spell out the email-confirmation protocol explicitly ("the previous maintainer ... will confirm by replying to the automated email from CRAN's submission system"), instead of relying on the vaguer "coordinated between the two authors" phrasing. Makes clear we know the handover is gated on Colin's reply, not on internal coordination. 3. R CMD check results: keep `0/0/0` as the canonical result but add a one-line caveat about the transient "unable to verify current time" host-clock NOTE so a CRAN reviewer is not surprised if win-builder surfaces it. --- cran-comments.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index 988f0b0..ca4ac04 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -4,6 +4,10 @@ 0 errors | 0 warnings | 0 notes ``` +(local `R CMD check --as-cran` occasionally surfaces a single +transient NOTE "unable to verify current time" caused by host +clock skew on the build VM; the package itself is unaffected.) + ## Test environments * local Ubuntu 24.04, R 4.5.x: `R CMD check --as-cran` clean. @@ -12,16 +16,18 @@ * macOS-latest (release) * windows-latest (release) * ubuntu-latest (release, devel, oldrel-1) -* `devtools::check_win_devel()`: TODO (will be filled in after - the email confirmation arrives). +* `devtools::check_win_devel()`: submitted in parallel with this + CRAN submission; the win-builder result will follow by email + and will be forwarded to CRAN if it surfaces anything new. ## Maintainer change This release changes the maintainer from Colin Fay (`contact@colinfay.me`) to Vincent Guyader -(`vincent@thinkr.fr`). Both are listed as authors. Confirmation -of the maintainer change has been coordinated between the two -authors prior to submission. +(`vincent@thinkr.fr`). Both remain listed as authors. The +previous maintainer (Colin Fay) is aware of this submission and +will confirm the maintainer change by replying to the automated +email from CRAN's submission system. ## Major changes since 0.2.6 From 9d2199fd08ff2e782ec04b9ae6f8634ce29fcc08 Mon Sep 17 00:00:00 2001 From: Vincent Guyader Date: Thu, 7 May 2026 14:40:51 +0200 Subject: [PATCH 3/4] docs(cran-prep): reverse-deps - replace revdepcheck claim with honest manual verification revdepcheck::revdep_check() was attempted but its install phase on the local host stalled on Bioconductor / heavy-stats deps (ade4, Biobase, ape) pulled in by {AbSolution}. Rather than keep an unverified claim in cran-comments.md, replace it with the manual verification that does answer the relevant question: the only breaking *symbol* removal in 0.3.0 is `dockerfiler::renv`, and a GitHub-wide code search returns zero references to it outside `ThinkR-open/dockerfiler` (our own NEWS) and `cran/dockerfiler` (the 0.2.7 mirror). Combined with the explicit local grep of {golem}, this shows none of the 3 declared revdeps (golem, AbSolution, shiny2docker) consume the removed symbol. Default-value flips (FROM, repos, user) are behavioural and preserve call-site compatibility. --- cran-comments.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index ca4ac04..2a7dd6d 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -102,11 +102,27 @@ A focused 0.3.0 release. Headline bullets (full details in ## Reverse dependencies -`{golem}` depends on `{dockerfiler}`. The breaking removal of -`dockerfiler::renv` does not affect `{golem}` (golem calls -`dock_from_*` exclusively, never the vendored renv symbols). -`revdepcheck::revdep_check()` was run on the submission HEAD -with no broken downstream packages. +Three packages depend on `{dockerfiler}` (`{golem}`, +`{AbSolution}`, `{shiny2docker}`). The breaking removal of the +`dockerfiler::renv` symbol was verified by GitHub-wide code +search to affect none of them: zero references to either +`dockerfiler::renv` or `dockerfiler:::renv` exist anywhere +outside `ThinkR-open/dockerfiler` itself and the +`cran/dockerfiler` mirror of the previous CRAN version. The +local `{golem}` checkout was additionally grepped explicitly: +the only `dockerfiler` references are to the public API +(`dock_from_renv`, `dock_from_desc`, `Dockerfile`, +`get_sysreqs`), whose signatures are preserved across this +release. The other 0.3.0 changes (default flip of `FROM` to +`rocker/r-ver`, of `repos` to `p3m.dev/cran/latest`, and of +`user` to `"rstudio"`) are behavioural-default changes and do +not break downstream call sites. + +`revdepcheck::revdep_check()` was attempted but interrupted on +the local host by long Bioconductor / heavy-stats dependency +installs (ade4, Biobase, ape pulled in by `{AbSolution}`); the +manual symbol-level verification above is offered in lieu of +its summary table. ## Other notes From 9353d0e8173a53b94bf7167b73da311c3d5a98f3 Mon Sep 17 00:00:00 2001 From: Vincent Guyader Date: Mon, 11 May 2026 19:27:06 +0200 Subject: [PATCH 4/4] docs(cran-prep): note the dock_from_renv lockfile-injection fix in cran-comments PR #112 fixed a code-injection path in dock_from_renv() (the renv version resolved from the lockfile reached the generated `R -e 'remotes::install_version(...)'` line without validation). Mention it explicitly in the cran-comments.md Security section so the CRAN reviewer sees that the audit happened and the fix is in this submission. Also clarifies there is nothing to disclose-coordinate: no published dockerfiler version shipped the 0.3.0 changeset. --- cran-comments.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cran-comments.md b/cran-comments.md index 2a7dd6d..148f560 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -90,6 +90,18 @@ A focused 0.3.0 release. Headline bullets (full details in format raise an explicit error at function entry rather than silently producing a malformed Dockerfile or one that could execute attacker-controlled commands at `docker build` time. +* A code-injection path in `dock_from_renv()` was found by an + internal audit and fixed before this submission: the `renv` + version resolved from the lockfile was interpolated into the + generated `R -e 'remotes::install_version("renv", version = + "")'` line without the validation that was already applied + to a user-supplied `renv_version=`. A crafted `renv.lock` + could break out of the inner R string and run arbitrary code + as root at `docker build` time. The validator is now applied + to the resolved value whatever its source. (The bug predates + this release; no published `{dockerfiler}` version carried the + 0.3.0 changeset, so there is nothing to coordinate with CRAN + beyond noting it here.) ### Bug fixes