From f76b0aaed4200ac5049088539f82f50847f0a635 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 14:02:49 +0200 Subject: [PATCH 01/11] fix test so they can run on the installed package - Includes qc doc - Only used for dv.templates other packages must contain their own set of scripts - Includes the testing badge fix tests include qc doc add badge style & lint --- README.md | 1 + inst/validation/results/.gitempty | 0 inst/validation/run_validation.R | 40 ++++++ inst/validation/specs.R | 7 + inst/validation/utils-validation.R | 148 +++++++++++++++++++ inst/validation/val_report.Rmd | 17 +++ inst/validation/val_report_child.Rmd | 205 +++++++++++++++++++++++++++ scripts/test.R | 47 ++++-- tests/testthat/setup.R | 8 ++ tests/testthat/shiny-app/app.R | 6 - tests/testthat/test-hello.R | 7 + tests/testthat/test-shiny.R | 2 +- 12 files changed, 467 insertions(+), 21 deletions(-) create mode 100644 inst/validation/results/.gitempty create mode 100644 inst/validation/run_validation.R create mode 100644 inst/validation/specs.R create mode 100644 inst/validation/utils-validation.R create mode 100644 inst/validation/val_report.Rmd create mode 100644 inst/validation/val_report_child.Rmd create mode 100644 tests/testthat/setup.R delete mode 100644 tests/testthat/shiny-app/app.R diff --git a/README.md b/README.md index 8dd5ead..a228d22 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # dv.templates [![Build status](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/check.yml/badge.svg)](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/check.yml?query=workflow) +[![Build status](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/test.yml/badge.svg)](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/test.yml?query=workflow) [![Build status](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/gitleaks.yml/badge.svg)](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/gitleaks.yml?query=workflow) [![Build status](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/lintr.yml/badge.svg)](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/lintr.yml?query=workflow) [![Build status](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/pkgdown.yml/badge.svg)](https://github.com/boehringer-ingelheim/dv.templates/actions/workflows/pkgdown.yml?query=workflow) diff --git a/inst/validation/results/.gitempty b/inst/validation/results/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/inst/validation/run_validation.R b/inst/validation/run_validation.R new file mode 100644 index 0000000..e66e4c0 --- /dev/null +++ b/inst/validation/run_validation.R @@ -0,0 +1,40 @@ +local({ + # This is evaluated inside a local because, otherwise, all the variables created in the chunks of the rendered + # document leak into the environment + + validation_root <- "./inst/validation" + validation_report_rmd <- file.path(validation_root, "val_report.Rmd") + validation_report_html <- "val_report.html" + validation_results <- file.path(validation_root, "results") + val_param_rds <- file.path(validation_results, "val_param.rds") + + stopifnot(dir.exists(validation_root)) + stopifnot(file.exists(validation_report_rmd)) + + stopifnot(dir.exists(validation_results)) + unlink(list.files(validation_results)) + + saveRDS( + list( + package = pkg_name, + tests = test_results, + version = pkg_version + ), + val_param_rds + ) + + rmarkdown::render( + input = validation_report_rmd, + params = list( + package = pkg_name, + tests = test_results, + version = pkg_version + ), + output_dir = validation_results, + output_file = validation_report_html + ) + + # We use one of the leaked variables, created inside the validation report to asses if the validation is + # succesful or not + VALIDATION_PASSED +}) diff --git a/inst/validation/specs.R b/inst/validation/specs.R new file mode 100644 index 0000000..4903b4f --- /dev/null +++ b/inst/validation/specs.R @@ -0,0 +1,7 @@ +# Use a list to declare the specs + +specs_list <- list + +example_spec <- specs_list( + a_spec = "spec" +) diff --git a/inst/validation/utils-validation.R b/inst/validation/utils-validation.R new file mode 100644 index 0000000..5dc7360 --- /dev/null +++ b/inst/validation/utils-validation.R @@ -0,0 +1,148 @@ +#' Setting up the validation +#' +#' 1. Add package_name +#' 2. Copy that variable and the contents of if block to tests/testthat/setup.R +#' (If you are using the template this may already be in place for you) + +package_name <- "dv.templates" + +if (FALSE) { + # validation (S) + vdoc <- source( + system.file("validation", "utils-validation.R", package = package_name, mustWork = TRUE), + local = TRUE + )[["value"]] + specs <- vdoc[["specs"]] + # validation (F) +} + +#' 2. For those tests that cover an specific spec + +if (FALSE) { + test_that( + vdoc[["add_spec"]]("my test description", specs[["a_spec"]]), + { + expect_true(TRUE) + } + ) +} +#' The specs variable on the call references the one declared in point 1 + +#' 3. For those tests covering more than one spec. +#' NOTE: It must be c() and not list() +#' + +if (FALSE) { + test_that( + vdoc[["add_spec"]]("my test_description", c(specs$my$hier$spec, vdoc_specs$my$hier$other_spec)), + { + expect_true(TRUE) + } + ) +} + +#' Considerations: +#' - parse_spec uses deparse(substitute()). These spec_ids are later used to check if all requirements +#' are covered or not, therefore those calls cannot by substituted for: + +if (FALSE) { + my_spec <- specs$my$hier$spec + test_that(vdoc$parse_spec(my_spec, "my test_description"), { + ... + }) +} + +# In this case the substitute captures my_spec and cannot be used later. +# If you want to do this you must use the spec_id parameter where you pass a +# character vector with the ids. +# Notice that the ids in character form do no longer have the specs particle +# at the beginning, only the pathing of the spec is needed. + +if (FALSE) { + my_spec <- specs$my$hier$spec + test_that(vdoc$parse_spec(my_spec, "my test_description", spec_id = c("my$hier$spec")), { + ... + }) +} + +# Validation code + +local({ + specs <- source( + system.file("validation", "specs.R", package = package_name, mustWork = TRUE), + local = TRUE + )[["value"]] + recursive_ids <- function(x, parent = character(0)) { + if (!is.list(x)) { + return(parent) + } + unlist(mapply(recursive_ids, + x, + paste(parent, names(x), + sep = if (identical(parent, character(0))) "" else "$" + ), + SIMPLIFY = FALSE, USE.NAMES = FALSE + )) + } + + recursive_ids <- function(x, parent = character(0)) { + if (!is.list(x)) { + return(parent) + } + unlist(mapply(recursive_ids, x, + paste(parent, names(x), + sep = if (identical(parent, character(0))) "" else "$" + ), + SIMPLIFY = FALSE, USE.NAMES = FALSE + )) + } + + + spec_id_list <- recursive_ids(specs) + + list( + specs = specs, + spec_id_list = spec_id_list, + add_spec = function(desc, spec, spec_id) { + if (missing(spec_id)) { + if (!is.character(spec) || length(spec) == 0) stop("spec must be a non-empty character vector") + s_spec <- substitute(spec) + if (s_spec[[1]] == "c") { + spec_id <- sapply(s_spec[2:length(s_spec)], identity) + } else { + spec_id <- list(s_spec) # Otherwise the posterior vapply iterates over the expression + } + + spec_id_chr <- vapply(spec_id, function(x) { + sub("^[^$]*\\$", "", deparse(x)) + }, FUN.VALUE = character(1)) + + if (!all(spec_id_chr %in% spec_id_list)) { + stop("At least one spec is not declared in the spec list") + } # This should be covered by pack of constants but just in case + } else { + spec_id_chr <- spec_id + } + structure(desc, spec_id = spec_id_chr, spec = spec) + }, + get_spec = function(result) { + lapply( + result, + function(x) { + first_result <- try( + x[[1]][["test"]], + silent = TRUE + ) + if (inherits(first_result, "try-error")) { + list(spec_id = NULL, desc = NULL) + } else { + list( + spec_id = attr(first_result, "spec_id", exact = TRUE), + spec = attr(first_result, "spec", exact = TRUE) + ) + } + } + ) + } + ) +}) diff --git a/inst/validation/val_report.Rmd b/inst/validation/val_report.Rmd new file mode 100644 index 0000000..26a97e9 --- /dev/null +++ b/inst/validation/val_report.Rmd @@ -0,0 +1,17 @@ +--- +title: "Quality Control" +output: + html_document: + toc: true + toc_depth: 2 + code_folding: hide +toc-title: "----\nIndex" + +params: + package: NULL + tests: NULL + version: NULL +--- + +```{r, child = "val_report_child.Rmd"} +``` diff --git a/inst/validation/val_report_child.Rmd b/inst/validation/val_report_child.Rmd new file mode 100644 index 0000000..38e631f --- /dev/null +++ b/inst/validation/val_report_child.Rmd @@ -0,0 +1,205 @@ + + + +```{r setup, message = FALSE} +# Import vdoc functions ---- +vdoc <- source( + system.file("validation", "utils-validation.R", package = params[["package"]], mustWork = TRUE), + local = TRUE +)[["value"]] + +# Set required packages ---- +suppressPackageStartupMessages(stopifnot(requireNamespace("DT"))) +suppressPackageStartupMessages(stopifnot(requireNamespace("devtools"))) + +# Parse tests ---- + +tests <- as.data.frame(params[["tests"]]) +tests[["validation_data"]] <- vdoc[["get_spec"]](tests[["result"]]) +tests[["spec_id"]] <- sapply(tests[["validation_data"]], function(x) x[["spec_id"]]) +tests[["spec"]] <- sapply(tests[["validation_data"]], function(x) x[["spec"]]) +tests[["spec_id_paste"]] <- vapply(tests[["spec_id"]], function(x) paste(x, collapse = "\n"), FUN.VALUE = character(1)) +tests[["spec_paste"]] <- vapply(tests[["spec"]], function(x) paste(x, collapse = "\n"), FUN.VALUE = character(1)) +tests[["desc"]] <- paste0("(#", seq_len(nrow(tests)), "): ", tests[["test"]]) +tests[["with_spec"]] <- vapply(tests[["spec_id"]], Negate(is.null), FUN.VALUE = logical(1)) + +spec_tests <- tests[tests[["with_spec"]], ] +no_spec_tests <- tests[!tests[["with_spec"]], ] + +declared_spec <- vdoc[["spec_id_list"]] +tested_spec <- unique(unlist(tests[["spec_id"]])) +uncovered_spec <- declared_spec[!declared_spec %in% tested_spec] +undeclared_spec <- tested_spec[!tested_spec %in% declared_spec] + +spec_tests[["are_declared"]] <- sapply(spec_tests[["spec_id"]], function(x) all(x %in% declared_spec)) + +# Count tests in the different categories ---- + +mask_failed <- !!spec_tests[["failed"]] +mask_skipped <- !!spec_tests[["skipped"]] +mask_declared <- spec_tests[["are_declared"]] +n_pass_dec <- sum(!mask_failed & !mask_skipped & mask_declared) +n_fail_dec <- sum(mask_failed & mask_declared) +n_skip_dec <- sum(mask_skipped & mask_declared) +n_uncov <- length(uncovered_spec) +n_undec <- sum(!mask_declared) + +render_spec_table <- function(t) { + t <- t[trac_matrix_col] + colnames(t) <- names(trac_matrix_col) + t <- t[order(t[["Spec ID"]]), ] + DT::datatable(t, options = list(dom = "ltp"), filter = list(position = "top")) +} + +data_frame_by_row <- function(colnames, data) { + n <- length(data) + n_cols <- length(colnames) + stopifnot(n %% n_cols == 0) + columns <- vector("list", length = n_cols) + for (i in 1:n_cols) columns[[i]] <- unlist(data[seq(i, n, n_cols)]) + do.call(data.frame, setNames(columns, colnames)) +} + +# Select columns to be included in the tables ---- +trac_matrix_col <- c("Spec ID" = "spec_id_paste", "Spec" = "spec_paste", "Test Desc" = "desc", "File" = "file") + +# Check that validation passes and set title ---- +VALIDATION_PASSED <- n_fail_dec == 0 && n_uncov == 0 && n_undec == 0 && n_uncov == 0 # nolint + +result_symbol <- if (VALIDATION_PASSED) "\U02705" else "\U274C" +title <- paste(result_symbol, params[["package"]], params[["version"]]) +``` + +## `r title` + +The following document generates a report for R packages, to satisfy the criteria of a "Released" status under the **Non-GxP** project. The QC report contains the following information: + +- **Specifications (specs):** These can be attached to every test that the user adds. +- **Traceability matrix:** Contains test cases with passed, failed, or skipped expectations. +- **Uncovered or undeclared specs** +- **Session Info and System Configuration** + +::: {.infobox .warning} +Please be advised that the QC report generated for this module does not imply validation according to any other GxP criteria. +The QC report only satisfies our internally developed quality checks for non-GxP criteria. +For clinical reporting purposes, it is essential to note that any outputs generated using this module must be checked and verified within a validated system that adheres to the appropriate GxP guidelines. +::: + +---- +# Traceability matrix + +In this traceability matrix only those tests that point to an specification are included. + +Test cases can contain several expectations a test is considered: + + - **passed** if all expectations in the test pass. + + - **failed** if at least one expectation in the test fails. + + - **skipped** if at least one expectation in the test is skipped. + +A test can be both **failed** and **skipped**. + +## Summary + +```{r summary} +data_frame_by_row( + colnames = c("Spec Exists", "Test", "Count", "color"), + data = list( + "Yes", "Pass", n_pass_dec, "white", + "Yes", "Failed", n_fail_dec, if (n_fail_dec > 0) "red" else "green", + "Yes", "Skipped", n_skip_dec, if (n_skip_dec > 0) "red" else "green", + "Yes", "No Test", n_uncov, if (n_uncov > 0) "red" else "green", + "No", "NA", n_undec, if (n_undec > 0) "red" else "green" + ) +) |> + DT::datatable( + rownames = FALSE, + options = list(columnDefs = list(list(visible = FALSE, targets = c(3))), dom = "tp"), + filter = list(position = "top") + ) |> + DT::formatStyle( + c("Count"), + valueColumns = "color", + backgroundColor = DT::JS("value") + ) +``` + +## Passed tests + +```{r passed_test} +render_spec_table(spec_tests[!mask_failed & !mask_skipped & mask_declared, ]) +``` + +## Failed tests + +```{r failed_test} +render_spec_table(spec_tests[mask_failed & mask_declared, ]) +``` + +## Skipped tests + +```{r skipped_test} +render_spec_table(spec_tests[mask_skipped & mask_declared, ]) +``` + +## Uncovered specifications + +```{r uncovered_spec, echo=FALSE} +data.frame("Uncovered Specifications" = uncovered_spec) |> + DT::datatable( + options = list(dom = "ltp"), + filter = list(position = "top") + ) +``` + +## Undeclared specifications + +This should always be empty, as non existant specs are controlled during test execution. + +```{r undeclared_spec, echo=FALSE, results = "asis"} +render_spec_table(spec_tests[!mask_declared, ]) +``` + +# Session Info and System Configuration + +```{r system_conf} +devtools::session_info() +``` + +# List of specifications +```{r spec_list} +j <- vapply( + vdoc[["spec_id_list"]], + function(x) { + eval( + str2expression( + paste0("vdoc[[\"specs\"]]$", x) + ) + ) + }, + FUN.VALUE = character(1) +) |> + gsub("\n", "
", x = _, fixed = TRUE) + +data.frame(spec_id = names(j), spec = j) |> + DT::datatable( + rownames = FALSE, + options = list( + dom = "ltp" + ), + filter = list(position = "top"), + escape = FALSE + ) +``` diff --git a/scripts/test.R b/scripts/test.R index 79804f9..517785c 100644 --- a/scripts/test.R +++ b/scripts/test.R @@ -55,21 +55,32 @@ message("#######################################") message("###### RENDERING VALIDATION (S) ######") message("#######################################") -success[["valdoc"]] <- local({ - # This is evaluated inside a local because, otherwise, all the variables created in the chunks of the rendered - # document leak into the environment +validation_root <- "./inst/validation" +validation_exists <- dir.exists(validation_root) +validation_report_rmd <- file.path(validation_root, "val_report.Rmd") +validation_skip <- file.path(validation_root, "skip_qc") +validation_report_html <- "val_report.html" +validation_results <- file.path(validation_root, "results") +val_param_rds <- file.path(validation_results, "val_param.rds") - validation_root <- "./inst/validation" - validation_report_rmd <- file.path(validation_root, "val_report.Rmd") - validation_report_html <- "val_report.html" - validation_results <- file.path(validation_root, "results") - val_param_rds <- file.path(validation_results, "val_param.rds") - stopifnot(dir.exists(validation_root)) - stopifnot(file.exists(validation_report_rmd)) +if (!dir.exists(validation_root)) { + message("### Quality Control documentation is not present") + message("### Include quality control documentation or skip it by creating following file 'inst/validation/skip_qc'") + stop("QC_doc_not_present") +} - stopifnot(dir.exists(validation_results)) - unlink(list.files(validation_results)) +if (file.exists(validation_skip)) { + success[["valdoc"]] <- NA +} else { + +stopifnot(file.exists(validation_report_rmd)) +stopifnot(dir.exists(validation_results)) +unlink(list.files(validation_results)) + +success[["valdoc"]] <- local({ + # This is evaluated inside a local because, otherwise, all the variables created in the chunks of the rendered + # document leak into the environment saveRDS( list( @@ -95,6 +106,8 @@ success[["valdoc"]] <- local({ VALIDATION_PASSED }) +} + message("#######################################") message("###### RENDERING VALIDATION (F) ######") @@ -112,14 +125,20 @@ github_summary_file <- Sys.getenv("GITHUB_STEP_SUMMARY") summary <- "# Test Summary" summary <- c( summary, - purrr::imap_chr(success, ~ paste(" - ", if (.x) "\U02705" else "\U274C", "\t", .y)) + purrr::imap_chr(success, ~{ + symbol <- "\U02753" + symbol <- if (isTRUE(.x)) "\U02705" + symbol <- if (isFALSE(.x)) "\U0274C" + symbol <- if (is.na(.x)) "\U02757" + paste(" - ", symbol, .y) + }) ) CON <- file(github_summary_file, "a") on.exit(close(CON)) writeLines(summary, CON) -stopifnot(all(success)) +stopifnot(isTRUE(all(success))) message("##############################") message("###### BUILD RESULT (F) ######") diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R new file mode 100644 index 0000000..92d0bdb --- /dev/null +++ b/tests/testthat/setup.R @@ -0,0 +1,8 @@ +package_name <- "dv.templates" +# validation (S) +vdoc <- source( + system.file("validation", "utils-validation.R", package = package_name, mustWork = TRUE), + local = TRUE +)[["value"]] +specs <- vdoc[["specs"]] +# validation (F) diff --git a/tests/testthat/shiny-app/app.R b/tests/testthat/shiny-app/app.R deleted file mode 100644 index 1b5835f..0000000 --- a/tests/testthat/shiny-app/app.R +++ /dev/null @@ -1,6 +0,0 @@ -if (Sys.getenv("CI") == "true") { - pkgload::load_all(Sys.getenv("GITHUB_WORKSPACE")) -} else { - pkgload::load_all() -} -run_app() diff --git a/tests/testthat/test-hello.R b/tests/testthat/test-hello.R index 4dccc45..2d13182 100644 --- a/tests/testthat/test-hello.R +++ b/tests/testthat/test-hello.R @@ -3,3 +3,10 @@ test_that("hello greets the entity", { expected <- "Hello, Foo" expect_identical(result, expected) }) + +test_that( + vdoc[["add_spec"]]("my test description", specs$a_spec), + { + expect_true(TRUE) + } +) diff --git a/tests/testthat/test-shiny.R b/tests/testthat/test-shiny.R index ed05572..9cc0283 100644 --- a/tests/testthat/test-shiny.R +++ b/tests/testthat/test-shiny.R @@ -1,5 +1,5 @@ test_that("the greeter app updates user's name on clicking the button", { - app <- shinytest2::AppDriver$new(app_dir = "./shiny-app", name = "greeting_app") + app <- shinytest2::AppDriver$new(app_dir = run_app(), name = "greeting_app") # WHEN: the user enters their name and clicks the "Greet" button app$set_inputs(name = "Hello Bar") From 4d2e111f2c97f68c4aaab76550cc3224926b9e5e Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 15:20:36 +0200 Subject: [PATCH 02/11] run actions in the same way as packages will --- .github/workflows/check.yml | 11 ----------- .github/workflows/gitleaks.yml | 13 +------------ .github/workflows/lintr.yml | 11 ----------- .github/workflows/pkgdown.yml | 11 ----------- .github/workflows/roxygen.yml | 11 ----------- .github/workflows/shared_ci.yml | 11 +++++++++++ .github/workflows/styler.yml | 11 ----------- .github/workflows/test.yml | 10 +++++----- 8 files changed, 17 insertions(+), 72 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 600f376..4852e0c 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -2,17 +2,6 @@ name: Check 📦 on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main workflow_call: concurrency: diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index d9a2680..10cd967 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -1,18 +1,7 @@ --- name: Gitleaks 🌧️ -on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main +on: workflow_call: inputs: gitleaks-version: diff --git a/.github/workflows/lintr.yml b/.github/workflows/lintr.yml index 34d6c75..24be799 100644 --- a/.github/workflows/lintr.yml +++ b/.github/workflows/lintr.yml @@ -2,17 +2,6 @@ name: Lintr 🔍 on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main workflow_call: inputs: lintr_error_on_lint: diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml index d377b62..a57c0c6 100644 --- a/.github/workflows/pkgdown.yml +++ b/.github/workflows/pkgdown.yml @@ -2,17 +2,6 @@ name: Pkgdown 📖 on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main workflow_call: concurrency: diff --git a/.github/workflows/roxygen.yml b/.github/workflows/roxygen.yml index 14c6d3d..b6b0523 100644 --- a/.github/workflows/roxygen.yml +++ b/.github/workflows/roxygen.yml @@ -2,17 +2,6 @@ name: Roxygen 📄 on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main workflow_call: concurrency: diff --git a/.github/workflows/shared_ci.yml b/.github/workflows/shared_ci.yml index 56967a9..3b6559e 100644 --- a/.github/workflows/shared_ci.yml +++ b/.github/workflows/shared_ci.yml @@ -2,6 +2,17 @@ name: Checks 🧩 on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + branches: + - main + push: + branches: + - main workflow_call: jobs: diff --git a/.github/workflows/styler.yml b/.github/workflows/styler.yml index b6db137..0a65aa8 100644 --- a/.github/workflows/styler.yml +++ b/.github/workflows/styler.yml @@ -2,17 +2,6 @@ name: Styler 🦄 on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main workflow_call: concurrency: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d8cf070..62302f6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,5 @@ --- -name: Test 📦 +name: Test and QC 🧪 on: pull_request: @@ -32,7 +32,7 @@ jobs: - name: Checkout project ⬇️ uses: actions/checkout@v4 - - name: Checkout Repo Templates + - name: Checkout Repo Templates ⬇️ uses: actions/checkout@v4 with: ref: main @@ -42,11 +42,11 @@ jobs: - name: Install package dependencies 📄 uses: boehringer-ingelheim/dv.templates/.github/actions/dependencies@main - - name: Test 📦 + - name: Test and QC 🧪 run: Rscript templates/scripts/test.R - - name: Archive validation results + - name: Archive validation results ⬆️ uses: actions/upload-artifact@v4 with: name: val_results - path: inst/validation/results + path: inst/validation/results \ No newline at end of file From 2bd4bbdcf5a5690d7b0b41ce4a337f56557d1ee7 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 15:22:08 +0200 Subject: [PATCH 03/11] remove call conditions in test.yml --- .github/workflows/test.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 62302f6..ccae72f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,18 +1,7 @@ --- name: Test and QC 🧪 -on: - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - branches: - - main - push: - branches: - - main +on: workflow_call: concurrency: From 26160119875a250da334e6877e7312d89fce999f Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 15:24:59 +0200 Subject: [PATCH 04/11] fix name typo --- .github/workflows/shared_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shared_ci.yml b/.github/workflows/shared_ci.yml index 3b6559e..8ef22c5 100644 --- a/.github/workflows/shared_ci.yml +++ b/.github/workflows/shared_ci.yml @@ -21,7 +21,7 @@ jobs: uses: boehringer-ingelheim/dv.templates/.github/workflows/check.yml@main test: - name: Test 📦 + name: Test and QC 🧪 uses: boehringer-ingelheim/dv.templates/.github/workflows/test.yml@main lintr: From 0476816f73a667687a12266017a37d4cbdd1bc1f Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 22:20:34 +0200 Subject: [PATCH 05/11] add test.yml to workflows.md --- workflows.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/workflows.md b/workflows.md index e74009e..afcfdb8 100644 --- a/workflows.md +++ b/workflows.md @@ -4,6 +4,10 @@ Runs devtools::check() and devtools::test() on the R package inside the checked out repository. +### [`test.yml`](https://github.com/boehringer-ingelheim/dv.templates/blob/main/.github/workflows/test.yml) + +Runs tests on the installed package, generates the qc documentation and uploads it as an artifact for later consumption. + ### [`gitleaks.yml`](https://github.com/boehringer-ingelheim/dv.templates/blob/main/.github/workflows/gitleaks.yml) Runs [`gitleaks`](https://github.com/zricethezav/gitleaks) on the repo to discover any secrets that might have been hardcoded. From bbe3b0e76da07ff5187d02ef3d1e1b9cdff64f8d Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 22:26:56 +0200 Subject: [PATCH 06/11] use shell instead of explicit call to Rscript --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ccae72f..eba7fa9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,7 +32,8 @@ jobs: uses: boehringer-ingelheim/dv.templates/.github/actions/dependencies@main - name: Test and QC 🧪 - run: Rscript templates/scripts/test.R + run: templates/scripts/test.R + shell: Rscript {0} - name: Archive validation results ⬆️ uses: actions/upload-artifact@v4 From c550c58545900b46e850171b56fcd116c4c9182c Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 22:28:30 +0200 Subject: [PATCH 07/11] remove explicit GITHUB_PAT --- .github/workflows/check.yml | 2 -- .github/workflows/lintr.yml | 2 -- .github/workflows/pkgdown.yml | 2 -- .github/workflows/roxygen.yml | 2 -- .github/workflows/styler.yml | 2 -- .github/workflows/test.yml | 2 -- 6 files changed, 12 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4852e0c..43a04ee 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ diff --git a/.github/workflows/lintr.yml b/.github/workflows/lintr.yml index 24be799..94954cb 100644 --- a/.github/workflows/lintr.yml +++ b/.github/workflows/lintr.yml @@ -20,8 +20,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml index a57c0c6..2b7c4cb 100644 --- a/.github/workflows/pkgdown.yml +++ b/.github/workflows/pkgdown.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ diff --git a/.github/workflows/roxygen.yml b/.github/workflows/roxygen.yml index b6b0523..2dd2b6c 100644 --- a/.github/workflows/roxygen.yml +++ b/.github/workflows/roxygen.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ diff --git a/.github/workflows/styler.yml b/.github/workflows/styler.yml index 0a65aa8..313d9e1 100644 --- a/.github/workflows/styler.yml +++ b/.github/workflows/styler.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eba7fa9..65ffc99 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,8 +14,6 @@ jobs: runs-on: ubuntu-latest container: image: ${{ vars.CI_IMAGE }} - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout project ⬇️ From 130610b0e895132c469b85e175f0e5de28b9a820 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Tue, 4 Jun 2024 22:29:04 +0200 Subject: [PATCH 08/11] rename test.R to test_qc_pkg.R --- .github/workflows/test.yml | 2 +- scripts/{test.R => test_qc_pkg.R} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{test.R => test_qc_pkg.R} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65ffc99..722a580 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: uses: boehringer-ingelheim/dv.templates/.github/actions/dependencies@main - name: Test and QC 🧪 - run: templates/scripts/test.R + run: templates/scripts/test_qc_pkg.R shell: Rscript {0} - name: Archive validation results ⬆️ diff --git a/scripts/test.R b/scripts/test_qc_pkg.R similarity index 100% rename from scripts/test.R rename to scripts/test_qc_pkg.R From bcb6e10c702e9f49808a639f11c24e9f18ed9386 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Wed, 5 Jun 2024 10:05:54 +0200 Subject: [PATCH 09/11] refactor test.yml - only clone required directories - move ref branch to variable --- .github/workflows/test.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 722a580..c6d1e25 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,9 @@ concurrency: group: test-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +env: + TEMPLATE_REF: main + jobs: test: name: ${{ vars.CI_IMAGE }} @@ -19,11 +22,14 @@ jobs: - name: Checkout project ⬇️ uses: actions/checkout@v4 - - name: Checkout Repo Templates ⬇️ + - name: Checkout templates repo ⬇️ uses: actions/checkout@v4 with: - ref: main + ref: ${{env.TEMPLATE_REF}} repository: boehringer-ingelheim/dv.templates + sparse-checkout: | + scripts/ + inst/validation path: templates - name: Install package dependencies 📄 From ee651aac1eef575f8f8134749ebd94bf1e27b7b3 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Wed, 5 Jun 2024 10:27:04 +0200 Subject: [PATCH 10/11] move template repo to var in test.yml --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c6d1e25..b20afb3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,7 @@ concurrency: env: TEMPLATE_REF: main + TEMPLATE_repo: boehringer-ingelheim/dv.templates jobs: test: @@ -26,7 +27,7 @@ jobs: uses: actions/checkout@v4 with: ref: ${{env.TEMPLATE_REF}} - repository: boehringer-ingelheim/dv.templates + repository: ${{env.TEMPLATE_REPO}} sparse-checkout: | scripts/ inst/validation From 895073625c1129b8e5c47f0d2030c7bee75b9fa6 Mon Sep 17 00:00:00 2001 From: Luis Moris Fernandez Date: Wed, 5 Jun 2024 10:33:02 +0200 Subject: [PATCH 11/11] fix typo --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b20afb3..933b991 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ concurrency: env: TEMPLATE_REF: main - TEMPLATE_repo: boehringer-ingelheim/dv.templates + TEMPLATE_REPO: boehringer-ingelheim/dv.templates jobs: test: