I would like to add the latest Github release identifier and date, as well as the latest date in which a workflow was executed successfully to a (R)markdown file.
For example, for the repository https://github.com/twbs/bootstrap, I would like to add to my (R)markdown file the following:
This is the release {release_id}, published on {release_date}.
The software was validated successfully on {myworkflow.latest_successfully_date}.
Where {release_id}
, {release_date}
and {myworkflow.latest_successfully_date}
are the information about the identifier of the release (v.5.3.2 in the example repository), the date of the release (14 September 2023 in the example repository) and the date of the latest successful run for the myworkflow
(11:29 AM GMT+1 for the, let's say, bundlewatch workflow in the example repository), respectively.
Can you help me? Please, provide a detailed answer with some reference, so I can understand why it works and how I can extend the solution to similar situations. I'm an intermediate R user with very limited knowledge of git and HTML and almost no knowledge of javascript.
Thank you.
Getting a report on the current version might be complicated. You might have uncommitted changes in your local copy, you might have commits that haven't been pushed to Github, and you might have tags that are different from the tags on Github. You need a series of queries to answer all of these questions.
The gert
package can get information from a local git repository, and gh
can work with the Github API to get Github information.
Using those, I put together this function to generate a report on the current state of a local repository. It's not formatted for R Markdown, and there may be things that are different in your repository than the assumptions I made. But it's a start.
stopifnot(requireNamespace("gert"),
requireNamespace("gh"))
versionReport <- function(repo = ".", max = 100, remotename = "origin") {
changes <- gert::git_status(repo = repo)
branch <- gert::git_branch(repo = repo)
log <- gert::git_log(repo = repo, max = max)[,
c("commit", "author", "time")]
tags <- gert::git_tag_list(repo = repo)[, c("commit", "name")]
log <- merge(log, tags, by = "commit", all.x = TRUE,
all.y = FALSE)
remote <- gert::git_remote_list(repo = repo)
remote <- subset(remote, name == remotename)
if (nrow(remote)) {
remotels <- gert::git_remote_ls(remote = remotename,
repo = repo)[, c("oid", "ref")]
names(remotels) <- c("commit", "remoteref")
remotetags <- subset(remotels, grepl("^refs/tags", remoteref))
log <- merge(log, remotetags, all.x = TRUE, all.y = FALSE)
}
o <- order(log$time, decreasing = TRUE)
log <- log[o, ]
remotetags <- subset(log, !is.na(name))
if (nrow(remote) && nrow(remotetags)) {
ref <- sub("https://github.com", "/repos", remote$url)
releases <- try(releases <- gh::gh(paste0(ref, "/releases")))
if (inherits(releases, "try-error"))
releases <- NULL
else {
releases <- data.frame(name = sapply(releases, function(x) x$tag_name),
release = sapply(releases,
function(x) x$name),
published = as.Date(sapply(releases,
function(x) x$published_at)))
remotetags <- merge(remotetags, releases, all.x = TRUE, all.y = FALSE)
o <- order(remotetags$time, decreasing = TRUE)
remotetags <- remotetags[o, ]
}
}
result <- structure(list(repo = normalizePath(repo),
time = Sys.time(),
changes = changes,
branch = branch,
log = log,
remote = remote,
remotetags = remotetags),
class = "gitVersionInfo")
}
print.gitVersionInfo <- function(x, ...) {
cat("Report on ", x$repo, "\n",
" at: ", format(x$time), "\n\n")
if (nrow(changes <- x$changes))
cat("Uncommitted files: \n",
paste(changes$file, collapse = ", "), "\n\n")
cat("git branch: ", x$branch, "\n\n")
log <- x$log
cat("Latest commit: \n",
" SHA: ", log$commit[1], "\n",
" Author: ", log$author[1], "\n",
" Time: ", format(log$time[1]), "\n\n")
tags <- log[!is.na(log$name),]
if (nrow(tags)) {
tag <- tags[1,]
cat("Most recent local tag: \n",
" Name: ", tag$name, "\n",
" SHA: ", tag$commit, "\n",
" Time: ", format(tag$time), "\n\n")
} else
cat("No recent tags.\n\n")
if (nrow(remote <- x$remote))
cat("remote:\n",
" name: ", remote$name, "\n",
" url: ", remote$url, "\n\n")
if (nrow(remotetags <- x$remotetags)) {
remotetag <- basename(remotetags[1, "remoteref"])
if (remotetag != tags[1, "name"])
cat("Most recent remote tag: \n",
" Name: ", remotetag, "\n",
" SHA: ", remotetags[1, "commit"], "\n",
" Time: ", format(remotetags[1, "time"]), "\n\n")
else
cat("Same remote tag.\n\n")
} else
cat("No recent remote tags.\n\n")
releases <- subset(remotetags, !is.na(release))
if (nrow(releases))
cat("Github release: \n",
" name: ", releases$name[1], "\n",
" SHA: ", releases$commit[1], "\n",
" published: ", format(releases$published[1]), "\n\n")
else
catlf("No Github release found.\n\n")
}
report <- versionReport(".")
print(report)
#> Report on .../bootstrap
#> at: 2023-11-19 12:00:56
#>
#> Uncommitted files: .gitignore, bootstrap.Rproj
#>
#> git branch: "main"
#>
#> Latest commit:
#> SHA: e4f0d61c8fe67e041729f8295339020969677a9c
#> Author: Julien Déramond <juderamond@gmail.com>
#> Time: 2023-11-18 03:52:03
#>
#> Most recent local tag:
#> Name: v5.3.2
#> SHA: 344e912d04b5b6a04482113eff20ab416ff01048
#> Time: 2023-09-14 10:19:27
#>
#> Origin is https://github.com/twbs/bootstrap
#>
#> Same remote tag.
#>
#> Github release:
#> id: v5.3.2
#> date: 2023-09-14