From 25e71ba5f4d485ffa4eb56ec074194529f297265 Mon Sep 17 00:00:00 2001 From: Craig Gower-Page Date: Thu, 26 Sep 2024 16:23:29 +0100 Subject: [PATCH] Fix broken docker build (#427) Closes #410 --- .github/workflows/build_docker.yaml | 25 ++----- .github/workflows/build_docker_latest.yaml | 85 ---------------------- .github/workflows/check_for_cran.yaml | 55 -------------- .github/workflows/on_biweekly.yaml | 2 - .github/workflows/on_pr_main.yaml | 5 -- CONTRIBUTING.md | 16 ++-- misc/docker/Dockerfile | 10 +-- misc/docker/install_packages.R | 82 +++++++++++++-------- 8 files changed, 66 insertions(+), 214 deletions(-) delete mode 100644 .github/workflows/build_docker_latest.yaml delete mode 100644 .github/workflows/check_for_cran.yaml diff --git a/.github/workflows/build_docker.yaml b/.github/workflows/build_docker.yaml index 2f160565b..e949137aa 100644 --- a/.github/workflows/build_docker.yaml +++ b/.github/workflows/build_docker.yaml @@ -1,9 +1,11 @@ -name: Build fixed version Docker images +name: Build latest version Docker images env: REGISTRY: ghcr.io on: + schedule: + - cron: '0 5 1 * *' workflow_dispatch: @@ -18,16 +20,7 @@ jobs: matrix: config: - { - src_image: "rocker/r-ver:4.0.4", - cran_url: "https://packagemanager.rstudio.com/cran/2021-04-20", - tag: "rbmi:r404", - mmrm_version : "v0.1.5" - } - - { - src_image: "rocker/r-ver:4.1.0", - cran_url: "https://packagemanager.rstudio.com/cran/2021-08-04", - tag: "rbmi:r410", - mmrm_version : "v0.1.5" + tag: "rbmi:latest" } # Token permissions @@ -37,8 +30,8 @@ jobs: # Build steps steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Check out the repo + uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 @@ -64,9 +57,6 @@ jobs: run: | echo push = ${{ github.event_name == 'push' }} echo tag = ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.config.tag }} - echo IMAGE=${{ matrix.config.src_image }} - echo CRANURL=${{ matrix.config.cran_url }} - echo MMRM_VERSION=${{ matrix.config.mmrm_version }} - name: Build and push image uses: docker/build-push-action@v3 @@ -75,9 +65,6 @@ jobs: push: true tags: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.config.tag }} build-args: | - IMAGE=${{ matrix.config.src_image }} - CRANURL=${{ matrix.config.cran_url }} - MMRM_VERSION=${{ matrix.config.mmrm_version }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new diff --git a/.github/workflows/build_docker_latest.yaml b/.github/workflows/build_docker_latest.yaml deleted file mode 100644 index 0e1ff1df9..000000000 --- a/.github/workflows/build_docker_latest.yaml +++ /dev/null @@ -1,85 +0,0 @@ -name: Build latest version Docker images - -env: - REGISTRY: ghcr.io - -on: - schedule: - - cron: '0 5 1 * *' - workflow_dispatch: - - -jobs: - build: - runs-on: ubuntu-latest - name: Build & Deploy Docker Images - - - strategy: - fail-fast: true - matrix: - config: - - { - src_image: "rocker/r-ver:latest", - cran_url: "https://packagemanager.rstudio.com/cran/latest", - tag: "rbmi:latest", - mmrm_version : "v0.1.5" - } - - # Token permissions - permissions: - contents: read - packages: write - - # Build steps - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - id: buildx - with: - install: true - - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Cache Docker layers - uses: actions/cache@v3 - with: - path: /tmp/.buildx-cache - key: docker-cache-${{ matrix.config.tag }} - - - - name: debug - run: | - echo push = ${{ github.event_name == 'push' }} - echo tag = ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.config.tag }} - echo IMAGE=${{ matrix.config.src_image }} - echo CRANURL=${{ matrix.config.cran_url }} - - - name: Build and push image - uses: docker/build-push-action@v3 - with: - context: ./misc/docker - push: true - tags: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.config.tag }} - build-args: | - IMAGE=${{ matrix.config.src_image }} - CRANURL=${{ matrix.config.cran_url }} - MMRM_VERSION=${{ matrix.config.mmrm_version }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - - # Fix bug where docker cache just continiously grows as it doesn't purge older layers - # That are no longer in use - # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#local-cache - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/workflows/check_for_cran.yaml b/.github/workflows/check_for_cran.yaml deleted file mode 100644 index e88825fb4..000000000 --- a/.github/workflows/check_for_cran.yaml +++ /dev/null @@ -1,55 +0,0 @@ - - -on: - workflow_dispatch: - -name: Check for CRAN - -jobs: - - rcmdcheck: - - strategy: - fail-fast: true - matrix: - config: - - { R: "devel", os: "ubuntu-latest"} - - { R: "release", os: "macos-latest"} - - { R: "release", os: "ubuntu-latest"} - - runs-on: ${{ matrix.config.os }} - - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - R_TEST_FULL: 'FALSE' - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install R - uses: r-lib/actions/setup-r@v2 - id: install-r - with: - r-version: ${{ matrix.config.R }} - - - name: Prevent Windows from installing non-binary packages - if: ${{ matrix.config.os == 'windows-latest' }} - shell: bash - run: | - echo 'options(install.packages.check.source = "no")' >> .Rprofile - - - name: Install R package dependencies - shell: Rscript {0} - run: | - options("repos" = list("CRAN" = "https://www.stats.bris.ac.uk/R/")) - install.packages("remotes") - remotes::install_deps(dependencies = TRUE) - - - name: Install Pandoc - uses: r-lib/actions/setup-pandoc@v2 - - - name: Check - uses: ./.github/actions/rcmdcheck - with: - slim: false diff --git a/.github/workflows/on_biweekly.yaml b/.github/workflows/on_biweekly.yaml index 89a6dc0ce..793163a29 100644 --- a/.github/workflows/on_biweekly.yaml +++ b/.github/workflows/on_biweekly.yaml @@ -13,8 +13,6 @@ jobs: fail-fast: true matrix: config: - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r404"} - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r410"} - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:latest"} runs-on: ubuntu-latest diff --git a/.github/workflows/on_pr_main.yaml b/.github/workflows/on_pr_main.yaml index b4390ec7a..b15186ee3 100644 --- a/.github/workflows/on_pr_main.yaml +++ b/.github/workflows/on_pr_main.yaml @@ -12,13 +12,10 @@ name: On Pull Request jobs: rcmdcheck: - strategy: fail-fast: true matrix: config: - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r404"} - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r410"} - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:latest"} runs-on: ubuntu-latest container: @@ -44,8 +41,6 @@ jobs: fail-fast: true matrix: config: - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r404"} - # - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:r410"} - { image: "ghcr.io/${{ github.repository_owner }}/rbmi:latest"} runs-on: ubuntu-latest container: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb25602c7..587dedbd4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,24 +60,20 @@ test_that("some unit test", { The scheduled tests can also be manually activated by going to "https://github.com/insightsengineering/rbmi" -> "Actions" -> "Bi-Weekly" -> "Run Workflow". It is advisable to do this before releasing to CRAN. -### CRAN Releases - -In order to release a package to CRAN it needs to be tested across multiple different OS's and versions of R. This has been implemented in this project via a GitHub Action Workflow titled "Check for CRAN" which needs to be manually activated. To do this go to "https://github.com/insightsengineering/rbmi" -> "Actions" -> "Check for CRAN" -> "Run Workflow". - -If all these tests pass then the package can be safely released to CRAN (after updating the relevant `cran-comments.md` file) ### Docker Images -To support CI/CD in terms of reducing installation time, several Docker images have been pre-built which contain all the packages and system dependencies that this project needs. The current relevant images can be found at: +To support CI/CD, in terms of reducing setup time, a Docker images has been created which contains all the packages and system dependencies required for this project. The image can be found at: -- ghcr.io/insightsengineering/rbmi:r404 -- ghcr.io/insightsengineering/rbmi:r410 - ghcr.io/insightsengineering/rbmi:latest -The `latest` image is automatically re-built once a month to contain the latest version of R and its packages. The other versions are built with older versions of R (as indicated by the tag number) and contain package versions as they were when that version of R was released. This is important to ensure that the package works with older versions of R which many companies typically run due to delays in their validation processes. +This image is automatically re-built once a month to contain the latest version of R and its packages. The code to create this images can be found in `misc/docker`. -The code to create these images can be found in `misc/docker`. The legacy images (i.e. everything excluding the "latest" image) are only built on manual request by running the corresponding GitHub Actions Workflow. +To build the image locally run the following from the project root directory: +``` +docker build -f misc/docker/Dockerfile -t rbmi:latest . +``` ### Reproducibility, Print Tests & Snaps diff --git a/misc/docker/Dockerfile b/misc/docker/Dockerfile index 33acc5c4c..03b62f943 100644 --- a/misc/docker/Dockerfile +++ b/misc/docker/Dockerfile @@ -1,9 +1,5 @@ -ARG IMAGE -FROM ${IMAGE} - -ARG CRANURL -ARG MMRM_VERSION +FROM rocker/r-ver:latest ENV REQD_PKGS="\ libicu-dev \ @@ -39,13 +35,15 @@ ENV REQD_PKGS="\ qpdf \ devscripts \ cmake \ + libpq-dev \ " RUN apt-get update -y --fix-missing && \ apt-get upgrade -y && \ apt-get install -y $REQD_PKGS -ADD install_packages.R / +ADD misc/docker/install_packages.R / +ADD DESCRIPTION / RUN Rscript /install_packages.R diff --git a/misc/docker/install_packages.R b/misc/docker/install_packages.R index 006164187..92006e640 100644 --- a/misc/docker/install_packages.R +++ b/misc/docker/install_packages.R @@ -1,41 +1,59 @@ +# Determine which OS we are on +# Rocker images are Ubuntu based so should be jammy / focal / etc +OS_CODENAME <- system( + 'cat /etc/os-release | grep "VERSION_CODENAME" | sed -e "s/VERSION_CODENAME=//"', + intern = TRUE +) + +# Configure PPM URL for binary package installation +CRANURL <- sprintf( + "https://packagemanager.posit.co/cran/__linux__/%s/latest", + OS_CODENAME +) +# Configure useragent to enable binary package installation from PPM +options( + "repos" = list("CRAN" = CRANURL), + "HTTPUserAgent" = sprintf( + "R/%s R (%s)", + getRversion(), + paste(getRversion(), R.version["platform"], R.version["arch"], R.version["os"]) + ) +) + +# Throw errors if any warnings arise options(warn = 2) -install.packages("remotes", repos = Sys.getenv("CRANURL")) - -# mmrm wasn't available when in-house servers locked their package versions -# and instead had v0.13 of mmrm patched in after the fact -# here we allow the build to specify "latest" to grab the latest version of mmrm -# or a specific named version from github -mmrm_version <- Sys.getenv("MMRM_VERSION") -if (mmrm_version == "latest") { - install.packages("mmrm", repos = Sys.getenv("CRANURL"), dependencies = TRUE) -} else { - remotes::install_git("https://github.com/openpharma/mmrm.git", ref = mmrm_version, upgrade = FALSE) +if (!requireNamespace("desc", quietly = TRUE)) { + install.packages("desc") } -pkgs <- c( - "tidyverse", - "glmmTMB", - "mvtnorm", - "devtools", - "rstan", - "rstantools", - "RcppParallel", - "Rcpp", - "R6", - "assertthat", - "emmeans", - "covr", - "testthat", - "nlme", - "roxygen2", - "tinytex", - "bookdown", - "RhpcBLASctl", - "R.rsp" + +# Get a list of all packages that we claim we depend on in the DESCRIPTION file +pkgs <- desc::desc("DESCRIPTION")$get_deps()$package |> unique() + +# Add on additional packages that might be needed in the future +pkgs <- c(pkgs, "tidyverse", "devtools") + + +# R will error if you try to update the base packages so remove them +# if they are in any of the imports / suggests / depends list +base_pkgs <- c( + "KernSmooth", "class", "foreign", "methods", "rpart", "survival", + "MASS", "cluster", "grDevices", "mgcv", "spatial", "tcltk", + "Matrix", "codetools", "graphics", "nlme", "splines", "tools", + "base", "compiler", "grid", "nnet", "stats", "translations", + "boot", "datasets", "lattice", "parallel", "stats4", "utils", + "R" ) +pkgs <- pkgs[!pkgs %in% base_pkgs] -install.packages(pkgs, repos = Sys.getenv("CRANURL"), dependencies = TRUE) +install.packages(pkgs, dependencies = TRUE) + +# Install cmdstanr (not available from CRAN) +install.packages( + "cmdstanr", + repos = c("https://stan-dev.r-universe.dev", getOption("repos")) +)