Skip to content

Commit

Permalink
Merge pull request #68 from r-lib/github-actions-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
gaborcsardi authored Feb 2, 2022
2 parents 59e1b11 + d4b97c8 commit 6c683ac
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 6 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Imports:
Suggests:
callr,
covr,
gh,
mockery,
reticulate,
rmarkdown,
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

# development version

* `session_diff()` now accepts the URL to a GitHub Actions log as the source for
`new` and/or `old` (@jennybc, #68).

# 1.2.2

* This version does not add an emoji hash to the output.
Expand Down
14 changes: 11 additions & 3 deletions R/compare.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
#' * `"clipboard"` takes the session info from the system clipboard.
#' If the clipboard contains a URL, it is followed to download the
#' session info.
#' * A URL starting with `http://` or `https://`. `session_diff` searches
#' the HTML (or text) page for the session info header to find the session
#' info.
#' * The URL where you inspect the results for a GitHub Actions job.
#' Typically has this form:
#' ```
#' https://github.com/OWNER/REPO/runs/JOB_ID?check_suite_focus=true
#' ```
#' * Any other URL starting with `http://` or `https://`. `session_diff()`
#' searches the HTML (or text) page for the session info header to find the
#' session info.
#'
#'
#' @export
#' @examplesIf FALSE
Expand Down Expand Up @@ -61,6 +67,8 @@ get_session_info <- function(src, name = NULL, ...) {
get_session_info_local(...)
} else if (is_string(src) == 1 && src == "clipboard") {
get_session_info_clipboard()
} else if (is_string(src) && is_gha_url(src)) {
get_session_info_gha(src)
} else if (is_string(src) && grepl("https?://", src)) {
get_session_info_url(src)
} else {
Expand Down
89 changes: 89 additions & 0 deletions R/github-actions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# taken from usethis
# definitely designed for GitHub URLs but not overtly GitHub-specific
# https://stackoverflow.com/questions/2514859/regular-expression-for-git-repository
# https://git-scm.com/docs/git-clone#_git_urls
# https://stackoverflow.com/questions/27745/getting-parts-of-a-url-regex
github_url_regex <- paste0(
"^",
"(?<protocol>\\w+://)?",
"(?<user>.+@)?",
"(?<host>[^/:]+)",
"[/:]",
"(?<repo_owner>[^/]+)",
"/",
"(?<repo_name>[^/#]+)",
"(?<fragment>.*)",
"$"
)

parse_as_gha_url <- function(url) {
res <- re_match(url, github_url_regex)$groups
res$job_id <- re_match(res$fragment, "^/runs/(?<job_id>[0-9]+).*")$groups$job_id

ok <- res$host %in% "github.com" &
!is.na(res$repo_owner) & !is.na(res$repo_name) &!is.na(res$job_id)

data.frame(
owner = ifelse(ok, res$repo_owner, NA_character_),
repo = ifelse(ok, res$repo_name, NA_character_),
job_id = ifelse(ok, res$job_id, NA_character_),
stringsAsFactors = FALSE,
row.names = NULL
)
}

is_gha_url <- function(url) {
res <- parse_as_gha_url(url)
!is.na(res$job_id)
}

get_session_info_gha <- function(url) {
if (!requireNamespace("gh", quietly = TRUE)) {
stop(
"The gh package is not available.\n",
"This appears to be the URL for a GitHub Actions (GHA) log:\n",
url, "\n",
"You must install the gh package to get session info for GHA job logs."
)
}

dat <- parse_as_gha_url(url)
meta <- gh::gh(
"/repos/{owner}/{repo}/actions/jobs/{job_id}",
owner = dat$owner, repo = dat$repo, job_id = dat$job_id
)
raw_log <- gh::gh(
"/repos/{owner}/{repo}/actions/jobs/{job_id}/logs",
owner = dat$owner, repo = dat$repo, job_id = dat$job_id
)
timestamped_lines <- unlist(strsplit(raw_log$message, split = "\r\n"))
lines <- sub("^[^\\s]+\\s+", "", timestamped_lines, perl = TRUE)

re_start <- "[-=\u2500\u2550][ ]Session info[ ]"
cand <- grep(re_start, lines)
if (length(cand) == 0) stop("Cannot find session info at '", url, "'.")
lines <- lines[cand[1]:length(lines)]
lines[1] <- sub(paste0("^.*(", re_start, ")"), "\\1", lines[1])

grepl_end <- function(lines) {
grepl("^[ ]*\\[[0-9]\\] ", lines) |
grepl("^[ ]*[-\u2500]+$", lines)
}
end <- which(grepl_end(lines))[1]
if (is.na(end)) stop("Cannot parse session info from '", url, "'.")
while (end < length(lines) && grepl_end(lines[end + 1])) {
end <- end + 1
}

si <- get_session_info_literal(lines[1:end])

si$arg <- "github-actions"
si$name <- paste(
meta$name,
meta$conclusion,
paste("job", meta$id),
paste("run", meta$run_id),
sep = " | "
)
si
}
9 changes: 6 additions & 3 deletions man/session_diff.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6c683ac

Please sign in to comment.