Skip to content

Commit 27b698b

Browse files
committed
WIP
1 parent 239d225 commit 27b698b

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

.github/workflows/runner.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ jobs:
1313
- uses: r-lib/actions/setup-r@v2
1414
with:
1515
extra-repositories: https://mrc-ide.r-universe.dev
16-
- uses: mrc-ide/orderly-action@main
16+
- uses: r-lib/actions/setup-r-dependencies@v2
1717
with:
18-
packit-url: https://packit.dide.ic.ac.uk/reside
18+
packages: cli, httr2
19+
dependencies: NA
20+
- name: Execute tasks
21+
shell: bash
22+
run: Rscript --verbose 'run.R'

run.R

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
PACKIT_URL <- "https://packit.dide.ic.ac.uk/reside"
2+
3+
get_packit_audience <- function(base_url) {
4+
response <- httr2::request(base_url) |>
5+
httr2::req_url_path_append("packit/api/auth/login/service/audience") |>
6+
httr2::req_perform() |>
7+
httr2::resp_body_json()
8+
response$audience
9+
}
10+
11+
get_oidc_token <- function(audience) {
12+
url <- Sys.getenv("ACTIONS_ID_TOKEN_REQUEST_URL", NA)
13+
token <- Sys.getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN", NA)
14+
15+
if (is.na(url) || is.na(token)) {
16+
cli::cli_abort(paste(
17+
"ID token environment variables are not set. Make sure you have added",
18+
"the {.code id-token: write} permission to your workflow."))
19+
}
20+
21+
response <- httr2::request(url) |>
22+
httr2::req_url_query(audience=audience) |>
23+
httr2::req_auth_bearer_token(token) |>
24+
httr2::req_perform() |>
25+
httr2::resp_body_json()
26+
response$value
27+
}
28+
29+
get_packit_token <- function(base_url, token) {
30+
response <- httr2::request(base_url) |>
31+
httr2::req_url_path_append("packit/api/auth/login/service") |>
32+
httr2::req_body_json(list(token = token)) |>
33+
httr2::req_perform() |>
34+
httr2::resp_body_json()
35+
response$token
36+
}
37+
38+
task_run <- function(branch, hash, name) {
39+
req <- httr2::request(PACKIT_URL) |>
40+
httr2::req_url_path_append("packit/api/runner/run") |>
41+
httr2::req_auth_bearer_token(packit_token) |>
42+
httr2::req_body_json(list(name = name, branch = branch, hash = hash))
43+
44+
task <- httr2::req_perform(req) |>
45+
httr2::resp_body_json()
46+
47+
task$taskId
48+
}
49+
50+
task_status <- function(task_id, include_logs = FALSE) {
51+
req <- httr2::request(PACKIT_URL) |>
52+
httr2::req_auth_bearer_token(packit_token) |>
53+
httr2::req_url_path_append("packit/api/runner/status", task_id) |>
54+
httr2::req_url_query(includeLogs = include_logs)
55+
56+
httr2::req_perform(req) |>
57+
httr2::resp_body_json()
58+
}
59+
60+
task_logs <- function(task_id) {
61+
unlist(task_status(task_id, include_logs = TRUE)$logs)
62+
}
63+
64+
task_wait <- function(task_id) {
65+
while (TRUE) {
66+
status <- task_status(task_id)
67+
if (status$status != "RUNNING") {
68+
return(status)
69+
}
70+
Sys.sleep(1)
71+
}
72+
}
73+
74+
# The server will match its configured audience against the one found in the
75+
# token exactly. A mismatch could occur if, for example, the user provided a
76+
# non-canonical URL that routes to the same place but isn't strictly equal
77+
# (eg. using `https://hostname:443` instead of just `https://hostname`).
78+
#
79+
# It is tempting to just use the audience provided by the server instead of
80+
# PACKIT_URL and not have to worry about it ever failing to match. If we did
81+
# that though, a malicious server could present an arbitrary audience and use
82+
# the token we give it to login to a completely different service on behalf on
83+
# this action, and we do not want to allow that.
84+
#
85+
# This warning provides an easy diagnostic and resolution path for the benign
86+
# case of a non-canonical URL, while avoiding the aforementioned pitfall.
87+
expected_audience <- get_packit_audience(PACKIT_URL)
88+
if (expected_audience != PACKIT_URL) {
89+
cli::cli_warn(
90+
paste("The Packit URL is {.url {PACKIT_URL}}, but the server is expecting",
91+
"the audience to be {.url {expected_audience}}. Authentication is",
92+
"likely to fail."))
93+
}
94+
95+
github_token <- get_oidc_token(PACKIT_URL)
96+
packit_token <- get_packit_token(PACKIT_URL, github_token)
97+
98+
ref_name <- Sys.getenv("GITHUB_REF_NAME", "main")
99+
sha <- Sys.getenv("GITHUB_SHA", "HEAD")
100+
name <- "incoming_data"
101+
102+
task_id <- task_run(ref_name, sha, name)
103+
task_wait(task_id)
104+
status <- task_status(task_id)
105+
writeLines(unlist(status$logs))
106+
107+
if (status$status != "COMPLETE") {
108+
cli::cli_abort("Task failed")
109+
}

0 commit comments

Comments
 (0)