使用 httr 通过 Travis-CI 在 Github 进行身份验证以及本地身份验证(本地有效,远程无效)

Bry*_*son 7 r github-api travis-ci httr

我有一个Rmd文件,它使用httr访问Github的API。在本地,如果我R在渲染之前在控制台中运行以下内容,我可以很好地通过 Github 进行身份验证Rmd

myapp <- oauth_app("APP", key = "xyz", secret = "pqr")
github_token <- oauth2.0_token(oauth_endpoints("github"), myapp)
Run Code Online (Sandbox Code Playgroud)

密钥和秘密是在 Github 上创建的,并且在我渲染时存在于我的工作区中,因此github_token被选中并且我可以在本地渲染时访问 Github-API 而不会达到访问限制。

现在,同样Rmd在 Travis-CI 中自动构建,然后在我推送 master 分支时部署到 gh-pages。我有这个没有身份验证的工作,但这将我的 Githhub-API 请求限制限制为 60/小时,我需要通过身份验证获得的更高限制。为此,我在 Github 中也设置了个人访问令牌 (PAT);设置 PAT 的页面说“个人访问令牌的功能类似于普通的 OAuth 访问令牌。它们可以用来代替 Git over HTTPS 的密码,或者可以用来通过基本身份验证对 API 进行身份验证”。

这是Rmd我尝试检测渲染是本地还是远程并获取适当令牌的部分内容。但是,当它在 Travis-CI 上运行时,令牌似乎没有被识别,所以我认为我没有正确使用它。

# Figure out the build location, and get the needed token
at_home <- FALSE
at_TCI <- FALSE
token_found <- FALSE
token_OK <- FALSE # not used now/yet

# Check to see if we are at TRAVIS-CI
# This next variable is in the Travis build environment & is a character string
token_value <- Sys.getenv("TRAVIS_CI") 
if (token_value != "") {
  token_found <- TRUE
  at_TCI <- TRUE
}

# Check to see if we are on the local/home machine
# This token is generated interactively via "Web Application Flow",
# and is deposited in the local workspace
# See developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#web-application-flow
# This token has classes 'Token2.0', 'Token', 'R6' <Token2.0>
if (!at_TCI) {
  token_found <- exists("github_token")
  if (token_found) {
    token_value <- github_token
    at_home <- TRUE
  }
}

# See where we stand and act accordingly
if (!token_found) {
  message("Could not retrieve token - GET calls will be rate-limited by Github")
  # TEMPORARY: just use a few lines for faster testing & not blasting GH limits
  DF <- DF[1:5,]
}
if (token_found) {
  set_config(config(token = token_value)) # applies to all GET requests below
}

Run Code Online (Sandbox Code Playgroud)

set_config当我在 Travis-CI 时,我认为该调用无法正常工作,因为我收到一个错误,该错误似乎来自GET稍后发生的调用(在 T-CI 上进行故障排除真的很困难,但在Rmd本地工作正常)。这是一个示例GET调用,在运行上面的代码段后远程失败,但在本地工作:

repoOK[i] <- identical(status_code(GET(DF$repo[i])), 200L)
Run Code Online (Sandbox Code Playgroud)

DF$repo[i]网址在哪里。

我是httrGithub-API 的新手,但我花了很多时间尝试在 SO 上找到的咒语和 Github 文档,但到目前为止远程构建没有成功。因此,我呼吁 SO 社区的怜悯!

编辑:带有完整代码的GH 存储库

编辑 2:在赏金期间(!)没有人回答。所以我将在主分支上工作。该分支的代码在本地运行,但在 Travis-CI 中失败。此外,这个分支已经消除了所有 Python 的东西,以避免其他问题并保持干净。这个分支在 Travis-CI 上给出了以下错误:

getGHdates(DF$repo[i], "commits") 错误:超出 Github 访问速率,稍后再试

Bry*_*son 1

答案似乎是,在本地工作时无法使用与在 Travis-CI 远程使用所需相同的身份验证方法。为了Rmd在两个位置正确渲染,我必须编写比我希望的更复杂的代码。特别是,对于本地工作,按如下方式进行身份验证就足够了。

首先,在R控制台运行(如上);

myapp <- oauth_app("APP", key = "xyz", secret = "pqr")
github_token <- oauth2.0_token(oauth_endpoints("github"), myapp)
Run Code Online (Sandbox Code Playgroud)

然后在Rmd代码中需要:

# Figure out the build location, and get the needed token
at_home <- FALSE
at_TCI <- FALSE
token_found <- FALSE
where <- NULL

# Check to see if we are at TRAVIS-CI
# This token has class character
token_value <- Sys.getenv("TRAVIS_CI")
if (token_value != "") {
  token_found <- TRUE
  at_TCI <- TRUE
}

# Check to see if we are on the local/home machine
# This token is generated interactively via "Web Application Flow",
# and is deposited in the local workspace with the name github_token before rendering
# See developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#web-application-flow
# This token has classes 'Token2.0', 'Token', 'R6' <Token2.0>
if (!at_TCI) {
  token_found <- exists("github_token")
  if (token_found) {
    token_value <- github_token
    at_home <- TRUE
  }
}

# See where we stand and act accordingly
if (!token_found) {
  message("Could not retrieve token - GET calls will be rate-limited by Github")
  # TEMPORARY: just use a few lines for faster testing & not blasting GH limits
  DF <- DF[1:5,]
}
if (token_found) {
  if (at_home) set_config(config(token = token_value))
  # This is sufficient for at_home and the GET calls elsewhere have a simple form
  if (at_home) where <- "home"
  if (at_TCI) where <- "TCI"
}

if (is.null(where)) stop("I'm lost")

# Report for troubleshooting
# cat("at_home = ", at_home, "\n")
# cat("at_TCI = ", at_TCI, "\n")
# cat("token_found = ", token_found, "\n")
Run Code Online (Sandbox Code Playgroud)

通过这种安排,使用 调用 Github API 就GET可以正常工作。

然而,当在 Travis-CI 远程工作时,这种方法不起作用。对于这种情况,需要按照以下方式做一些事情:

for (i in 1:ne) {
  if (!is.na(DF$web[i])) {
    if (at_home) access_string <- DF$web[i]
    if (at_TCI) {
      GH <- grepl("github\\.com", DF$web[i])
      if (!GH) access_string <- DF$web[i] # local access
      if (GH) access_string <- paste0(DF$web[i], "?access_token=",
        token_value) # remote access from Travis-CI
    }
    webOK[i] <- identical(status_code(GET(access_string)), 200L)
    webLink[i] <- TRUE
    if (webLink[i] != webOK[i]) badWeb[i] <- TRUE
  }
}
Run Code Online (Sandbox Code Playgroud)

我找到了在此处的GET调用中嵌入令牌的建议。

如果您已经读到这里,祝您自己的项目好运!完整代码位于此GH 存储库中。