Last active
May 19, 2016 20:22
-
-
Save nbenn/7ce01f52f6cdd5277441d487eb066946 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