diff --git a/R/installDepsWithErrManagement.R b/R/installDepsWithErrManagement.R
deleted file mode 100644
index 5a3c99aad7f94b7d94940eb3b326c76fb8983f08..0000000000000000000000000000000000000000
--- a/R/installDepsWithErrManagement.R
+++ /dev/null
@@ -1,185 +0,0 @@
-#' @title devtools::install_dev_deps with error management
-#' @description Add an error and warning management around
-#'              devtools::install_dev_deps call.
-#'              Useful for any R CI.
-#' @param doUpgrades TRUE to pass "always" to subfunction, this force updrage of dependencies.
-#'                   FALSE to pass "never" to subfunction, dependencies will nerver be upgraded.
-#' @param warningsAsErrors Boolean,
-#'                         TRUE to manage warnings and errors as errors.
-#'                         FALSE to manage only errors as errors.
-#' @param printAllMessages Boolean, TRUE to  print all messages
-#'                         printed by devtools::install_dev_deps
-#' @return A list with:
-#'         - errorOccurs: a boolean at TRUE if an error or a warning occurs
-#'         - outputs: a vector containing all outputs
-#'                    generated by devtools::install_dev_deps
-#'         - messages: a vector containing all messages
-#'                     generated by devtools::install_dev_deps
-#' @examples
-#' installDepsWithErrManagement(doUpgrades = TRUE, warningsAsErrors = TRUE, printAllMessages = TRUE)
-installDepsWithErrManagement <- function(doUpgrades = TRUE,
-                                         warningsAsErrors = FALSE,
-                                         printAllMessages = TRUE) {
-    errorOccurs <- installDepsWithSink(
-        doUpgrades = doUpgrades,
-        warningsAsErrors = warningsAsErrors)
-
-    # Print all messages to console
-    if (printAllMessages) {
-        print(errorOccurs)
-    }
-
-    if (!errorOccurs$errorOccurs) {
-        # Check for other problems:
-        # - Check for unavailable packages
-        searchingMessage <- "Skipping \\d* packages not available:"
-        pbs1 <- stringi::stri_detect_regex(
-            str = errorOccurs$outputs,
-            pattern = searchingMessage,
-            case_insensitive = FALSE)
-        pbs2 <- stringi::stri_detect_regex(
-            str = errorOccurs$messages,
-            pattern = searchingMessage,
-            case_insensitive = FALSE)
-        if (any(pbs1) || any(pbs2)) {
-            message <- "Error: Some packages have not been installed"
-            message(message)
-            errorOccurs$errorOccurs <- TRUE
-            errorOccurs$condition <- simpleError(message = message)
-        }
-    }
-
-    if (errorOccurs$errorOccurs) {
-        message("Some error occurs in devtools::install_dev_deps call")
-    }
-
-    return(errorOccurs)
-}
-
-#' @title devtools::install_dev_deps with error and warning catching
-#'        and all outputs messages grabbed
-#' @description Add message grabbing.
-#' @param doUpgrades TRUE to pass "always" to subfunction, this force updrage of dependencies.
-#'                   FALSE to pass "never" to subfunction, dependencies will nerver be upgraded.
-#' @param warningsAsErrors Boolean,
-#'                         TRUE to manage warnings and errors as errors.
-#'                         FALSE to manage only errors as errors.
-#' @return A list with:
-#'         - errorOccurs: a boolean at TRUE if an error is catched
-#'         - condition: a condition object related to the error catched
-#'                      (or NULL if no error catched)
-#'         - outputs: a vector containing all outputs
-#'                    generated by devtools::install_dev_deps
-#'         - messages: a vector containing all messages
-#'                     generated by devtools::install_dev_deps
-#' @examples
-#' installDepsWithSink(doUpgrades = TRUE, warningsAsErrors = FALSE)
-installDepsWithSink <- function(doUpgrades = TRUE,
-                                warningsAsErrors = FALSE) {
-    outputs <- vector("character")
-    messages <- vector("character")
-
-    con1 <- textConnection(
-        object = "outputs",
-        open = "wr",
-        local = TRUE)
-    con2 <- textConnection(
-        object = "messages",
-        open = "wr",
-        local = TRUE)
-
-    sink(file = con1, type = "output")
-    sink(file = con2, type = "message")
-
-    errorOccurs <- installDepsWithWarnCatching(
-        doUpgrades = doUpgrades,
-        warningsAsErrors = warningsAsErrors)
-
-    sink(type = "output")
-    sink(type = "message")
-
-    close(con1)
-    close(con2)
-
-    return(list(errorOccurs = errorOccurs$errorOccurs,
-                condition = errorOccurs$condition,
-                outputs = outputs,
-                messages = messages))
-}
-
-#' @title devtools::install_dev_deps with error and warning catching
-#' @description Add an error and warning catching around
-#'              devtools::install_dev_deps call.
-#' @param doUpgrades TRUE to pass "always" to subfunction, this force updrage of dependencies.
-#'                   FALSE to pass "never" to subfunction, dependencies will nerver be upgraded.
-#' @param warningsAsErrors Boolean,
-#'                         TRUE to manage warnings and errors as errors.
-#'                         FALSE to manage only errors as errors.
-#' @return A list with:
-#'         - errorOccurs: a boolean at TRUE if an error is catched
-#'         - condition: a condition object related to the error catched
-#'                      (or NULL if no error catched)
-#' @examples
-#' installDepsWithWarnCatching(doUpgrades = TRUE, warningsAsErrors = FALSE)
-installDepsWithWarnCatching <- function(doUpgrades = TRUE,
-                                        warningsAsErrors = FALSE) {
-    if (warningsAsErrors) {
-        errorOccurs <- tryCatch(
-            expr = {
-                installDepsWithErrCatching(doUpgrades = doUpgrades)
-            },
-            warning = function(w) {
-                return(list(errorOccurs = TRUE, condition = w))
-            })
-    } else {
-        errorOccurs <- installDepsWithErrCatching(doUpgrades = doUpgrades)
-    }
-    return(errorOccurs)
-}
-
-#' @title devtools::install_dev_deps with error catching
-#' @description Catch any error raised by devtools::install_dev_deps and return it as string
-#' @param doUpgrades TRUE to pass "always" to subfunction, this force updrage of dependencies.
-#'                   FALSE to pass "never" to subfunction, dependencies will nerver be upgraded.
-#' @return A list with:
-#'         - errorOccurs: a boolean at TRUE if an error is catched
-#'         - condition: a condition object related to the error catched
-#'                      (or NULL if no error catched)
-#' @examples
-#' installDepsWithErrCatching(doUpgrades = TRUE)
-installDepsWithErrCatching <- function(doUpgrades = TRUE) {
-    errorOccurs <- tryCatch(
-        expr = {
-            repo <- "https://cloud.r-project.org"
-
-            # Install devtools and stringi packages which are used here
-            # TODO Utiliser installPackageIfNeeded ici quand ce sera dans le paquet r4UREP
-            if (doUpgrades) {
-                message("Force updating (or installing) packages \"devtools\" and \"stringi\"...")
-                install.packages(pkgs = "devtools", repos = repo)
-                install.packages(pkgs = "stringi", repos = repo)
-            } else {
-                if (!require(package = "devtools", character.only = TRUE)) {
-                    message("Installing package \"devtools\"...")
-                    install.packages(pkgs = "devtools", repos = repo)
-                } else {
-                    message("Package \"devtools\" Already installed, skip.")
-                }
-                if (!require(package = "stringi", character.only = TRUE)) {
-                    message("Installing package \"stringi\"...")
-                    install.packages(pkgs = "stringi", repos = repo)
-                } else {
-                    message("Package \"stringi\" Already installed, skip.")
-                }
-            }
-
-            message("Installing dependencies (upgrade=", doUpgrades, ")...")
-            devtools::install_dev_deps(dependencies = TRUE,
-                                       upgrade = doUpgrades)
-            list(errorOccurs = FALSE, condition = NULL)
-        },
-        error = function(e) {
-            return(errorOccurs = TRUE, condition = e)
-        })
-    return(errorOccurs)
-}
diff --git a/R/installPackageIfNeeded.R b/R/installPackageIfNeeded.R
deleted file mode 100644
index 74c3d88f1dac784594013fdf77268a838ddedcd9..0000000000000000000000000000000000000000
--- a/R/installPackageIfNeeded.R
+++ /dev/null
@@ -1,32 +0,0 @@
-#' @title Install a package only if needed
-#' @description Check if a package is already installed,
-#'              if not then install it
-#' @param packageToInstallName Name of the package to install
-#' @param doUpgrades 1 to force re-installation
-#'                   other values to install only if not already installed
-#' @return Nothing
-#' @examples
-#' installPackageIfNeeded()
-installPackageIfNeeded <- function(packageToInstallName, doUpdate) {
-    if (doUpdate == 1) {
-        message("Force installing package \"", packageToInstallName, "\"...")
-        install.packages(pkgs = packageToInstallName, repos = repo)
-    } else {
-        message("Checking if package \"", packageToInstallName, "\" need to be installed...")
-        missingOrError <- tryCatch(
-            expr = {
-                repo <- "https://cloud.r-project.org"
-
-                !require(package = packageToInstallName, character.only = TRUE)
-            },
-            error = function(e) {
-                return(TRUE)
-            })
-
-        if (missingOrError) {
-            message("Package \"", packageToInstallName, "\" must be installed!")
-            message("Installing package \"", packageToInstallName, "\"...")
-            install.packages(pkgs = packageToInstallName, repos = repo)
-        }
-    }
-}
diff --git a/R/optionsForCi.R b/R/optionsForCi.R
deleted file mode 100644
index 01ea1b202bea51ddc9ad1a5d7ef18a26590758d0..0000000000000000000000000000000000000000
--- a/R/optionsForCi.R
+++ /dev/null
@@ -1,16 +0,0 @@
-#' @title Set options for R CI
-#' @description Set some options useful for CI
-#' @return A backup of options before this function call
-#' @examples
-#' beforeOptions <- setOptionsForCi()
-#' # Restor options
-#' options(beforeOptions)
-setOptionsForCi <- function() {
-    optionsBackup <- options()
-    options(showWarnCalls = TRUE, # Show a call stack for warnings
-            showErrorCalls = TRUE, # Show a call stack for errors
-            show.error.messages = TRUE, # Show error message with try or error handler
-            warn = 2) # Warnings turned as errors
-    # Return the value but don't print the value (if no assignement)
-    invisible(optionsBackup)
-}
diff --git a/README.md b/README.md
index bd1feedde64cf3aab1f88a40262303bb5a6b153e..41ed870e114ff617ad33b6b96de2a10b4ca5e3be 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
 # Gitlab CI Templates
 
-[![main CI](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/badges/main/pipeline.svg)](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/commits/main "main branch CI pipeline status!")
+<!-- badges: start -->
+[![Pipeline main branch](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/badges/main/pipeline.svg?key_text=Pipeline+main+branch&key_width=130)](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/pipelines/main/latest)
+[![Latest Release](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/badges/release.svg)](https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/releases)
+<!-- badges: end -->
 
 This repository contains useful Gitlab CI templates files.
 
diff --git a/templates/templates-r.yml b/templates/templates-r.yml
index 9bdbc46c20db0ebd554d4f896fe57bfc54a87007..c93e6bc19a5b6e4b7d0cc04f9f1b4f90cccd3c95 100644
--- a/templates/templates-r.yml
+++ b/templates/templates-r.yml
@@ -2,8 +2,11 @@ include:
   - local: '/templates/templates-checkers.yml'
 
 .R-default-globals:
+  image: rocker/tidyverse
+  tags:
+    - docker
+    - stable
   variables:
-    R_PACKAGE_SOURCE_REPO: "https://cloud.r-project.org"
     R_RUN_CODE_COMMAND: Rscript -e
     # Another option (but with poorer performance):
     #R_RUN_CODE_COMMAND: R -q -e
@@ -11,21 +14,18 @@ include:
     # Other than 1 value disable package update at beginning of all template jobs
     # (1 may be the default value, but this has a very expensive time cost on the CI)
     R_DO_PACKAGE_UPDATE: 0
-    # MUST be redefined if your package folder is not the root directory
+    # MUST be redefined if your package folder isn't the root directory
     #  of the project repository
     R_PACKAGE_ROOT_RELATIVE_PATH: .
     # This generally doesn't need to be redefined
     R_PACKAGE_ROOT_ABSOLUTE_PATH: ${CI_PROJECT_DIR}/${R_PACKAGE_ROOT_RELATIVE_PATH}
   before_script:
-    # Files other than yml must be download because Gitlab include keyword doesn't get it
-    - echo '*** Download required R functions... ***'
-    - mkdir ${CI_PROJECT_DIR}/temp_gitlabTemplates
-    - wget https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/raw/main/R/optionsForCi.R?inline=false
-        --output-document=${CI_PROJECT_DIR}/temp_gitlabTemplates/optionsForCi.R
-    - wget https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/raw/main/R/installPackageIfNeeded.R?inline=false
-        --output-document=${CI_PROJECT_DIR}/temp_gitlabTemplates/installPackageIfNeeded.R
-  after_script:
-    - rm -rf ${CI_PROJECT_DIR}/temp_gitlabTemplates
+    - echo "Installing rlang package..."
+    - ${R_RUN_CODE_COMMAND} 'utils::install.packages(pkgs = "rlang", repos = "https://cloud.r-project.org")'
+    - echo "Installing devtools package..."
+    - ${R_RUN_CODE_COMMAND} 'if (!rlang::is_installed(pkg = "devtools")) {utils::install.packages(pkgs = "devtools", repos = "https://cloud.r-project.org")}'
+    - echo "Installing citoolsr package..."
+    - ${R_RUN_CODE_COMMAND} 'devtools::install_gitlab(repo = "urep/dev_utils/r_utils/citoolsr", host = "https://forgemia.inra.fr")'
 
 .R-package-cache:
   extends:
@@ -37,7 +37,7 @@ include:
   before_script:
     - echo $R_LIBS_USER
     - echo $R_LIBS
-    - mkdir -p $R_LIBS_USER
+    - ${R_RUN_CODE_COMMAND} 'if (!dir.exists(Sys.getenv("R_LIBS_USER"))) {dir.create(Sys.getenv("R_LIBS_USER"), recursive = TRUE)}'
     - ${R_RUN_CODE_COMMAND} '.libPaths()'
     - !reference [.R-default-globals, before_script]
   cache:
@@ -49,37 +49,17 @@ include:
 # Update already installed R packages
 # It is recommended to run this before a package installation
 .R-update-packages:
-  image: rocker/r-base
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
   script:
-    - echo '*** Updating R packages... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        if (Sys.getenv("R_DO_PACKAGE_UPDATE") == 1) {
-          pkgsToUpdate <- old.packages(repos = Sys.getenv("R_PACKAGE_SOURCE_REPO"));
-          if (!is.null(pkgsToUpdate) && nrow(pkgsToUpdate) > 0) {
-            update.packages(repos = Sys.getenv("R_PACKAGE_SOURCE_REPO"), ask = FALSE)
-          }
-        } else {
-          message("Package update disabled by variable R_DO_PACKAGE_UPDATE")
-        }
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::updatePackages(doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))'
 
 # Install all R dependencies for the project
 # This job is in error if a required package is not found
 # (the default behaviour for devtools::install_dev_deps is just print a message,
 #  no error and no warning unfortunately)
 .R-install-package-dependencies-withCache:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -90,43 +70,12 @@ include:
   script:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-update-packages, script]
-    # Files other than yml must be download because Gitlab include keyword doesn't get it
-    - echo '*** Install package dependencies... ***'
-    - wget https://forgemia.inra.fr/urep/dev_utils/gitlab-ci-templates/-/raw/main/R/installDepsWithErrManagement.R?inline=false
-        --output-document=${CI_PROJECT_DIR}/temp_gitlabTemplates/installDepsWithErrManagement.R
-    # TODO Retester en remplaçant "doUpgrades = TRUE" ci-dessous par une valeur dépendant de R_DO_PACKAGE_UPDATE ?
-    #      Il me semble que j'avais des problèmes si "doUpgrades = FALSE", mais lesquels je ne me souviens plus...
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        getwd();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installDepsWithErrManagement.R"));
-
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-
-        resList <- installDepsWithErrManagement(doUpgrades = TRUE,
-                                                warningsAsErrors = TRUE,
-                                                printAllMessages = TRUE);
-
-        if (resList[["errorOccurs"]]) {
-          message <- "Some error occurs in devtools::install_dev_deps call";
-          if (Sys.getenv("TEST_ERROR") == 1) {
-            message(message)
-          } else {
-            stop(message)
-          }
-        }
-
-        if (resList[["errorOccurs"]] == FALSE && Sys.getenv("TEST_ERROR") == 1) {
-          stop("An error is expected but none occurs")
-        }
-        '
+    # #10 : Retester en remplaçant "doUpgrades = TRUE" ci-dessous par une valeur dépendant de R_DO_PACKAGE_UPDATE ?
+    #       Il me semble que j'avais des problèmes si "doUpgrades = FALSE", mais lesquels je ne me souviens plus...
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::installDepsWithErrManagementCi(doUpgrades = TRUE, warningsAsErrors = TRUE, errorExpected = Sys.getenv("TEST_ERROR"))'
 
 # Check if documentation is uptodate
 .R-check-documentation-is-uptodate:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -136,18 +85,9 @@ include:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-update-packages, script]
     - echo '*** Install devtools... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "devtools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); citoolsr::installPackageIfNeeded(packageToInstallName = "devtools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))'
     - echo '*** Check documentation is uptodate... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        devtools::document()
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); devtools::document()'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     # Change on RoxygenNote field of DESCRIPTION file is expected, so we revert this before checking other changes
     - git checkout HEAD -- DESCRIPTION
@@ -157,10 +97,6 @@ include:
 # In case a README.Rmd is used, then a README.md must be manually generated.
 # This job check if this action have been done or not.
 .R-check-README-is-uptodate:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -170,28 +106,15 @@ include:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-update-packages, script]
     - echo '*** Install devtools... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "devtools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); citoolsr::installPackageIfNeeded(packageToInstallName = "devtools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))'
     - echo '*** Check README is uptodate... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        devtools::build_readme()
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); devtools::build_readme()'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
   allow_failure: false
 
 # Run the standard R devtools check() function
 .R-checks:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -200,7 +123,7 @@ include:
   variables:
     # Set to "TRUE" check if the license is a valid standard open source license.
     # Set to "FALSE" to not doing anty check on the license.
-    CHECK_LICENSE: "FALSE"
+    CHECK_LICENSE: "TRUE"
     # For tests purposes (0 or 1 (other values same as 0))
     ERROR_EXPECTED: 0
   script:
@@ -210,39 +133,7 @@ include:
     - apt-get -yq install qpdf
     - !reference [.R-install-package-dependencies-withCache, script]
     - echo '*** Check package... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        checkDir <- "./check";
-        dir.create(checkDir, recursive = TRUE);
-        res <- devtools::check(
-          pkg = ".",
-          document = TRUE,
-          build_args = NULL,
-          manual = FALSE,
-          cran = TRUE,
-          remote = TRUE,
-          incoming = FALSE,
-          force_suggests = TRUE,
-          run_dont_test = FALSE,
-          args = c("--timings", "--no-tests"),
-          env_vars = c("NOT_CRAN" = "TRUE", "_R_CHECK_LICENSE_" = Sys.getenv("CHECK_LICENSE")),
-          quiet = FALSE,
-          check_dir = checkDir,
-          vignettes = TRUE,
-          error_on = "never"
-        );
-        print(res);
-        if (length(res$errors) > 0 || length(res$warnings) > 0 || length(res$notes) > 0) {
-          if (Sys.getenv("ERROR_EXPECTED") != 1) {
-            stop()
-          }
-        } else {
-          if (Sys.getenv("ERROR_EXPECTED") == 1) {
-            stop()
-          }
-        }
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::checkPackage(checkLicense = Sys.getenv("CHECK_LICENSE"), errorExpected = Sys.getenv("ERROR_EXPECTED"))'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     # Change on RoxygenNote field of DESCRIPTION file is expected, so we revert this before checking other changes
     - git checkout HEAD -- DESCRIPTION
@@ -250,10 +141,6 @@ include:
 
 # Run the tests
 .R-run-tests:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -265,34 +152,7 @@ include:
   script:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-install-package-dependencies-withCache, script]
-    - echo '*** Install dependencies... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "testthat", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"));
-        installPackageIfNeeded(packageToInstallName = "devtools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
-    # Run tests
-    - echo '*** Run tests... ***'
-    # Use custom testthat reporter in order to disable test progression tick
-    #  (which is not adapted to the runner log)
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        myReporter <- testthat::ProgressReporter$new(update_interval = Inf, min_time = Inf);
-        res <- devtools::test(reporter = myReporter);
-        print(res);
-        if (any(as.data.frame(res)[["failed"]] > 0) || any(as.data.frame(res)[["warning"]] > 0)) {
-          if (Sys.getenv("ERROR_EXPECTED") != 1) {
-            stop("Some tests failed.")
-          }
-        } else {
-          if (Sys.getenv("ERROR_EXPECTED") == 1) {
-            stop("Some tests must failed, but none failed.")
-          }
-        }
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::runTests(errorExpected = Sys.getenv("ERROR_EXPECTED"))'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
 
@@ -302,10 +162,6 @@ include:
 #  - An html report as artifact
 #  - A Cobertura xml report for display in Gitlab merge requests diffs (with red and green lines)
 .R-run-tests-coverage:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -317,53 +173,7 @@ include:
   script:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-install-package-dependencies-withCache, script]
-    - echo '*** Install covr... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "DT", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"));
-        installPackageIfNeeded(packageToInstallName = "htmltools", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"));
-        installPackageIfNeeded(packageToInstallName = "covr", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
-    # Tests with coverage
-    - echo '*** Run tests... ***'
-    - mkdir coverage
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        cov <- tryCatch(
-          expr = {
-            covr::package_coverage()
-          },
-          error = function(e) {
-            return(FALSE)
-          })
-        print(cov);
-        if (class(cov) == "logical" && cov == FALSE) {
-          if (Sys.getenv("ERROR_EXPECTED") != 1) {
-            stop()
-          }
-        } else {
-          if (Sys.getenv("ERROR_EXPECTED") == 1) {
-            stop()
-          }
-
-          print("Generate covr report...");
-          filename <- file.path("coverage", "coverage-report.html");
-          res <- covr::report(x = cov, file = filename, browse = FALSE);
-          print(res);
-          if (!file.exists(filename)) {stop("File \"", filename, "\" not found!")}
-
-          print("Generate cobertura report...");
-          filename <- file.path("coverage", "cobertura.xml");
-          res <- covr::to_cobertura(cov = cov, filename = filename);
-          print(res);
-          if (!file.exists(filename)) {stop("File \"", filename, "\" not found!")}
-        }
-
-        print("End script...")
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::testsCoverage(errorExpected = Sys.getenv("ERROR_EXPECTED"))'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
   coverage: '/Coverage: \d+\.\d+/'
@@ -380,10 +190,6 @@ include:
 
 # Check lintr rules
 .R-lintr:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -398,36 +204,11 @@ include:
     - echo '*** Install lintr... ***'
     - apt-get update
     - apt-get -yq install libxml2-dev
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "lintr", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
-    - echo '*** Run lintr... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        res <- lintr::lint_package();
-        print(res);
-        if (length(res) > 0) {
-          if (Sys.getenv("ERROR_EXPECTED") != 1) {
-            stop()
-          }
-        } else {
-          if (Sys.getenv("ERROR_EXPECTED") == 1) {
-            stop()
-          }
-        }
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::runLintr(errorExpected = Sys.getenv("ERROR_EXPECTED"))'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
 
 .R-generate-doc-website:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -439,42 +220,7 @@ include:
   script:
     - cd ${R_PACKAGE_ROOT_ABSOLUTE_PATH}
     - !reference [.R-update-packages, script]
-    - echo '*** Install pkgdown... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "pkgdown", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
-    - echo '*** Install devtools... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "installPackageIfNeeded.R"));
-        installPackageIfNeeded(packageToInstallName = "lintr", doUpdate = Sys.getenv("R_DO_PACKAGE_UPDATE"))
-        '
-    - echo '*** Generate doc website... ***'
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        res <- tryCatch(
-          expr = {
-            pkgdown::check_pkgdown();
-            devtools::build_site()
-          },
-          error = function(e) {
-            return(FALSE)
-          })
-        if (class(res) == "logical" && res == FALSE) {
-          if (Sys.getenv("ERROR_EXPECTED") != 1) {
-            stop()
-          }
-        } else {
-          if (Sys.getenv("ERROR_EXPECTED") == 1) {
-            stop()
-          }
-        }
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::generateDocWebsite(errorExpected = Sys.getenv("ERROR_EXPECTED"))'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
   artifacts:
@@ -482,10 +228,6 @@ include:
     - ${R_PACKAGE_ROOT_RELATIVE_PATH}/docs/*
 
 .R-build-source-package:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -497,11 +239,7 @@ include:
     - mkdir -p ${R_PACKAGE_ROOT_ABSOLUTE_PATH}/build
     - echo '*** Build package... ***'
     # Build source package
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        devtools::build(path = file.path(Sys.getenv("R_PACKAGE_ROOT_ABSOLUTE_PATH"), "build"), binary = FALSE)
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); devtools::build(path = file.path(Sys.getenv("R_PACKAGE_ROOT_ABSOLUTE_PATH"), "build"), binary = FALSE)'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
   artifacts:
@@ -509,10 +247,6 @@ include:
       - ${R_PACKAGE_ROOT_RELATIVE_PATH}/build/*.tar.gz
 
 .R-build-linux-binary-package:
-  image: rocker/tidyverse
-  tags:
-    - docker
-    - stable
   extends:
     - .R-default-globals
     - .R-package-cache
@@ -524,13 +258,60 @@ include:
     - mkdir -p ${R_PACKAGE_ROOT_ABSOLUTE_PATH}/build/bin
     - echo '*** Build package... ***'
     # Build binary package
-    - >
-      ${R_RUN_CODE_COMMAND} '
-        source(file.path(Sys.getenv("CI_PROJECT_DIR"), "temp_gitlabTemplates", "optionsForCi.R")); setOptionsForCi();
-        devtools::build(path = file.path(Sys.getenv("R_PACKAGE_ROOT_ABSOLUTE_PATH"), "build", "bin"), binary = TRUE)
-        '
+    - ${R_RUN_CODE_COMMAND} 'citoolsr::setOptionsForCi(); devtools::build(path = file.path(Sys.getenv("R_PACKAGE_ROOT_ABSOLUTE_PATH"), "build", "bin"), binary = TRUE)'
     - echo "Checking if all is correctly managed with git (no versioned item modified, no not versioned item, etc)..."
     - !reference [.check-git-changes-status-base, script]
   artifacts:
     paths:
       - ${R_PACKAGE_ROOT_RELATIVE_PATH}/build/bin/*.tar.gz
+
+# Can't reuse other jobs because Powershell doesn't allow the use of variable as command :(
+.R-build-windows-binary-package:
+  tags:
+    - windows-powershell
+    - stable
+  image: null
+  extends:
+    - .R-default-globals
+    - .R-package-cache
+    - .R-install-package-dependencies-withCache
+  variables:
+    # Other than 1 value disable package update at beginning of all template jobs
+    # (1 may be the default value, but this has a very expensive time cost on the CI)
+    R_DO_PACKAGE_UPDATE: 0
+    # MUST be redefined if your package folder isn't the root directory
+    #  of the project repository
+    R_PACKAGE_ROOT_RELATIVE_PATH: .
+    # This generally doesn't need to be redefined
+    R_PACKAGE_ROOT_ABSOLUTE_PATH: ${CI_PROJECT_DIR}\${R_PACKAGE_ROOT_RELATIVE_PATH}
+    LOCAL_R_LIBS_USER: ci/lib
+    R_LIBS_USER: "${CI_PROJECT_DIR}/${LOCAL_R_LIBS_USER}"
+    R_LIBS: "${R_LIBS_USER}:/usr/local/lib/R/site-library:/usr/local/lib/R/library"
+  before_script:
+    - echo $env:R_LIBS_USER
+    - echo $env:R_LIBS
+    - Rscript -e 'if (!dir.exists(Sys.getenv(\"R_LIBS_USER\"))) {dir.create(Sys.getenv(\"R_LIBS_USER\"), recursive = TRUE)}'
+    - Rscript -e '.libPaths()'
+    - echo "Installing rlang package..."
+    - Rscript -e 'utils::install.packages(pkgs = \"rlang\", repos = \"https://cloud.r-project.org\")'
+    - echo "Installing devtools package..."
+    - Rscript -e 'if (!rlang::is_installed(pkg = \"devtools\")) {utils::install.packages(pkgs = \"devtools\", repos = \"https://cloud.r-project.org\")}'
+    - echo "Installing citoolsr package..."
+    - Rscript -e 'devtools::install_gitlab(repo = \"urep/dev_utils/r_utils/citoolsr\", host = \"https://forgemia.inra.fr\")'
+  script:
+    - cd ${env:R_PACKAGE_ROOT_ABSOLUTE_PATH}
+    - Rscript -e 'citoolsr::updatePackages(doUpdate = Sys.getenv(\"R_DO_PACKAGE_UPDATE\"))'
+    - Rscript -e 'citoolsr::installDepsWithErrManagementCi(doUpgrades = TRUE, warningsAsErrors = TRUE, errorExpected = 0)'
+    - Rscript -e 'if (!dir.exists(file.path(Sys.getenv(\"R_PACKAGE_ROOT_ABSOLUTE_PATH\"), \"build\", \"bin\"))) {dir.create(file.path(Sys.getenv(\"R_PACKAGE_ROOT_ABSOLUTE_PATH\"), \"build\", \"bin\"), recursive = TRUE)}'
+    - echo '*** Build package... ***'
+    # Build binary package
+    - Rscript -e 'citoolsr::setOptionsForCi(); devtools::build(path = file.path(Sys.getenv(\"R_PACKAGE_ROOT_ABSOLUTE_PATH\"), \"build\", \"bin\"), binary = TRUE)'
+  artifacts:
+    paths:
+      - ${R_PACKAGE_ROOT_RELATIVE_PATH}/build/bin/*.zip
+  cache:
+    - key: R-installed-packages-cache
+      paths:
+       - "${LOCAL_R_LIBS_USER}"
+      policy: pull-push
+  allow_failure: true
diff --git a/tests/.gitlab-ci-r-tests.yml b/tests/.gitlab-ci-r-tests.yml
index ecffbd3d38bd5d827bb1027c8947c07b1969d2df..c6d11e6afeb02ac535c495d436f1d29c5b93afa3 100644
--- a/tests/.gitlab-ci-r-tests.yml
+++ b/tests/.gitlab-ci-r-tests.yml
@@ -3,16 +3,17 @@
 include:
   - local: '/templates/templates-r.yml'
 
-Test R Update Packages:
-  extends:
-    - .R-update-packages
-  variables:
-    R_DO_PACKAGE_UPDATE: 1
-  rules:
-    - changes:
-      - .gitlab-ci.yml
-      - tests/.gitlab-ci-r-tests.yml
-      - templates/templates-r.yml
+# Test too long and not particularly necessary
+# Test R Update Packages:
+#   extends:
+#     - .R-update-packages
+#   variables:
+#     R_DO_PACKAGE_UPDATE: 1
+#   rules:
+#     - changes:
+#       - .gitlab-ci.yml
+#       - tests/.gitlab-ci-r-tests.yml
+#       - templates/templates-r.yml
 
 Test R-install-package-dependencies-withCache Good:
   extends:
@@ -122,6 +123,7 @@ Test R-checks Good:
       - R/*
   variables:
     R_PACKAGE_ROOT_RELATIVE_PATH: tests/r-package
+    CHECK_LICENSE: "FALSE"
   script:
     - !reference [.R-checks, script]
 
@@ -137,6 +139,7 @@ Test R-checks Bad:
       - R/*
   variables:
     R_PACKAGE_ROOT_RELATIVE_PATH: tests/r-package-bad-check
+    CHECK_LICENSE: "FALSE"
     ERROR_EXPECTED: 1
   script:
     - !reference [.R-checks, script]
@@ -164,7 +167,7 @@ Test R-run-tests Warning:
       - .gitlab-ci.yml
       - tests/.gitlab-ci-r-tests.yml
       - templates/templates-r.yml
-      - tests/r-package-bad-tests/*
+      - tests/r-package-warning-tests/*
       - R/*
   variables:
     R_PACKAGE_ROOT_RELATIVE_PATH: tests/r-package-warning-tests
@@ -309,8 +312,6 @@ Test R-build-source-package Good:
       then echo "File found"; exit 0;
       else echo "File not found"; exit -1;
       fi
-  when: on_success
-  allow_failure: false
 
 Test R-build-linux-binary-package Good:
   extends:
@@ -330,5 +331,19 @@ Test R-build-linux-binary-package Good:
       then echo "File found"; exit 0;
       else echo "File not found"; exit -1;
       fi
-  when: on_success
-  allow_failure: false
+
+Test R-build-windows-binary-package Good:
+  extends:
+    - .R-build-windows-binary-package
+  rules:
+    - changes:
+      - .gitlab-ci.yml
+      - tests/.gitlab-ci-r-tests.yml
+      - templates/templates-r.yml
+      - tests/r-package/*
+      - R/*
+  variables:
+    R_PACKAGE_ROOT_RELATIVE_PATH: tests\r-package
+  script:
+    - !reference [.R-build-windows-binary-package, script]
+    - if (Test-Path -Path "${R_PACKAGE_ROOT_ABSOLUTE_PATH}/build/bin/minimal_1.0.0.zip" -PathType Leaf) { echo "File found"; exit 0 } else { echo "File not found"; exit -1 }
diff --git a/tests/.gitlab-ci-runner-tests.yml b/tests/.gitlab-ci-runner-tests.yml
index ed8b8883d4a9bfbe4d826c396cae733c7c347a9d..e2384f9a4903dd4a7f0f85f2210115de3724d814 100644
--- a/tests/.gitlab-ci-runner-tests.yml
+++ b/tests/.gitlab-ci-runner-tests.yml
@@ -79,6 +79,57 @@ Test runner HpcUREP shell:
     - clt-hpcurep-s
     - stable
 
+Test runner HpcUREP shell cache 1:
+  extends:
+    - .rules-template
+  tags:
+    - bash
+    - linux-bash
+    - clt-hpcurep-s
+    - stable
+  script:
+    - 'echo "A file for cache test" > "testFile.txt"'
+  cache:
+    - key: UrepCacheTestHpcUREPShell
+      paths:
+       - "testFile.txt"
+      policy: push
+
+Test runner HpcUREP shell cache 2:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner HpcUREP shell cache 1"
+  tags:
+    - bash
+    - linux-bash
+    - clt-hpcurep-s
+    - stable
+  script:
+    - if [[ -f "testFile.txt" ]];
+      then echo "File found";
+      else echo "File not found"; exit -1;
+      fi
+  cache:
+    - key: UrepCacheTestHpcUREPShell
+      paths:
+       - "testFile.txt"
+      policy: pull-push
+
+Test runner HpcUREP shell R available:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner HpcUREP shell"
+  tags:
+    - bash
+    - linux-bash
+    - clt-hpcurep-s
+    - stable
+  script:
+    - Rscript -e 'R.version'
+    - R -q -e 'R.version'
+
 Test runner HpcUREP docker:
   extends:
     - .linux-test-template
@@ -89,6 +140,45 @@ Test runner HpcUREP docker:
     - stable
   image: alpine:3.16
 
+Test runner HpcUREP docker cache 1:
+  extends:
+    - .rules-template
+  tags:
+    - docker
+    - linux-docker
+    - clt-hpcurep-s
+    - stable
+  image: alpine:3.16
+  script:
+    - 'echo "A file for cache test" > "testFile.txt"'
+  cache:
+    - key: UrepCacheTestHpcUREPDocker
+      paths:
+       - "testFile.txt"
+      policy: push
+
+Test runner HpcUREP docker cache 2:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner HpcUREP docker cache 1"
+  tags:
+    - docker
+    - linux-docker
+    - clt-hpcurep-s
+    - stable
+  image: alpine:3.16
+  script:
+    - if [[ -f "testFile.txt" ]];
+      then echo "File found";
+      else echo "File not found"; exit -1;
+      fi
+  cache:
+    - key: UrepCacheTestHpcUREPDocker
+      paths:
+       - "testFile.txt"
+      policy: pull-push
+
 # Allow failure because not working anymore :(, see issue #7
 Test runner HpcUREP use docker:
   extends:
@@ -127,6 +217,21 @@ Test runner HpcUREP use docker dind:
 #     - shiny-server
 #     - test
 
+# Test runner shiny-server shell R available:
+  # extends:
+  #   - .rules-template
+#   needs:
+#     - "Test runner shiny-server shell"
+#   tags:
+#     - bash
+#     - linux-bash
+#     - shiny
+#     - shiny-server
+#     - test
+#   script:
+#     - Rscript -e 'R.version'
+#     - R -q -e 'R.version'
+
 # Test runner shiny-server docker:
 #   extends:
 #     - .linux-test-template
@@ -158,11 +263,90 @@ Test runner HpcUREP use docker dind:
 #     - shiny-server
 #     - test
 
+# Test runner shiny-server shell cache 1:
+#   extends:
+#     - .rules-template
+#   tags:
+#     - bash
+#     - linux-bash
+#     - shiny
+#     - shiny-server
+#     - test
+#   script:
+#     - 'echo "A file for cache test" > "testFile.txt"'
+#   cache:
+#     - key: UrepCacheTestShinyServerShell
+#       paths:
+#        - "testFile.txt"
+#       policy: push
+
+# Test runner shiny-server shell cache 2:
+#   extends:
+#     - .rules-template
+#   needs:
+#     - "Test runner shiny-server shell cache 1"
+#   tags:
+#     - bash
+#     - linux-bash
+#     - shiny
+#     - shiny-server
+#     - test
+#   script:
+#     - if [[ -f "testFile.txt" ]];
+#       then echo "File found";
+#       else echo "File not found"; exit -1;
+#       fi
+#   cache:
+#     - key: UrepCacheTestShinyServerShell
+#       paths:
+#        - "testFile.txt"
+#       policy: pull-push
+
+# Test runner shiny-server docker cache 1:
+#   extends:
+#     - .rules-template
+#   tags:
+#     - docker
+#     - linux-docker
+#     - shiny
+#     - shiny-server
+#     - test
+#   image: alpine:3.16
+#   script:
+#     - 'echo "A file for cache test" > "testFile.txt"'
+#   cache:
+#     - key: UrepCacheTestShinyServerDocker
+#       paths:
+#        - "testFile.txt"
+#       policy: push
+
+# Test runner shiny-server docker cache 2:
+#   extends:
+#     - .rules-template
+#   needs:
+#     - "Test runner shiny-server docker cache 1"
+#   tags:
+#     - docker
+#     - linux-docker
+#     - shiny
+#     - shiny-server
+#     - test
+#   image: alpine:3.16
+#   script:
+#     - if [[ -f "testFile.txt" ]];
+#       then echo "File found";
+#       else echo "File not found"; exit -1;
+#       fi
+#   cache:
+#     - key: UrepCacheTestShinyServerDocker
+#       paths:
+#        - "testFile.txt"
+#       policy: pull-push
+
 ##########################################
 # Tests for clt-dgilmour-p runners       #
 ##########################################
 
-# Allow failure because this PC is not always connected
 Test runner clt-dgilmour-p Windows PowerShell:
   extends:
     - .windows-test-template
@@ -170,9 +354,26 @@ Test runner clt-dgilmour-p Windows PowerShell:
     - windows-powershell
     - stable
     - clt-dgilmour-p
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p Windows PowerShell R available:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner clt-dgilmour-p Windows PowerShell"
+  tags:
+    - windows-powershell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - Rscript -e 'R.version'
+    # This can not work on Powershell because "R" is already a Powershell command
+    #  (which invoke the previously run command)
+    #- R -q -e 'R.version'
+  # Allow failure because this PC is not always connected
   allow_failure: true
 
-# Allow failure because this PC is not always connected
 Test runner clt-dgilmour-p Windows cmd shell:
   extends:
     - .windows-test-template
@@ -180,10 +381,26 @@ Test runner clt-dgilmour-p Windows cmd shell:
     - windows-cmd-shell
     - stable
     - clt-dgilmour-p
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p Windows cmd shell R available:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner clt-dgilmour-p Windows cmd shell"
+  tags:
+    - windows-cmd-shell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - Rscript -e 'R.version'
+    - R -q -e 'R.version'
+  # Allow failure because this PC is not always connected
   allow_failure: true
 
 # Require switching to Windows container on docker desktop
-# Allow failure because not working, see issue #1
+# Not working, see issue #1
 Test runner clt-dgilmour-p Windows docker:
   extends:
     - .windows-test-template
@@ -192,6 +409,7 @@ Test runner clt-dgilmour-p Windows docker:
     - test
     - clt-dgilmour-p
   image: mcr.microsoft.com/windows/nanoserver:1809
+  # Allow failure because this PC is not always connected
   allow_failure: true
 
 Test runner clt-dgilmour-p Windows use docker PowerShell :
@@ -204,6 +422,8 @@ Test runner clt-dgilmour-p Windows use docker PowerShell :
   script:
     - !reference [.use-docker-test-template, script]
     - docker pull mcr.microsoft.com/windows/nanoserver:1809
+  # Allow failure because this PC is not always connected
+  allow_failure: true
 
 Test runner clt-dgilmour-p Windows use docker cmd shell :
   extends:
@@ -215,9 +435,11 @@ Test runner clt-dgilmour-p Windows use docker cmd shell :
   script:
     - !reference [.use-docker-test-template, script]
     - docker pull mcr.microsoft.com/windows/nanoserver:1809
+  # Allow failure because this PC is not always connected
+  allow_failure: true
 
 # Require switching to Windows container on docker desktop
-# Allow failure because not working, see issue #1
+# Not working, see issue #1
 Test runner clt-dgilmour-p Windows use docker dind:
   extends:
     - .use-docker-dind-test-template
@@ -228,4 +450,121 @@ Test runner clt-dgilmour-p Windows use docker dind:
   script:
     - !reference [.use-docker-dind-test-template, script]
     - docker pull mcr.microsoft.com/windows/nanoserver:1809
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p cmd shell cache 1:
+  extends:
+    - .rules-template
+  tags:
+    - windows-cmd-shell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - 'echo "A file for cache test" > "testFile.txt"'
+  cache:
+    - key: UrepCacheTestWinCmdShell
+      paths:
+       - "testFile.txt"
+      policy: push
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p cmd shell cache 2:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner clt-dgilmour-p cmd shell cache 1"
+  tags:
+    - windows-cmd-shell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - If exist "testFile.txt" (
+        echo "File found"
+      ) else (
+        echo "File not found" & exit -1
+      )
+  cache:
+    - key: UrepCacheTestWinCmdShell
+      paths:
+       - "testFile.txt"
+      policy: pull-push
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p powershell cache 1:
+  extends:
+    - .rules-template
+  tags:
+    - windows-powershell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - New-Item testFile.txt
+    - Set-Content testFile.txt 'A file for cache test'
+  cache:
+    - key: UrepCacheTestWinPowerShell
+      paths:
+       - "testFile.txt"
+      policy: push
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p powershell cache 2:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner clt-dgilmour-p powershell cache 1"
+  tags:
+    - windows-powershell
+    - stable
+    - clt-dgilmour-p
+  script:
+    - if (Test-Path -Path "testFile.txt" -PathType Leaf) { echo "File found"; exit 0 } else { echo "File not found"; exit -1 }
+  cache:
+    - key: UrepCacheTestWinPowerShell
+      paths:
+       - "testFile.txt"
+      policy: pull-push
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p docker cache 1:
+  extends:
+    - .rules-template
+  tags:
+    - windows-docker
+    - test
+    - clt-dgilmour-p
+  image: mcr.microsoft.com/windows/nanoserver:1809
+  script:
+    - New-Item testFile.txt
+    - Set-Content testFile.txt 'A file for cache test'
+  cache:
+    - key: UrepCacheTestWinDocker
+      paths:
+       - "testFile.txt"
+      policy: push
+  # Allow failure because this PC is not always connected
+  allow_failure: true
+
+Test runner clt-dgilmour-p docker cache 2:
+  extends:
+    - .rules-template
+  needs:
+    - "Test runner clt-dgilmour-p docker cache 1"
+  tags:
+    - windows-docker
+    - test
+    - clt-dgilmour-p
+  image: mcr.microsoft.com/windows/nanoserver:1809
+  script:
+    - if (Test-Path -Path "testFile.txt" -PathType Leaf) { echo "File found"; exit 0 } else { echo "File not found"; exit -1 }
+  cache:
+    - key: UrepCacheTestWinDocker
+      paths:
+       - "testFile.txt"
+      policy: pull-push
+  # Allow failure because this PC is not always connected
   allow_failure: true
diff --git a/tests/r-package-bad-check/DESCRIPTION b/tests/r-package-bad-check/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-bad-check/DESCRIPTION
+++ b/tests/r-package-bad-check/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-bad-doc-website/DESCRIPTION b/tests/r-package-bad-doc-website/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-bad-doc-website/DESCRIPTION
+++ b/tests/r-package-bad-doc-website/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-bad-lintr/DESCRIPTION b/tests/r-package-bad-lintr/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-bad-lintr/DESCRIPTION
+++ b/tests/r-package-bad-lintr/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-bad-tests/DESCRIPTION b/tests/r-package-bad-tests/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-bad-tests/DESCRIPTION
+++ b/tests/r-package-bad-tests/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-doc-not-uptodate/DESCRIPTION b/tests/r-package-doc-not-uptodate/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-doc-not-uptodate/DESCRIPTION
+++ b/tests/r-package-doc-not-uptodate/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-readme-not-uptodate/DESCRIPTION b/tests/r-package-readme-not-uptodate/DESCRIPTION
index 536094fcac35ccba2e4ba7139fe5cdd3180a864e..6e4d0c73f5ab85b25d298f5e7046b9e1e2f85022 100644
--- a/tests/r-package-readme-not-uptodate/DESCRIPTION
+++ b/tests/r-package-readme-not-uptodate/DESCRIPTION
@@ -33,8 +33,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package-warning-tests/DESCRIPTION b/tests/r-package-warning-tests/DESCRIPTION
index 5dfb9bc0ec12adcd380c71f14adaf2459196a087..34ad4def756987473b322cc11d9baa7e53f03a77 100644
--- a/tests/r-package-warning-tests/DESCRIPTION
+++ b/tests/r-package-warning-tests/DESCRIPTION
@@ -32,8 +32,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown
diff --git a/tests/r-package/DESCRIPTION b/tests/r-package/DESCRIPTION
index 5dfb9bc0ec12adcd380c71f14adaf2459196a087..34ad4def756987473b322cc11d9baa7e53f03a77 100644
--- a/tests/r-package/DESCRIPTION
+++ b/tests/r-package/DESCRIPTION
@@ -32,8 +32,6 @@ Suggests:
     tools,
     rmarkdown,
     tinytex,
-    todor,
-    magick,
     spelling,
     covr,
     pkgdown