diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e30501d..086dbff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,6 +2,7 @@ on: push: branches: - main + - 'release-*' tags: - 'v*' # Trigger on version tags paths-ignore: @@ -9,6 +10,7 @@ on: pull_request: branches: - main + - 'release-*' paths-ignore: - 'SimpleITK_Foyer/**' workflow_dispatch: @@ -30,7 +32,7 @@ jobs: # Build against oldest patch versions x.y.0 as R is forward # compatible. R: [ '4.4.0', '4.5.0', '4.6.0' ] - os: [ 'macos-15-intel', 'windows-latest'] + os: [ 'macos-15-intel', 'windows-latest' ] runs-on: ${{ matrix.os }} name: ${{ matrix.R }} ${{ matrix.os }} build @@ -155,7 +157,7 @@ jobs: run: | dnf install -y epel-release dnf install -y --allowerasing \ - cmake git gcc gcc-c++ make patch \ + cmake git gcc-toolset-13-gcc gcc-toolset-13-gcc-c++ make patch \ libcurl-devel openssl-devel libxml2-devel \ harfbuzz-devel fribidi-devel libssh2-devel \ curl tar @@ -188,6 +190,7 @@ jobs: env: ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS: 2 run: | + source scl_source enable gcc-toolset-13 R -e "Sys.setenv(MAKEJ=2); Sys.setenv(ADDITIONAL_SITK_MODULES='-DSimpleITK_USE_ELASTIX=ON'); remotes::install_local('.', lib=Sys.getenv('R_LIBS_USER'), upgrade='never', INSTALL_opts='--build')" R -e "library(SimpleITK); Version()" @@ -241,13 +244,19 @@ jobs: if [ "${TAG_NAME}" != "${SITK_TARGET}" ]; then echo "Tag ${TAG_NAME} does not match SITK_TARGET ${SITK_TARGET}" echo "Skipping draft release creation." - echo "draft_release=false" >> $GITHUB_OUTPUT + echo "create_draft_release=false" >> $GITHUB_OUTPUT else - echo "draft_release=true" >> $GITHUB_OUTPUT + echo "create_draft_release=true" >> $GITHUB_OUTPUT + fi + # if tag is not vMAJOR.MINOR.PATCH.SUB_PATCH (all numeric) then this is a pre-release + if [[ "${TAG_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then + echo "is_prerelease=false" >> $GITHUB_OUTPUT + else + echo "is_prerelease=true" >> $GITHUB_OUTPUT fi - name: Download all artifacts - if: steps.verify_tag.outputs.draft_release == 'true' + if: steps.verify_tag.outputs.create_draft_release == 'true' uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: release-artifacts @@ -255,25 +264,31 @@ jobs: merge-multiple: true - name: Display downloaded artifacts - if: steps.verify_tag.outputs.draft_release == 'true' + if: steps.verify_tag.outputs.create_draft_release == 'true' run: | echo "Downloaded artifacts:" ls -lhR release-artifacts/ - name: Generate release body message with current version - if: steps.verify_tag.outputs.draft_release == 'true' + if: steps.verify_tag.outputs.create_draft_release == 'true' run: | - sed 's/{{VERSION}}/${{ github.ref_name }}/g' .github/workflows/release_message_template.md > /tmp/release_body.md + if [[ "${{ steps.verify_tag.outputs.is_prerelease }}" == "true" ]]; then + TEMPLATE=".github/workflows/pre_release_message_template.md" + else + TEMPLATE=".github/workflows/release_message_template.md" + fi + sed 's/{{VERSION}}/${{ github.ref_name }}/g' "${TEMPLATE}" > /tmp/release_body.md # This action automatically creates the release if it doesn't exist, # or updates it if it does. - name: Create or Update Draft Release - if: steps.verify_tag.outputs.draft_release == 'true' + if: steps.verify_tag.outputs.create_draft_release == 'true' uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: draft: true + prerelease: ${{ steps.verify_tag.outputs.is_prerelease == 'true' }} name: SimpleITK ${{ github.ref_name }} R Package Release body_path: /tmp/release_body.md files: | diff --git a/.github/workflows/pre_release_message_template.md b/.github/workflows/pre_release_message_template.md new file mode 100644 index 0000000..fd67df7 --- /dev/null +++ b/.github/workflows/pre_release_message_template.md @@ -0,0 +1,14 @@ +**Please manually upload the artifacts from [CircleCI](https://dl.circleci.com/status-badge/redirect/gh/SimpleITK/SimpleITKRInstaller/tree/main), review and test the packages before publishing this release. Then remove this line and make it public.** + +Detailed release notes are available on the [main SimpleITK repository](https://github.com/SimpleITK/SimpleITK/releases/{{VERSION}}). + + +Install the package directly from this page, using the URL to the asset which matches your OS and R version: + +```r +install.packages("https://github.com/SimpleITK/SimpleITKRInstaller/releases/download/{{VERSION}}/PACKAGE_FILE", repos = NULL, type = "source") +``` + +**Linux GLIBC compatibility note:** The Linux binary package targets GLIBC 2.28, making it compatible with Linux distributions that include GLIBC 2.28 or newer. The oldest supported version per distribution is: Ubuntu 20.04 (Focal Fossa), Debian 10 (Buster), CentOS/RHEL 8, Rocky Linux 8, AlmaLinux 8, Fedora 29, openSUSE Leap 15.3. + +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). diff --git a/.github/workflows/release_message_template.md b/.github/workflows/release_message_template.md index 89c7aaf..55ba4b6 100644 --- a/.github/workflows/release_message_template.md +++ b/.github/workflows/release_message_template.md @@ -30,7 +30,11 @@ The `install_simpleitk` function provides finer installation control such as Sim help(install_simpleitk) ``` -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. +To install the package directly from this page, using the URL to the asset which matches your OS and R version: + +```r +install.packages("https://github.com/SimpleITK/SimpleITKRInstaller/releases/download/{{VERSION}}/PACKAGE_FILE", repos = NULL, type = "source") +``` **Linux GLIBC compatibility note:** The Linux binary package targets GLIBC 2.28, making it compatible with Linux distributions that include GLIBC 2.28 or newer. The oldest supported version per distribution is: Ubuntu 20.04 (Focal Fossa), Debian 10 (Buster), CentOS/RHEL 8, Rocky Linux 8, AlmaLinux 8, Fedora 29, openSUSE Leap 15.3. diff --git a/release_instructions.md b/release_instructions.md index 702d14e..a9f1e7a 100644 --- a/release_instructions.md +++ b/release_instructions.md @@ -1,29 +1,124 @@ # 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. +This document describes the steps to create a binary R release for SimpleITK. -1. Create branch off of `main` and switch to it, `git checkout -b updateRelease main`. +## Branch and versioning strategy -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`. +- `main` always tracks the highest stable SimpleITK release by semantic version. +- All locally created branches are pushed directly to the authoritative repository. +- Short-lived branches, cut from `main`, are used for all new work. +- Long-lived `release-major.minor` branches created only for old maintenance series (e.g. `release-2.5` after `main` has moved to 3.0) to provide a safe PR target. They are never merged back into `main`. + +--- + +## Releasing on a short-lived branch + +Use this process for all releases where `main` is at the same or lower version than the target (e.g. v3.0.0b1, v3.0.0, or v3.0.1 while 3.0 is the leading series). + +1. Create a short-lived branch from `main` and switch to it: + + ``` + git checkout main + git pull https://github.com/SimpleITK/SimpleITKRInstaller.git main + git checkout -b release-v3.0.0b1 + ``` + +1. Update the `DESCRIPTION` file: change `SITK_TARGET` to the desired version (e.g. `v3.0.0b1`) and run the `sitk_r_version_date.sh` script. + +1. Commit and push: + + ``` + git commit -am "Update SimpleITK to v3.0.0b1" + git push https://github.com/SimpleITK/SimpleITKRInstaller.git release-v3.0.0b1 + ``` + +1. On GitHub open a PR targeting `main`. Verify all builds pass and artifacts are created. + +1. Stable release (new highest version) — on GitHub merge the PR (we'll delete the branch later), then tag the HEAD of `main`: + + ``` + git checkout main + git pull https://github.com/SimpleITK/SimpleITKRInstaller.git main + git tag -a v3.0.0 -m "Release v3.0.0" + git push https://github.com/SimpleITK/SimpleITKRInstaller.git v3.0.0 + ``` + + Prerelease — on GitHub close the PR without merging, then tag its HEAD: + + ``` + git checkout release-v3.0.0b1 + git pull https://github.com/SimpleITK/SimpleITKRInstaller.git release-v3.0.0b1 + git tag -a v3.0.0b1 -m "Release v3.0.0b1" + git push https://github.com/SimpleITK/SimpleITKRInstaller.git v3.0.0b1 + ``` + + This branch on the authoritative repository will be deleted in the last step; the tag keeps the commit permanently reachable. + +1. Monitor the tag-triggered build at https://github.com/SimpleITK/SimpleITKRInstaller/actions. If a build fails due to transient issues, rerun from failed (artifacts from successful builds are retained). + +1. Once all builds complete a [draft release](https://github.com/SimpleITK/SimpleITKRInstaller/releases) is created automatically. Verify the expected binary packages are present, test them (download, unzip, rename, install), then publish the release. + +1. Delete the short-lived branch: -1. Commit and push changes: - ``` - git commit -am "Update SimpleITK release" - git push origin updateRelease + git push https://github.com/SimpleITK/SimpleITKRInstaller.git --delete release-v3.0.0b1 + git branch -d release-v3.0.0b1 ``` -1. On GitHub create a PR, see that all tests pass and binary artifacts are created successfuly. Merge into main. +--- + +## Releasing a patch on an old maintenance series (e.g. v2.5.7 after main is at v3.0.0) + +Old maintenance series have a long-lived `release-major.minor` branch as a safe PR target so that old-series patches cannot accidentally be merged into `main`. + +### Creating a maintenance branch (one time per series) + +If the `release-2.5` branch does not yet exist, cut it from the last stable tag of that series (e.g. `v2.5.6`): -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 fetch --tags https://github.com/SimpleITK/SimpleITKRInstaller.git +git checkout v2.5.6 +git checkout -b release-2.5 +git push https://github.com/SimpleITK/SimpleITKRInstaller.git release-2.5 +``` - ``` - git tag v2.5.5 - git push https://github.com/SimpleITK/SimpleITKRInstaller.git v2.5.5 - ``` +### Releasing a patch -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. Create a short-lived branch off the maintenance branch: -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). + ``` + git checkout release-2.5 + git pull https://github.com/SimpleITK/SimpleITKRInstaller.git release-2.5 + git checkout -b release-v2.5.7 + ``` + + > **Note**: this branch carries the CI from `release-2.5`, not current `main`. If CI fixes are needed, apply them to `release-2.5` first. -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). +1. Update the `DESCRIPTION` file: change `SITK_TARGET` to `v2.5.7` and run the `sitk_r_version_date.sh` script. + +1. Commit and push: + + ``` + git commit -am "Update SimpleITK to v2.5.7" + git push https://github.com/SimpleITK/SimpleITKRInstaller.git release-v2.5.7 + ``` + +1. On GitHub open a PR **targeting `release-2.5`** (not `main`). Verify all builds pass and artifacts are created. Merge into `release-2.5`. + +1. Pull the updated maintenance branch and tag its HEAD: + + ``` + git checkout release-2.5 + git pull https://github.com/SimpleITK/SimpleITKRInstaller.git release-2.5 + git tag -a v2.5.7 -m "Release v2.5.7" + git push https://github.com/SimpleITK/SimpleITKRInstaller.git v2.5.7 + ``` + +1. Monitor, verify artifacts, and publish the release. + +1. Delete the short-lived branch: + + ``` + git push https://github.com/SimpleITK/SimpleITKRInstaller.git --delete release-v2.5.7 + git branch -d release-v2.5.7 + ```