Skip to content

WIP: Binary distributions via GitHub Releases. #183

WIP: Binary distributions via GitHub Releases.

WIP: Binary distributions via GitHub Releases. #183

Workflow file for this run

on:
push:
branches:
- main
tags:
- 'v*' # Trigger on version tags
pull_request:
branches:
- main
workflow_dispatch:
# enable manual triggering
schedule:
# run testing on the first of each month 5am ET / 9am UTC
- cron: '0 9 1 * *'
# Set minimal permissions for all jobs (read-only)
permissions:
contents: read
actions: read
jobs:
R-build:
strategy:
fail-fast: false
matrix:
R: [ '4.4.3', '4.5.3', '4.6.0' ]
os: [ 'macos-15-intel', 'ubuntu-24.04', 'windows-latest']
runs-on: ${{ matrix.os }}
name: ${{ matrix.R }} ${{ matrix.os }} build
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup R (also sets the R_LIBS_USER environment variable)
uses: r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2.12.0
with:
r-version: ${{ matrix.R }}
- name: System Dependencies
if: startsWith( matrix.os, 'ubuntu' )
run: |
sudo apt-get -y update &&
sudo apt-get install -y libcurl4-openssl-dev libssh2-1-dev libharfbuzz-dev libfribidi-dev gh &&
sudo rm -rf /var/lib/apt/lists/*
- name: Configuration Information
shell: bash
run: |
cmake --version
if [[ "$RUNNER_OS" == "Windows" ]]; then
ls -d /c/rtools* 2>/dev/null || echo "No rtools found in /c/"
which g++ || { echo "No g++ found on PATH"; exit 1; }
g++ --version
else
c++ --version
fi
which R
R --version
- name: Install R packages
shell: bash
run: |
R -e "install.packages(c('remotes'), lib=Sys.getenv('R_LIBS_USER'), repos='https://cloud.r-project.org/')"
- name: Build and test
shell: bash
env:
ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS: 2
run: |
R -e "Sys.setenv(MAKEJ=2); remotes::install_git(c('.'), lib=Sys.getenv('R_LIBS_USER'), upgrade='never', INSTALL_opts='--build')"
R -e "library(SimpleITK); Version()"
- name: Collect built package artifact
id: create_package
shell: bash
run: |
# canonical approach to collecting build artifacts in a directory for upload
mkdir -p artifacts
# remotes::install_git(..., INSTALL_opts='--build') writes a valid package
# file into the current working directory (GITHUB_WORKSPACE).
PKG_PATH=$(find "${GITHUB_WORKSPACE}" -maxdepth 1 -type f \
\( -name 'SimpleITK_*.tgz' -o -name 'SimpleITK_*.zip' -o -name 'SimpleITK_*.tar.gz' \) \
| head -n 1)
if [[ -z "${PKG_PATH}" ]]; then
echo "No built package artifact found in ${GITHUB_WORKSPACE}."
exit 1
fi
# package naming is SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_${OS_ARCHIVE_EXT}
R_VERSION_SHORT=$(echo "${{ matrix.R }}" | cut -d'.' -f1,2)
PKG_VERSION=$(Rscript -e "cat(read.dcf('DESCRIPTION', 'Version')[1])")
if [[ "$RUNNER_OS" == "macOS" ]]; then
PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_macos-x86_64.tgz"
elif [[ "$RUNNER_OS" == "Linux" ]]; then
PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_linux-x86_64.tar.gz"
elif [[ "$RUNNER_OS" == "Windows" ]]; then
PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_windows-x86_64.zip"
else
echo "Unsupported OS: $RUNNER_OS"
exit 1
fi
mv "${PKG_PATH}" "${GITHUB_WORKSPACE}/artifacts/${PKG_NAME}"
ls -lh artifacts/
# Export PKG_NAME as output for use in upload step
echo "pkg_name=${PKG_NAME}" >> $GITHUB_OUTPUT
- name: Upload binary package
if: steps.create_package.outcome == 'success'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ steps.create_package.outputs.pkg_name }}
path: artifacts/*
retention-days: 30
create-release:
name: Create GitHub Draft Release
# Only run this job for tag pushes after the R-build job completes
# successfully.
if: startsWith(github.ref, 'refs/tags/v')
needs: R-build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: Verify tag matches SITK_TARGET
id: verify_tag
run: |
SITK_TARGET=$(grep '^SITK_TARGET:' DESCRIPTION | awk '{print $2}')
TAG_NAME="${{ github.ref_name }}"
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
else
echo "draft_release=true" >> $GITHUB_OUTPUT
fi
- name: Download all artifacts
if: steps.verify_tag.outputs.draft_release == 'true'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: release-artifacts
pattern: SimpleITK_*
merge-multiple: true
- name: Display downloaded artifacts
if: steps.verify_tag.outputs.draft_release == 'true'
run: |
echo "Downloaded artifacts:"
ls -lhR release-artifacts/
# 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'
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
draft: true
name: SimpleITK ${{ github.ref_name }} R Package Release
body: |
**Please 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/${{ github.ref_name }}).
The GitHub Pages repository provides platform-specific binaries. If a binary is not available, you will need to build SimpleITK locally using the remotes installer. See the [README](https://github.com/${{ github.repository }}/blob/main/README.md) for detailed instructions.
Windows and macOS:
```r
install.packages(
"SimpleITK",
repos = c("https://simpleitk.github.io/SimpleITKRInstaller/${{ github.ref_name }}"),
type = "binary"
)
```
Linux:
```r
install.packages(
"SimpleITK",
repos = NULL,
contriburl = paste0(
"https://simpleitk.github.io/SimpleITKRInstaller/${{ github.ref_name }}/__linux__/ubuntu-noble/",
paste(R.version$major, sub("\\..*$", "", R.version$minor), sep = "."),
"/src/contrib"
),
type = "source"
)
```
The Linux install above uses a "source" type installation even though it is binary, due to the way R handles binary packages on this platform.
files: |
release-artifacts/*
fail_on_unmatched_files: true