-
-
Save jwijffels/5bd734ab60ed821e48f65cd5dd65b2da to your computer and use it in GitHub Desktop.
Fetch latest build artifact from gitlab and install as R package.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' Install an R package hosted as a build artifact on gitlab | |
#' | |
#' Gitlab supports the storage of build artifacts which may be utilized as | |
#' distribution mechanism for code binaries. Applying this to scheme to R, a | |
#' build task may be defined (for example for each tagged commit), yielding a | |
#' .zip file of the tar.gz package produced by R CMD build. This function | |
#' fetches the most recent build artifact and installs it as a package. | |
#' | |
#' @param gitlab A string representing the base url of the gitlab host | |
#' @param name The name of the package repository | |
#' @param token The user token, required for accessing the gitlab REST api | |
#' @param ... All further arguments are passed to install.packages | |
#' | |
#' @return NULL | |
#' | |
install.gitlab <- function(gitlab, name, token, ...) { | |
library(httr) | |
base <- paste0(gitlab, "/api/v3/") | |
resp <- GET(paste0(base, "projects"), add_headers("PRIVATE-TOKEN"=token)) | |
json <- content(resp) | |
id.project <- lapply(json, function(project, name) { | |
if(project$name == name) return(project$id) | |
else return(NULL) | |
}, name=name) | |
id.project <- unlist(id.project) | |
if(length(id.project) != 1) warning("expecting to find exactly 1 repo match.") | |
resp <- GET(paste0(base, "projects/", id.project, "/builds"), | |
add_headers("PRIVATE-TOKEN"=token)) | |
json <- content(resp) | |
build <- lapply(json, function(build) { | |
if(!is.null(build$artifacts_file$filename)) { | |
id <- build$id | |
date <- build$started_at | |
date <- gsub(paste0("^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:", | |
"[0-9]{2}\\.[0-9]+[+-][0-9]{2}):([0-9]{2})$"), | |
"\\1\\2", date) | |
date <- as.POSIXct(strptime(date, "%Y-%m-%dT%H:%M:%OS%z")) | |
return(list(id, date)) | |
} | |
else return(NULL) | |
}) | |
build <- lapply(build, data.frame) | |
build <- do.call(rbind.data.frame, build) | |
colnames(build) <- c("build_id", "build_date") | |
latest <- build$build_id[tail(order(build$build_date), n=1)] | |
resp <- GET(paste0(base, "projects/", id.project, "/builds/", latest, | |
"/artifacts"), | |
add_headers("PRIVATE-TOKEN"=token)) | |
tempdir <- paste0(tempdir(), "/build_", name) | |
tmpexis <- dir.exists(tempdir) | |
if(!tmpexis) dir.create(tempdir) | |
tempzip <- paste0(tempdir, "/", name, ".zip") | |
if(file.exists(tempzip)) stop(".zip already exists in temp dir.") | |
temptar <- list.files(tempdir, pattern="*.tar.gz", full.names=T) | |
if(length(temptar) != 0) stop("some .tar.gz already exists in temp dir.") | |
writeBin(content(resp, "raw"), tempzip) | |
unzip(tempzip, exdir=tempdir) | |
temptar <- list.files(tempdir, pattern="*.tar.gz", full.names=T) | |
if(length(temptar) != 1) stop("expecting exactly 1 .tar.gz file in temp dir.") | |
install.packages(pkgs=temptar, repos=NULL, type="source", ...) | |
if(tmpexis) unlink(c(tempzip, temptar)) | |
else unlink(tempdir, recursive=T) | |
return(invisible(NULL)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment