Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I deploy an ‘renv’ app from inside a *different* project? #1093

Open
klmr opened this issue Jul 18, 2024 · 3 comments
Open

How do I deploy an ‘renv’ app from inside a *different* project? #1093

klmr opened this issue Jul 18, 2024 · 3 comments

Comments

@klmr
Copy link

klmr commented Jul 18, 2024

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 believe the fix would be to replace

deps$description <- lapply(deps$Package, package_record)

with

  deps$description <- lapply(deps$Package, package_record, lib_dir = renv::paths$library(project = bundleDir))

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.

@klmr
Copy link
Author

klmr commented Jul 30, 2024

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.

@soetang
Copy link

soetang commented Oct 30, 2024

I think this i related to #1046

@klmr
Copy link
Author

klmr commented Nov 1, 2024

@soetang I think you might be right. However, I am a bit confused by the discussion: I don’t really understand why ‘rsconnect’ would require any of these hoops. As far as I can tell the issue is really due to the fact that parseRenvDependencies() simply looks for dependencies in the wrong location (= it does not realise that the currently active renv might not be the renv of the project-to-be-deployed).

If I am right, no user action should be necessary, and this should be fixed inside parseRenvDependencies() (looking at it again, the fix from my initial post should work… should it not?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants