From 37f5b314ed5f8b3b785488e8b0371b8e43668ff0 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Tue, 9 Jul 2024 16:34:16 +0800 Subject: [PATCH] support GH_TOKEN and GITHUB_TOKEN for auth (#1937) --- DESCRIPTION | 2 +- NEWS.md | 3 +++ R/bootstrap.R | 18 +++++++++++++----- R/download.R | 16 ++++++++-------- R/github.R | 1 + R/update.R | 16 ---------------- inst/resources/activate.R | 18 +++++++++++++----- man/paths.Rd | 2 +- tests/testthat/helper-skip.R | 3 ++- 9 files changed, 42 insertions(+), 37 deletions(-) create mode 100644 R/github.R diff --git a/DESCRIPTION b/DESCRIPTION index 9ffb7a7e2..69adcc8f5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,7 +21,7 @@ Suggests: BiocManager, cli, covr, cpp11, devtools, gitcreds, jsonlite, jsonvalid miniUI, packrat, pak, R6, remotes, reticulate, rmarkdown, rstudioapi, shiny, testthat, uuid, waldo, yaml, webfakes Encoding: UTF-8 -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Roxygen: list(markdown = TRUE) VignetteBuilder: knitr Config/Needs/website: tidyverse/tidytemplate diff --git a/NEWS.md b/NEWS.md index 426514614..0ea3ae120 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ # renv (development version) +* `renv` now supports setting of GitHub authentication credentials via + any of `GITHUB_TOKEN`, `GITHUB_PAT`, and `GH_TOKEN`. (#1937) + * `renv` now also passes any custom headers available to `utils::available.packages()` during bootstrap. (#1942) diff --git a/R/bootstrap.R b/R/bootstrap.R index bb5188427..1265a0789 100644 --- a/R/bootstrap.R +++ b/R/bootstrap.R @@ -387,6 +387,14 @@ renv_bootstrap_download_tarball <- function(version) { } +renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } +} + renv_bootstrap_download_github <- function(version) { enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") @@ -394,16 +402,16 @@ renv_bootstrap_download_github <- function(version) { return(FALSE) # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { + token <- renv_bootstrap_github_token() + if (nzchar(Sys.which("curl")) && nzchar(token)) { fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "curl", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "wget", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) diff --git a/R/download.R b/R/download.R index 04c989800..e22f5fd3b 100644 --- a/R/download.R +++ b/R/download.R @@ -529,20 +529,20 @@ renv_download_auth_bitbucket <- function() { renv_download_auth_github <- function(url) { - pat <- renv_download_auth_github_pat(url) - if (is.null(pat)) + token <- renv_download_auth_github_token(url) + if (is.null(token)) return(character()) - c("Authorization" = paste("token", pat)) + c("Authorization" = paste("token", token)) } -renv_download_auth_github_pat <- function(url) { +renv_download_auth_github_token <- function(url) { - # check for an existing PAT - pat <- Sys.getenv("GITHUB_PAT", unset = NA) - if (!is.na(pat)) - return(pat) + # check for an existing token from environment variable + token <- renv_bootstrap_github_token() + if (length(token)) + return(token) # if gitcreds is available, try to use it gitcreds <- diff --git a/R/github.R b/R/github.R new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/R/github.R @@ -0,0 +1 @@ + diff --git a/R/update.R b/R/update.R index 3967ede74..8466643b1 100644 --- a/R/update.R +++ b/R/update.R @@ -71,22 +71,6 @@ renv_update_find_git_impl <- function(record) { renv_update_find_github <- function(records) { - # check for GITHUB_PAT - if (!renv_envvar_exists("GITHUB_PAT")) { - - msg <- paste( - "GITHUB_PAT is unset. Updates may fail due to GitHub's API rate limit.", - "", - "To increase your GitHub API rate limit:", - "- Use `usethis::create_github_token()` to create a Personal Access Token (PAT).", - "- Use `usethis::edit_r_environ()` and add the token as `GITHUB_PAT`.", - sep = "\n" - ) - - warning(msg, call. = FALSE) - - } - names(records) <- map_chr(records, `[[`, "Package") results <- renv_parallel_exec(records, function(record) { catch(renv_update_find_github_impl(record)) diff --git a/inst/resources/activate.R b/inst/resources/activate.R index 9ad0c8ebe..70abe0ec1 100644 --- a/inst/resources/activate.R +++ b/inst/resources/activate.R @@ -486,6 +486,14 @@ local({ } + renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } + } + renv_bootstrap_download_github <- function(version) { enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") @@ -493,16 +501,16 @@ local({ return(FALSE) # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { + token <- renv_bootstrap_github_token() + if (nzchar(Sys.which("curl")) && nzchar(token)) { fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "curl", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "wget", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) diff --git a/man/paths.Rd b/man/paths.Rd index 1577a74ee..b4c69a916 100644 --- a/man/paths.Rd +++ b/man/paths.Rd @@ -102,7 +102,7 @@ The prefix will be constructed based on fields within the system's } \section{Package cellar}{ -If your project depends on one or \R packages that are not available in any +If your project depends on one or more \R packages that are not available in any remote location, you can still provide a locally-available tarball for renv to use during restore. By default, these packages should be made available in the folder as specified by the \code{RENV_PATHS_CELLAR} environment variable. The diff --git a/tests/testthat/helper-skip.R b/tests/testthat/helper-skip.R index 47376cdb2..abf65acf0 100644 --- a/tests/testthat/helper-skip.R +++ b/tests/testthat/helper-skip.R @@ -1,6 +1,7 @@ skip_if_no_github_auth <- function() { - skip_if_not(renv_envvar_exists("GITHUB_PAT"), "GITHUB_PAT is not set") + token <- renv_bootstrap_github_token() + skip_if(empty(token), "GITHUB_PAT is not set") } skip_if_no_python <- function() {