Skip to content

Chore: customize github workflows to correctly install system dependencies #172

Chore: customize github workflows to correctly install system dependencies

Chore: customize github workflows to correctly install system dependencies #172

Workflow file for this run

# Source: https://github.com/pharmaverse/admiralci
# Stripped down version of admiralci checks. Good for
# the developement process. When package is ready to
# be published, revisit and add release-related
# workflows.
# 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
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: admiral-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
R_VERSION: "release"
jobs:
get_r_version:
name: Get R version
runs-on: ubuntu-latest
outputs:
r-version: ${{ steps.get_r_version.outputs.R_VERSION }}
steps:
- name: Get R Version for Downstream Container Jobs
id: get_r_version
run: echo "R_VERSION=$R_VERSION" >> $GITHUB_OUTPUT
shell: bash
spellcheck:
name: Spelling
runs-on: ubuntu-latest
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/[email protected]
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:
name: Lint
runs-on: ubuntu-latest
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/[email protected]
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)
}
man-pages:
name: Man Pages
runs-on: ubuntu-latest
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/[email protected]
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
tests:
name: Tests
runs-on: ubuntu-latest
needs: get_r_version
container:
image: "ghcr.io/pharmaverse/admiralci-${{ needs.get_r_version.outputs.r-version }}:latest"
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install dependencies
run: |
Rscript -e 'pak::local_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/[email protected]
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