I am trying to deploy a Plumber API that is using ‘renv’ via rsconnect::deployApp(). I am calling deployApp() from outside that project because I don’t want to add the ‘rsconnect’ package as a dependency to my project (I want to keep its dependencies as lean as possible).
Unfortunately this fails since the packages inside the Plumber API renv have different versions than the ones outside the project:
rsconnect::deployApp('plumber-api', appId = app_id, acocunt = account, server = server)
── Preparing for deployment ────────────────────────────────────────────────────
[…]
ℹ Capturing R dependencies from renv.lock
Error in `parseRenvDependencies()`:
! Library and lockfile are out of sync
ℹ Use renv::restore() or renv::snapshot() to synchronise
ℹ Or ignore the lockfile by adding to your .rscignore
Backtrace:
▆
1. └─rsconnect (local) deployApp(dir, appId = app_id, account = "default", server = "default")
2. └─rsconnect:::bundleApp(...)
3. └─rsconnect:::createAppManifest(...)
4. └─rsconnect:::bundlePackages(...)
5. └─rsconnect:::computePackageDependencies(...)
6. └─rsconnect:::parseRenvDependencies(bundleDir)
7. └─cli::cli_abort(...)
8. └─rlang::abort(...)
And indeed I can recapitulate this by looking at the package versions between my plumber-api project and the currently active project.
I also tried activating the plumber-api renv project before calling deployApp() via renv::load('plumber-api') but that doesn’t solve the issue, since parseRenvDependencies() internally calls packageDescription(…, lib.loc = NULL) to find the installed package version; however, for packages that are already loaded this will read the loaded package’s package description, not the ones from the suitable renv library.
Keeping the dependencies between these two projects in sync would be a non-trivial effort.
I’m happy to create a PR but I don’t really know how to create a good, self-contained test case for that — I’d have to create a mock package and install two different versions of that in two different projects.
Actually bundleDir isn’t what I thought it is, and consequently renv::paths$library(project = bundleDir) doesn’t actually work. But using .libPaths() instead should work.
I am trying to deploy a Plumber API that is using ‘renv’ via
rsconnect::deployApp()
. I am callingdeployApp()
from outside that project because I don’t want to add the ‘rsconnect’ package as a dependency to my project (I want to keep its dependencies as lean as possible).Unfortunately this fails since the packages inside the Plumber API renv have different versions than the ones outside the project:
And indeed I can recapitulate this by looking at the package versions between my
plumber-api
project and the currently active project.I also tried activating the
plumber-api
renv project before callingdeployApp()
viarenv::load('plumber-api')
but that doesn’t solve the issue, sinceparseRenvDependencies()
internally callspackageDescription(…, lib.loc = NULL)
to find the installed package version; however, for packages that are already loaded this will read the loaded package’s package description, not the ones from the suitable renv library.Keeping the dependencies between these two projects in sync would be a non-trivial effort.
I believe the fix would be to replace
https://github.com/rstudio/rsconnect/blob/9999fdb11dde6d5efe596677f9a6be6bd779e31d/R/bundlePackageRenv.R#L51
with
I’m happy to create a PR but I don’t really know how to create a good, self-contained test case for that — I’d have to create a mock package and install two different versions of that in two different projects.