Access CRAN on JFrog
JFrog offers a CRAN for R packages.
The R capabilities are not particularly fancy, but the main benefit for me is that this is a platform used elsewhere at work and hence someone else is taking care of maintenance.
A CRAN is part of JFrog’s Artifactory and R packages are accessed through Artifactory’s REST API.
In this post I show how to install packages from a JFROG CRAN.
The first thing is to generate an API key instead of using your password.
It is also possible to use access tokens, which I think is a good idea for e.g. CI jobs instead of making a user just to have an extra API key.
When creating a CRAN in JFrog you have to choose a name, which I refer to as <CRAN name>
in the following.
Basic authentication
JFrog’s own documentation suggests using basic HTTP access authentication by including username and API key in the CRAN URL:
install.packages("<package>", repos = "https://<user>:<API key>@<domain>.jfrog.io/artifactory/<CRAN name>"})
Typing the repos
argument every time gets tedious so instead I update my system wide Rprofile to include this repository:
options(
repos = c(
"JFROG" = "https://<user>:<API key>@<domain>.jfrog.io/artifactory/<CRAN name>",
"MRAN" = "https://mran.microsoft.com/snapshot/2020-10-10"
)
)
As explained in the post I linked to above I use MRAN instead of the bleeding edge CRAN and this particular date is for R version 4.0.2.
Actually, I don’t recommend hardcoding the <user>
and <API key>
in the system wide Rprofile
.
Instead I rely on environment variables:
options(
repos = c(
"JFROG" = paste0("https://", Sys.getenv('JFROG_USER'), ":", Sys.getenv('JFROG_API'), "@<domain>.jfrog.io/artifactory/<CRAN name>",
"MRAN" = "https://mran.microsoft.com/snapshot/2020-10-10"
)
)
Then each user fill their personal .Renviron
with the variables JFROG_USER
and JFROG_API
:
JFROG_USER=<user>
JFROG_API=<API key>
Remember that the usethis package can help find this file with usethis::edit_r_environ()
.
While the above method works there is a downside:
When installing a package (from any CRAN) R writes the full URL in the console – which now includes personal credentials.
This may be okay on a personal computer, but I don’t like it in automatic jobs with logs like a CI pipeline
This is where authentication with a dedicated header is useful:
install.packages("<package>", headers = c("X-JFrog-Art-Api" = Sys.getenv('JFROG_API')))
Alternatively, an access token (saved in the environment variable JFROG_PAT
) can be used for bearer authentication:
install.packages("<package>", headers = c("Authorization" = paste("Bearer", Sys.getenv('JFROG_PAT'))))
The headers
arguments is passed on to download.file
.