6363 extra-packages : |
6464 local::.
6565 any::lintr
66+ any::jsonlite
6667
6768 - name : Run lintr
6869 run : |
@@ -80,3 +81,144 @@ jobs:
8081 with :
8182 sarif_file : lintr-results.sarif
8283 wait-for-processing : true
84+
85+ - name : Install jarl
86+ uses : etiennebacher/setup-jarl@v0.1.1
87+ continue-on-error : true
88+ with :
89+ args : " --version"
90+
91+ - name : Run jarl
92+ run : |
93+ jarl check . --output-format json > jarl-results.json
94+ continue-on-error : true
95+
96+ - name : Convert jarl results to SARIF
97+ run : |
98+ library(jsonlite)
99+
100+ `%||%` <- function(x, y) {
101+ if (is.null(x) || length(x) == 0) y else x
102+ }
103+
104+ as_sarif_uri <- function(path) {
105+ path <- gsub("\\\\", "/", path)
106+ path <- sub("^\\./", "", path)
107+ path
108+ }
109+
110+ as_file_uri <- function(path) {
111+ path <- normalizePath(path, winslash = "/", mustWork = FALSE)
112+ if (.Platform$OS.type == "windows") {
113+ paste0("file:///", path, "/")
114+ } else {
115+ paste0("file://", path, "/")
116+ }
117+ }
118+
119+ jarl <- fromJSON("jarl-results.json", simplifyVector = FALSE)
120+ diagnostics <- jarl$diagnostics %||% list()
121+
122+ rule_ids <- unique(vapply(
123+ diagnostics,
124+ function(x) x$message$name %||% "jarl",
125+ character(1)
126+ ))
127+
128+ rules <- lapply(rule_ids, function(id) {
129+ diagnostic <- diagnostics[[match(
130+ id,
131+ vapply(
132+ diagnostics,
133+ function(x) x$message$name %||% "jarl",
134+ character(1)
135+ )
136+ )]]
137+
138+ list(
139+ id = id,
140+ fullDescription = list(
141+ text = diagnostic$message$body %||% id
142+ ),
143+ help = list(
144+ text = diagnostic$message$suggestion %||% ""
145+ ),
146+ defaultConfiguration = list(
147+ level = "warning"
148+ )
149+ )
150+ })
151+
152+ rule_index <- setNames(seq_along(rule_ids) - 1L, rule_ids)
153+
154+ results <- lapply(diagnostics, function(x) {
155+ id <- x$message$name %||% "jarl"
156+
157+ msg <- paste(
158+ c(
159+ x$message$body %||% id,
160+ if (!is.null(x$message$suggestion)) {
161+ paste("Suggestion:", x$message$suggestion)
162+ }
163+ ),
164+ collapse = "\n"
165+ )
166+
167+ list(
168+ ruleId = id,
169+ ruleIndex = unname(rule_index[[id]]),
170+ message = list(text = msg),
171+ locations = list(
172+ list(
173+ physicalLocation = list(
174+ artifactLocation = list(
175+ uri = as_sarif_uri(x$filename %||% ""),
176+ uriBaseId = "ROOTPATH"
177+ ),
178+ region = list(
179+ startLine = max(1L, x$location$row %||% 1L),
180+ startColumn = max(1L, x$location$column %||% 1L)
181+ )
182+ )
183+ )
184+ )
185+ )
186+ })
187+
188+ sarif <- list(
189+ `$schema` = "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
190+ version = "2.1.0",
191+ runs = list(
192+ list(
193+ tool = list(
194+ driver = list(
195+ name = "jarl",
196+ informationUri = "https://jarl.etiennebacher.com/",
197+ rules = rules
198+ )
199+ ),
200+ columnKind = "utf16CodeUnits",
201+ originalUriBaseIds = list(
202+ ROOTPATH = list(
203+ uri = as_file_uri(getwd())
204+ )
205+ ),
206+ results = results
207+ )
208+ )
209+ )
210+
211+ write_json(
212+ sarif,
213+ "jarl-results.sarif",
214+ auto_unbox = TRUE,
215+ pretty = TRUE
216+ )
217+ shell : Rscript {0}
218+
219+ - name : Upload analysis results to GitHub
220+ uses : github/codeql-action/upload-sarif@v4
221+ with :
222+ sarif_file : jarl-results.sarif
223+ wait-for-processing : true
224+
0 commit comments