From 3a7243418612838990af0161bb7b7da618725c4e Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 9 Jan 2025 08:57:28 +0100 Subject: [PATCH] chore: copy over admiralci workflows with minimal changes --- .github/workflows/lintr.yml | 145 ++++++++++++ .github/workflows/main.yml | 379 ++---------------------------- .github/workflows/man-pages.yml | 111 +++++++++ .github/workflows/r-cmd-check.yml | 227 ++++++++++++++++++ .github/workflows/spellcheck.yml | 88 +++++++ 5 files changed, 597 insertions(+), 353 deletions(-) create mode 100644 .github/workflows/lintr.yml create mode 100644 .github/workflows/man-pages.yml create mode 100644 .github/workflows/r-cmd-check.yml create mode 100644 .github/workflows/spellcheck.yml diff --git a/.github/workflows/lintr.yml b/.github/workflows/lintr.yml new file mode 100644 index 00000000..2f855d93 --- /dev/null +++ b/.github/workflows/lintr.yml @@ -0,0 +1,145 @@ +on: + workflow_dispatch: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: choice + options: + - devel + - latest + lint-all-files: + description: "Lint all files every time" + default: "false" + required: false + type: string + latest-lintr: + description: "Latest lintr CRAN release" + default: "false" + required: false + type: string + install-package: + description: "Install package locally." + default: "false" + required: false + type: string + workflow_call: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: string + lint-all-files: + description: "Lint all files every time" + default: "false" + required: false + type: string + latest-lintr: + description: "Latest lintr CRAN release" + default: "false" + required: false + type: string + install-package: + description: "Install package locally." + default: "false" + required: false + type: string + +name: Lint + +concurrency: + group: lint-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + container: + image: "ghcr.io/pharmaverse/admiralci-${{ inputs.r-version }}:latest" + if: > + !contains(github.event.commits[0].message, '[skip lint]') + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + ##################### BEGIN boilerplate steps ##################### + - name: Get branch names + id: branch-name + uses: tj-actions/branch-names@v8 + + - name: Checkout repo (PR) šŸ›Ž + uses: actions/checkout@v4.2.2 + if: github.event_name == 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: Checkout repository + uses: actions/checkout@v4.2.2 + if: github.event_name != 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + ~/.staged.dependencies + key: staged-deps + + - name: Run Staged dependencies + uses: insightsengineering/staged-dependencies-action@v1 + with: + run-system-dependencies: true + renv-restore: false + enable-check: false + direction: upstream + git-ref: ${{ steps.branch-name.outputs.current_branch }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + - name: Install latest release of lintr + run: | + install.packages("lintr", repos = "https://packagemanager.posit.co/cran/latest/") + shell: Rscript {0} + if: ${{ inputs.latest-lintr == 'true' }} + + - name: Install package + run: renv::install(".", dependencies = "no-deps") + shell: Rscript {0} + if: ${{ inputs.install-package == 'true' }} + ##################### END boilerplate steps ##################### + + - name: Changed files + id: files + uses: Ana06/get-changed-files@v2.2.0 + with: + format: "json" + filter: "*" + + - name: Lint + run: | + exclusions_list <- NULL + if (!identical("${{ inputs.lint-all-files }}", "true")) { + changed_files <- jsonlite::fromJSON('${{ steps.files.outputs.added_modified }}') + all_files <- list.files(recursive = TRUE) + exclusions_list <- if (any(changed_files %in% c(".lintr", "renv.lock"))) { + as.list(setdiff(all_files, changed_files)) + } else { + NULL + } + } + lints <- lintr::lint_package(exclusions = exclusions_list) + saveRDS(lints, file = "lints.rds") + shell: Rscript {0} + + - name: Error if lints are detected + run: | + lints <- readRDS("lints.rds") + if (length(lints) > 0L) { + print(lints) + stop("Lints detected. Please review and adjust code according to the comments provided.", call. = FALSE) + } + shell: Rscript {0} \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d820e916..802324d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,16 +3,7 @@ # the developement process. When package is ready to # be published, revisit and add release-related # workflows. -# The below workflows are based on those provided by admiralci. -# The testing workflow is custom. -# Instead of using reusable actions provided by admiralci, -# the actions are inlined in the workflow file. This is -# because some of the R dependencies required system packages -# not available/installable using reusable actions. -# If any updates are available, the workflow should be -# updated manually. -# Last update: 2025-01-07 -name: Modified Admiral CI/CD Wortkflows +name: admiral CI/CD Workflows on: workflow_dispatch: @@ -41,160 +32,28 @@ jobs: id: get_r_version run: echo "R_VERSION=$R_VERSION" >> $GITHUB_OUTPUT shell: bash - spellcheck: name: Spelling - runs-on: ubuntu-latest + uses: ./.github/workflows/spellcheck.yml + if: github.event_name == 'pull_request' needs: get_r_version - container: - image: "ghcr.io/pharmaverse/admiralci-${{ needs.get_r_version.outputs.r-version }}:latest" - steps: - - name: Get branch names - id: branch-name - uses: tj-actions/branch-names@v8 - - - name: Checkout repo - uses: actions/checkout@v4.2.2 - if: github.event_name == 'pull_request' - with: - ref: ${{ steps.branch-name.outputs.head_ref_branch }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - - name: Restore cache - uses: actions/cache@v4 - with: - path: | - ~/.staged.dependencies - key: staged-deps - - - name: Run Staged dependencies - uses: insightsengineering/staged-dependencies-action@v1 - with: - run-system-dependencies: true - renv-restore: false - enable-check: false - direction: upstream - git-ref: ${{ steps.branch-name.outputs.current_branch }} - - - name: Run Spellcheck - uses: insightsengineering/r-spellcheck-action@v3 - - lint: + with: + r-version: "${{ needs.get_r_version.outputs.r-version }}" + linter: name: Lint - runs-on: ubuntu-latest + uses: ./.github/workflows/lintr.yml needs: get_r_version - container: - image: "ghcr.io/pharmaverse/admiralci-${{ needs.get_r_version.outputs.r-version }}:latest" - steps: - - name: Get branch names - id: branch-name - uses: tj-actions/branch-names@v8 - - - name: Checkout repo - uses: actions/checkout@v4.2.2 - if: github.event_name == 'pull_request' - with: - ref: ${{ steps.branch-name.outputs.head_ref_branch }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - - name: Restore cache - uses: actions/cache@v4 - with: - path: | - ~/.staged.dependencies - key: staged-deps - - - name: Run Staged dependencies - uses: insightsengineering/staged-dependencies-action@v1 - with: - run-system-dependencies: true - renv-restore: false - enable-check: false - direction: upstream - git-ref: ${{ steps.branch-name.outputs.current_branch }} - - - name: Install latest release of lintr - shell: Rscript {0} - run: | - install.packages("lintr", repos = "https://packagemanager.posit.co/cran/latest/") - - - - name: Lint - shell: Rscript {0} - run: | - lints <- lintr::lint_package() - if (length(lints) > 0L) { - print(lints) - stop("Lints detected. Please review and adjust code according to the comments provided.", call. = FALSE) - } - + if: github.event_name == 'pull_request' + with: + r-version: "${{ needs.get_r_version.outputs.r-version }}" man-pages: name: Man Pages - runs-on: ubuntu-latest + uses: ./.github/worflows/man-pages.yml needs: get_r_version - container: - image: "ghcr.io/pharmaverse/admiralci-${{ needs.get_r_version.outputs.r-version }}:latest" - steps: - - name: Get branch names - id: branch-name - uses: tj-actions/branch-names@v8 - - - name: Checkout repo - uses: actions/checkout@v4.2.2 - if: github.event_name == 'pull_request' - with: - ref: ${{ steps.branch-name.outputs.head_ref_branch }} - - - name: Restore cache - uses: actions/cache@v4 - with: - path: | - ~/.staged.dependencies - key: staged-deps - - - name: Run Staged dependencies - uses: insightsengineering/staged-dependencies-action@v1 - with: - run-system-dependencies: false - renv-restore: false - enable-check: false - direction: upstream - git-ref: ${{ steps.branch-name.outputs.current_branch }} - - - name: Install dependencies - run: | - Rscript -e 'pak::local_install_deps(dependencies = TRUE)' - - - name: Generate man pages - run: roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace')) - shell: Rscript {0} - - - name: Set-up safe dir - run: git config --global --add safe.directory "${GITHUB_WORKSPACE}" - shell: bash - - - name: Roxygen check - run: | - git status -s - if [[ -n `git status -s | grep -E "man|DESCRIPTION"` ]] - then { - ROXYGEN_VERSION="$(Rscript -e 'packageVersion("roxygen2")' | awk '{print $NF}')" - echo "šŸ™ˆ Manuals are not up-to-date with roxygen comments!" - echo "šŸ”€ The following differences were noted:" - git diff man/* DESCRIPTION - echo -e "\nšŸ’» Please rerun the following command on your workstation and push your changes" - echo "--------------------------------------------------------------------" - echo "roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace'))" - echo "--------------------------------------------------------------------" - echo "ā„¹ roxygen2 version that was used in this workflow: $ROXYGEN_VERSION" - echo "šŸ™ Please ensure that the 'RoxygenNote' field in the DESCRIPTION file matches this version" - exit 1 - } else { - echo "šŸ’š Manuals are up-to-date with roxygen comments" - } - fi - shell: bash - + if: github.event_name == 'pull_request' + with: + r-version: "${{ needs.get_r_version.outputs.r-version }}" + tests: name: Tests runs-on: ubuntu-latest @@ -205,209 +64,23 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Install system dependencies + run: | + apt-get install -y --no-install-recommends \ + libudunits2-dev + - name: Install dependencies run: | - Rscript -e 'pak::local_install_deps(dependencies = TRUE)' + Rscript -e 'remotes::install_deps(dependencies = TRUE)' - name: Run tests shell: Rscript {0} run: | devtools::load_all(".") devtools::test() - check: - runs-on: ubuntu-latest - needs: - - spellcheck - - tests - - lint - - man-pages - container: - image: "ghcr.io/pharmaverse/admiralci-${{ matrix.r_version }}:latest" - name: Check (${{ matrix.r_version }}) - strategy: - fail-fast: false - matrix: - r_version: ["release", "devel", "oldrel"] - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - R_KEEP_PKG_SOURCE: true - R_REMOTES_NO_ERRORS_FROM_WARNINGS: true - R_REPOS: "https://cran.r-project.org" - DEPS_IGNORE: >- - pharmaversesdtm, - pharmaverseadam, - admiral, - admiraldev, - admiralophtha, - admiralonco, - admiralvaccine, - staged.dependencies - steps: - - name: Get branch names - id: branch-name - uses: tj-actions/branch-names@v8 - - - name: Checkout repo - uses: actions/checkout@v4.2.2 - if: | - github.event_name == 'pull_request' - with: - ref: ${{ steps.branch-name.outputs.head_ref_branch }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - - - name: Restore cache - uses: actions/cache@v4 - with: - path: | - ~/.staged.dependencies - key: staged-deps - - - name: Run Staged dependencies - uses: insightsengineering/staged-dependencies-action@v1 - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - with: - git-ref: ${{ steps.branch-name.outputs.current_branch }} - run-system-dependencies: false - renv-restore: false - enable-check: false - cran-repos: "https://cloud.r-project.org" - direction: upstream - - - name: Install dependencies from DESCRIPTION - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - run: | - Rscript -e 'pak::local_install_deps(dependencies = TRUE)' - - - name: Upload dependencies artifact - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - run: | - dir.create("/workspace/tmp") - library(dplyr) - installed_packages <- as.data.frame(installed.packages()) - packages_to_remove <- Sys.getenv("DEPS_IGNORE", "") - packages_to_remove <- unlist(strsplit(packages_to_remove, ",")) - installed_packages <- installed_packages %>% filter(LibPath != "/usr/local/lib/R/library") %>% # remove pre-built deps - filter(!Package %in% packages_to_remove) - # save deps as csv file - write.csv(installed_packages, "/workspace/tmp/deps-${{ matrix.r_version }}.csv", row.names = FALSE) - # create also renv.lock file - setwd("/workspace/tmp") - - renv_lock <- list( - "R" = list( - "Version" = paste(R.version$major, R.version$minor, sep=".") - ), - "Repositories" = list( - list(Name = "CRAN", URL = Sys.getenv("R_REPOS")) - ), - "Packages" = list() - ) - - # Populate with information about each package - for (package in installed_packages$Package) { - dep_name <- package - dep_version <- installed_packages[installed_packages$Package == package, "Version"] - - version_parts <- strsplit(dep_version, "\\.")[[1]] - if (length(version_parts) == 4) { - print(sprintf("skipping installation of dep %s", dep_name)) - } else { - print(sprintf("append dependency %s - version %s", dep_name, dep_version)) - requirements <- tools::package_dependencies(dep_name, recursive = TRUE) - have_requirements <- length(requirements[[1]]) > 0 - if (have_requirements) { - renv_lock[["Packages"]][[dep_name]] <- list( - "Package" = dep_name, - "Version" = dep_version, - "Source" = "Repository", - "Repository" = "CRAN", - "Requirements" = requirements[[dep_name]] - ) - } else { - renv_lock[["Packages"]][[dep_name]] <- list( - "Package" = dep_name, - "Version" = dep_version, - "Source" = "Repository", - "Repository" = "CRAN" - ) - } - } - } - - # Write the list to a JSON file (renv.lock) - writeLines(jsonlite::toJSON(renv_lock, pretty = TRUE, auto_unbox = TRUE), "renv-${{ matrix.r_version }}.lock") - print("generated renv.lock content") - system("cat renv-${{ matrix.r_version }}.lock") - shell: Rscript {0} - - - name: Upload deps.csv and renv.lock artifacts - uses: actions/upload-artifact@v4 - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - with: - name: deps-${{ matrix.r_version }} - path: | - /workspace/tmp/ - - - name: Check Version - id: check_version - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - run: | - maintenance_version="F" - description_dat <- readLines("DESCRIPTION") - for (i in seq_along(description_dat)) { - if (grepl("^Version:", description_dat[i])) { - current_version <- sub("^Version: ", "", description_dat[i]) - version_parts <- strsplit(current_version, "\\.")[[1]] - # check if maintenance version - if (length(version_parts) == 4) { - print("Maintenance version detected (format X.Y.Z.M with M >= 9000)") - maintenance_version="T" - } - } - } - cat(sprintf("maintenance_version=%s", maintenance_version), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) - shell: Rscript {0} - - - name: Check - if: | - (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || - matrix.r_version != 'devel' - env: - _R_CHECK_CRAN_INCOMING_REMOTE_: false - _R_CHECK_FORCE_SUGGESTS_: false - run: | - unlink("tmp",recursive=TRUE) - if ("${{ steps.check_version.outputs.maintenance_version }}" == "T"){ - Sys.setenv("_R_CHECK_CRAN_INCOMING_SKIP_LARGE_VERSION_" = TRUE) - } - if (!requireNamespace("rcmdcheck", quietly = TRUE)) install.packages("rcmdcheck") - options(crayon.enabled = TRUE) - check_error_on <- "error" - if (check_error_on == "") { - check_error_on <- "note" - } - rcmdcheck::rcmdcheck( - args = c("--no-manual", "--as-cran"), - error_on = check_error_on, - check_dir = "check" - ) - shell: Rscript {0} - - - name: Upload check results - if: failure() - uses: actions/upload-artifact@v4 - with: - name: r${{ matrix.r_version }}-results - path: check - + name: Check + uses: ./.github/workflows/r-cmd-check.yml + if: github.event_name == 'pull_request' + with: + error-on: error diff --git a/.github/workflows/man-pages.yml b/.github/workflows/man-pages.yml new file mode 100644 index 00000000..e0abb633 --- /dev/null +++ b/.github/workflows/man-pages.yml @@ -0,0 +1,111 @@ +on: + workflow_dispatch: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: choice + options: + - devel + - latest + workflow_call: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: string + +name: Man Pages + +concurrency: + group: roxygen-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Roxygen + runs-on: ubuntu-latest + container: + image: "ghcr.io/pharmaverse/admiralci-${{ inputs.r-version }}:latest" + if: > + !contains(github.event.commits[0].message, '[skip lint]') + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + ##################### BEGIN boilerplate steps ##################### + - name: Get branch names + id: branch-name + uses: tj-actions/branch-names@v8 + + - name: Checkout repo (PR) šŸ›Ž + uses: actions/checkout@v4.2.2 + if: github.event_name == 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: Checkout repository + uses: actions/checkout@v4.2.2 + if: github.event_name != 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + ~/.staged.dependencies + key: staged-deps + + - name: Run Staged dependencies + uses: insightsengineering/staged-dependencies-action@v1 + with: + run-system-dependencies: true + renv-restore: false + enable-check: false + direction: upstream + git-ref: ${{ steps.branch-name.outputs.current_branch }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies from DESCRIPTION + run: | + remotes::install_local(force = TRUE, dependencies = TRUE) + shell: Rscript {0} + env: + R_REMOTES_STANDALONE: "true" + + ##################### END boilerplate steps ##################### + + - name: Generate man pages + run: roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace')) + shell: Rscript {0} + + - name: Set-up safe dir + run: git config --global --add safe.directory "${GITHUB_WORKSPACE}" + shell: bash + + - name: Roxygen check + if: '!startsWith(github.event.comment.body, "/roxygenize")' + run: | + git status -s + if [[ -n `git status -s | grep -E "man|DESCRIPTION"` ]] + then { + ROXYGEN_VERSION="$(Rscript -e 'packageVersion("roxygen2")' | awk '{print $NF}')" + echo "šŸ™ˆ Manuals are not up-to-date with roxygen comments!" + echo "šŸ”€ The following differences were noted:" + git diff man/* DESCRIPTION + echo -e "\nšŸ’» Please rerun the following command on your workstation and push your changes" + echo "--------------------------------------------------------------------" + echo "roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace'))" + echo "--------------------------------------------------------------------" + echo "ā„¹ roxygen2 version that was used in this workflow: $ROXYGEN_VERSION" + echo "šŸ™ Please ensure that the 'RoxygenNote' field in the DESCRIPTION file matches this version" + exit 1 + } else { + echo "šŸ’š Manuals are up-to-date with roxygen comments" + } + fi + shell: bash \ No newline at end of file diff --git a/.github/workflows/r-cmd-check.yml b/.github/workflows/r-cmd-check.yml new file mode 100644 index 00000000..7d91adab --- /dev/null +++ b/.github/workflows/r-cmd-check.yml @@ -0,0 +1,227 @@ +on: + workflow_dispatch: + workflow_call: + inputs: + error-on: + description: Input for the 'error_on' parameter in rcmdcheck::rcmdcheck() + required: false + default: note + type: string + +name: R CMD Check + +concurrency: + group: r-cmd-check-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + R-CMD-check: + runs-on: ubuntu-latest + container: + image: "ghcr.io/pharmaverse/admiralci-${{ matrix.r_version }}:latest" + name: (${{ matrix.r_version }}) + if: > + !contains(github.event.commits[0].message, '[skip r-cmd-check]') + strategy: + fail-fast: false + matrix: + r_version: ["release", "devel", "oldrel"] + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: true + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + R_REPOS: "https://cran.r-project.org" + DEPS_IGNORE: >- + pharmaversesdtm, + pharmaverseadam, + admiral, + admiraldev, + admiralophtha, + admiralonco, + admiralvaccine, + staged.dependencies + + # DEPS_IGNORE: env variable to ignore package when building renv.lock (step Upload dependencies artifact) + # (improvments ideas : get this list of deps to ignore from staged.dependencies yml file) + + steps: + ##################### BEGIN boilerplate steps ##################### + - name: Get branch names + id: branch-name + uses: tj-actions/branch-names@v8 + + - name: Checkout repo (PR) šŸ›Ž + uses: actions/checkout@v4.2.2 + if: | + github.event_name == 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: Checkout repository + uses: actions/checkout@v4.2.2 + if: | + github.event_name != 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + ~/.staged.dependencies + key: staged-deps + + - name: Run Staged dependencies + uses: insightsengineering/staged-dependencies-action@v1 + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + with: + git-ref: ${{ steps.branch-name.outputs.current_branch }} + run-system-dependencies: true + renv-restore: false + enable-check: false + cran-repos: "https://cloud.r-project.org" + direction: upstream + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies from DESCRIPTION + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + run: | + remotes::install_local(force = TRUE, dependencies = TRUE) + shell: Rscript {0} + + ##################### END boilerplate steps ##################### + + - name: Upload dependencies artifact + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + run: | + dir.create("/workspace/tmp") + library(dplyr) + installed_packages <- as.data.frame(installed.packages()) + packages_to_remove <- Sys.getenv("DEPS_IGNORE", "") + packages_to_remove <- unlist(strsplit(packages_to_remove, ",")) + installed_packages <- installed_packages %>% filter(LibPath != "/usr/local/lib/R/library") %>% # remove pre-built deps + filter(!Package %in% packages_to_remove) + # save deps as csv file + write.csv(installed_packages, "/workspace/tmp/deps-${{ matrix.r_version }}.csv", row.names = FALSE) + # create also renv.lock file + setwd("/workspace/tmp") + + renv_lock <- list( + "R" = list( + "Version" = paste(R.version$major, R.version$minor, sep=".") + ), + "Repositories" = list( + list(Name = "CRAN", URL = Sys.getenv("R_REPOS")) + ), + "Packages" = list() + ) + + # Populate with information about each package + for (package in installed_packages$Package) { + dep_name <- package + dep_version <- installed_packages[installed_packages$Package == package, "Version"] + + version_parts <- strsplit(dep_version, "\\.")[[1]] + if (length(version_parts) == 4) { + print(sprintf("skipping installation of dep %s", dep_name)) + } else { + print(sprintf("append dependency %s - version %s", dep_name, dep_version)) + requirements <- tools::package_dependencies(dep_name, recursive = TRUE) + have_requirements <- length(requirements[[1]]) > 0 + if (have_requirements) { + renv_lock[["Packages"]][[dep_name]] <- list( + "Package" = dep_name, + "Version" = dep_version, + "Source" = "Repository", + "Repository" = "CRAN", + "Requirements" = requirements[[dep_name]] + ) + } else { + renv_lock[["Packages"]][[dep_name]] <- list( + "Package" = dep_name, + "Version" = dep_version, + "Source" = "Repository", + "Repository" = "CRAN" + ) + } + } + } + + # Write the list to a JSON file (renv.lock) + writeLines(jsonlite::toJSON(renv_lock, pretty = TRUE, auto_unbox = TRUE), "renv-${{ matrix.r_version }}.lock") + print("generated renv.lock content") + system("cat renv-${{ matrix.r_version }}.lock") + shell: Rscript {0} + + - name: Upload deps.csv and renv.lock artifacts + uses: actions/upload-artifact@v4 + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + with: + name: deps-${{ matrix.r_version }} + path: | + /workspace/tmp/ + + - name: Check Version + id: check_version + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + run: | + maintenance_version="F" + description_dat <- readLines("DESCRIPTION") + for (i in seq_along(description_dat)) { + if (grepl("^Version:", description_dat[i])) { + current_version <- sub("^Version: ", "", description_dat[i]) + version_parts <- strsplit(current_version, "\\.")[[1]] + # check if maintenance version + if (length(version_parts) == 4) { + print("Maintenance version detected (format X.Y.Z.M with M >= 9000)") + maintenance_version="T" + } + } + } + cat(sprintf("maintenance_version=%s", maintenance_version), file = Sys.getenv("GITHUB_OUTPUT"), append = TRUE) + shell: Rscript {0} + + - name: Check + if: | + (github.event_name == 'workflow_dispatch' && matrix.r_version == 'devel') || + matrix.r_version != 'devel' + env: + _R_CHECK_CRAN_INCOMING_REMOTE_: false + _R_CHECK_FORCE_SUGGESTS_: false + run: | + unlink("tmp",recursive=TRUE) + if ("${{steps.check_version.outputs.maintenance_version}}" == "T"){ + Sys.setenv("_R_CHECK_CRAN_INCOMING_SKIP_LARGE_VERSION_" = TRUE) + } + if (!requireNamespace("rcmdcheck", quietly = TRUE)) install.packages("rcmdcheck") + options(crayon.enabled = TRUE) + check_error_on <- "${{ inputs.error-on }}" + if (check_error_on == "") { + check_error_on <- "note" + } + rcmdcheck::rcmdcheck( + args = c("--no-manual", "--as-cran"), + error_on = check_error_on, + check_dir = "check" + ) + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: r${{ matrix.r_version }}-results + path: check \ No newline at end of file diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml new file mode 100644 index 00000000..d3f0b200 --- /dev/null +++ b/.github/workflows/spellcheck.yml @@ -0,0 +1,88 @@ +name: Spelling + +on: + workflow_dispatch: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: choice + options: + - devel + - latest + exclude: + description: "List of paths to exclude (comma seperated list)" + default: "" + required: false + type: string + workflow_call: + inputs: + r-version: + description: "The version of R to use" + default: "release" + required: false + type: string + exclude: + description: "List of paths to exclude (comma seperated list)" + default: "" + required: false + type: string + +concurrency: + group: spelling-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + spellcheck: + name: Spellcheck + runs-on: ubuntu-latest + container: + image: "ghcr.io/pharmaverse/admiralci-${{ inputs.r-version }}:latest" + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + if: > + !contains(github.event.commits[0].message, '[skip spellcheck]') + steps: + ##################### BEGIN boilerplate steps ##################### + - name: Get branch names + id: branch-name + uses: tj-actions/branch-names@v8 + + - name: Checkout repo (PR) šŸ›Ž + uses: actions/checkout@v4.2.2 + if: github.event_name == 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: Checkout repository + uses: actions/checkout@v4.2.2 + if: github.event_name != 'pull_request' + with: + ref: ${{ steps.branch-name.outputs.head_ref_branch }} + + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + ~/.staged.dependencies + key: staged-deps + + - name: Run Staged dependencies + uses: insightsengineering/staged-dependencies-action@v1 + with: + run-system-dependencies: true + renv-restore: false + enable-check: false + direction: upstream + git-ref: ${{ steps.branch-name.outputs.current_branch }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + ##################### END boilerplate steps ##################### + + - name: Run Spellcheck + uses: insightsengineering/r-spellcheck-action@v3 + with: + additional_options: "" + exclude: "${{ inputs.exclude }}" \ No newline at end of file