diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c5d6c1..e6942ec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -177,7 +177,7 @@ jobs: Detailed release notes are available on the [main SimpleITK repository](https://github.com/SimpleITK/SimpleITK/releases/${{ github.ref_name }}). - To install SimpleITK we use a Foyer helper package that downloads the appropriate binary from the GitHub release assets. This is a two step process. + To install SimpleITK we use a Foyer helper package that downloads the appropriate binary. This is a two step process. To install the latest SimpleITK version to your primary library directory, first element of `.libPaths()`, run the following: @@ -185,7 +185,7 @@ jobs: # install the SimpleITK foyer package install.packages( "SimpleITK.foyer", - repos = c("https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/"), + repos = c("https://simpleitk.r-universe.dev"), type = "source" ) @@ -207,6 +207,7 @@ jobs: If you directly download the package artifact from this release page, before you install the package you will need to first unzip the file. Then rename it to `SimpleITK_.zip` (windows), `SimpleITK_.tgz` (macOS), or `SimpleITK_.tar.gz` (Linux) to match the expected file name format. + If you need a custom build of SimpleITK or the binary package for your platform, R version, or desired SimpleITK version is not available you will need to build the package yourself. To do this, use the [remotes based installer](https://github.com/SimpleITK/SimpleITKRInstaller). files: | release-artifacts/* fail_on_unmatched_files: true diff --git a/.github/workflows/update_gh_cran.yml b/.github/workflows/update_gh_cran.yml deleted file mode 100644 index 602bc85..0000000 --- a/.github/workflows/update_gh_cran.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Update CRAN Repository - -on: - release: - types: [published] - -permissions: - contents: write - -concurrency: - group: update-cran-repository - cancel-in-progress: false - -jobs: - update-repo: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - ref: main - - - name: Set up R - uses: r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2.12.0 - - - name: Build Foyer Package - run: | - Rscript update_cran_repo.R \ - --foyer_dir SimpleITK_Foyer \ - --output_dir /tmp/cran_output \ - --repo_url https://github.com/${{ github.repository }} - - - name: Deploy to gh-pages - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git checkout gh-pages - rm -rf src - cp -r /tmp/cran_output/src . - git add src - if ! git diff --cached --quiet; then - git commit -m "Update CRAN-like repository for release ${{ github.event.release.tag_name }}" - git push - fi diff --git a/release_instructions.md b/release_instructions.md new file mode 100644 index 0000000..702d14e --- /dev/null +++ b/release_instructions.md @@ -0,0 +1,29 @@ +# Release Instructions + +This document describes the steps required to create the binary R release for SimpleITK which updates and relies on the remotes based SimpleITKRInstaller. + +1. Create branch off of `main` and switch to it, `git checkout -b updateRelease main`. + +1. Update the installer `DESCRIPTION` file: change the `SITK_TARGET` field to the desired SimpleITK version (e.g. v2.5.5) and run the version update script (in bash or Git Bash on windows), `sitk_r_version_date.sh`. This script will update the file's `Version` and `Date` fields according to the `SITK_TARGET`. + +1. Commit and push changes: + + ``` + git commit -am "Update SimpleITK release" + git push origin updateRelease + ``` + +1. On GitHub create a PR, see that all tests pass and binary artifacts are created successfuly. Merge into main. + +1. Update local `main` from the remote and check out the `main` branch. Tag it using the **exact tag** you listed in the `SITK_TARGET` and push the tag to this repository. + + ``` + git tag v2.5.5 + git push https://github.com/SimpleITK/SimpleITKRInstaller.git v2.5.5 + ``` + +1. Monitor the build process, https://github.com/SimpleITK/SimpleITKRInstaller/actions. If a build fails due to transient issues, rerun from failed (binary artifacts created for successful builds are retained across reruns). + +1. Once all builds complete successfully a [draft release](https://github.com/SimpleITK/SimpleITKRInstaller/releases) is automatically created. Verify that the expected binary packages are available as release artifacts and test them (download, unzip, rename and install). + +1. Edit and publish the release. Check that the binary distribution is working as expected via the r-universe distribution of the foyer package (follow the usage instructions provided in the GitHub release notes). diff --git a/update_cran_repo.R b/update_cran_repo.R deleted file mode 100644 index ec11a64..0000000 --- a/update_cran_repo.R +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env Rscript - -# Script to build the SimpleITK foyer package and deploy it to a CRAN-like -# repository structure on gh-pages. The foyer is a lightweight source package -# that, once installed, downloads the actual SimpleITK binary from GitHub -# releases for the user's platform. -# -# The gh-pages CRAN-like structure (source packages only): -# -# src/ -# └── contrib/ -# ├── PACKAGES -# ├── PACKAGES.gz -# ├── PACKAGES.rds -# └── SimpleITK.foyer_.tar.gz (updated with each release) -# -# The foyer package is version-aware and updated with each release. -# Users install it once from a fixed URL, then use install_simpleitk(version=...) -# to download any specific binary version from GitHub Releases. -# -# Usage: -# Rscript update_cran_repo.R --foyer_dir --output_dir --repo_url -# -# Arguments: -# --foyer_dir Directory containing the foyer package template -# --output_dir Output directory for the CRAN-like structure (e.g., /tmp/cran_output) -# --repo_url URL of the GitHub repository hosting binary releases -# (e.g., https://github.com/SimpleITK/SimpleITKRInstaller) -# -# Example: -# Rscript update_cran_repo.R \ -# --foyer_dir SimpleITK_Foyer \ -# --output_dir /tmp/cran_output \ -# --repo_url https://github.com/SimpleITK/SimpleITKRInstaller - -library(tools) - -# Parse command-line arguments in --key value format -parse_args <- function(args, required_args = NULL) { - parsed <- list() - i <- 1 - while (i <= length(args)) { - if (startsWith(args[i], "--")) { - key <- sub("^--", "", args[i]) - if (i < length(args) && !startsWith(args[i + 1], "--")) { - parsed[[key]] <- args[i + 1] - i <- i + 2 - } else { - stop(sprintf("Missing or invalid value for argument: --%s", key)) - } - } else { - stop(sprintf("Unexpected argument format: %s (expected a key starting with --)", args[i])) - } - } - if (!is.null(required_args)) { - missing_args <- setdiff(required_args, names(parsed)) - if (length(missing_args) > 0) { - stop("Missing required arguments: ", paste(missing_args, collapse = ", ")) - } - } - return(parsed) -} - -# Parse command line arguments -args <- commandArgs(trailingOnly = TRUE) -parsed_args <- parse_args(args, required_args = c("foyer_dir", "output_dir", "repo_url")) - -foyer_dir <- parsed_args[["foyer_dir"]] -output_dir <- parsed_args[["output_dir"]] -repo_url <- parsed_args[["repo_url"]] - -# Read version from the DESCRIPTION file of the foyer package -description_file <- file.path(foyer_dir, "DESCRIPTION") -version <- read.dcf(description_file, fields = "Version")[1, 1] - -# Validate foyer directory exists -if (!dir.exists(foyer_dir)) { - stop("Foyer directory does not exist: ", foyer_dir) -} - -# Copy foyer template to a temp directory to avoid modifying the original -build_dir <- tempdir() -foyer_copy <- file.path(build_dir, "SimpleITK") -if (dir.exists(foyer_copy)) unlink(foyer_copy, recursive = TRUE) -dir.create(foyer_copy, recursive = TRUE) -file.copy(list.files(foyer_dir, full.names = TRUE), foyer_copy, recursive = TRUE) - -# Update repository URL in R/install.R -install_r_path <- file.path(foyer_copy, "R", "install.R") -install_lines <- readLines(install_r_path) - -# Update the URL variable -install_lines <- sub( - '^(\\.sitk_repo_url <- ").*(")', - paste0("\\1", repo_url, "\\2"), - install_lines -) - -writeLines(install_lines, install_r_path) - -# Build the source package -message("Building foyer package...") -# Set tar options to avoid uid/gid warnings when R CMD build creates the tarball. -# --no-same-owner prevents tar from trying to preserve file ownership information, -# which can cause warnings if the original uid/gid values don't exist in the build -# environment. The package installs correctly regardless of these attributes. -Sys.setenv(R_BUILD_TAR = "tar --no-same-owner") -build_output <- system2("R", args = c("CMD", "build", "--no-manual", foyer_copy), - stdout = TRUE, stderr = TRUE) -cat(build_output, sep = "\n") - -tarball <- sprintf("SimpleITK.foyer_%s.tar.gz", version) -if (!file.exists(tarball)) { - stop("R CMD build failed. Expected tarball not found: ", tarball) -} - -# Create CRAN-like directory structure -dest_dir <- file.path(output_dir, "src", "contrib") -dir.create(dest_dir, recursive = TRUE, showWarnings = FALSE) -file.rename(tarball, file.path(dest_dir, tarball)) - -# Generate PACKAGES files -write_PACKAGES(dest_dir, type = "source") - -message("CRAN-like repository created at: ", output_dir) -message(" ", file.path(dest_dir, tarball)) -message(" ", file.path(dest_dir, tarball)) - -