22 push :
33 branches :
44 - main
5+ tags :
6+ - ' v*' # Trigger on version tags
57 pull_request :
68 branches :
79 - main
1113 # run testing on the first of each month 5am ET / 9am UTC
1214 - cron : ' 0 9 1 * *'
1315
16+ # Set minimal permissions for all jobs (read-only)
17+ permissions :
18+ contents : read
19+ actions : read
20+
1421jobs :
1522 R-build :
1623 strategy :
1724 fail-fast : false
1825 matrix :
1926 R : [ '4.4.3', '4.5.3', '4.6.0' ]
20- os : [ 'macos-15-intel', 'ubuntu-latest ', 'windows-latest']
27+ os : [ 'macos-15-intel', 'ubuntu-24.04 ', 'windows-latest']
2128 runs-on : ${{ matrix.os }}
2229 name : ${{ matrix.R }} ${{ matrix.os }} build
23- env :
24- R_LIBS : ${{ github.workspace }}/Rlibs
2530
2631 steps :
27- - uses : actions/checkout@v6
32+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2833 with :
2934 fetch-depth : 0
3035 ref : ${{ github.event.pull_request.head.sha }}
31- - name : Setup R
32- uses : r-lib/actions/setup-r@v2
36+
37+ - name : Setup R (also sets the R_LIBS_USER environment variable)
38+ uses : r-lib/actions/setup-r@a51a8012b0aab7c32ef9d19bf54da93f3254335e # v2.12.0
3339 with :
3440 r-version : ${{ matrix.R }}
3541 - name : System Dependencies
4147 - name : Configuration Information
4248 shell : bash
4349 run : |
44- mkdir -p "$R_LIBS"
4550 cmake --version
4651 if [[ "$RUNNER_OS" == "Windows" ]]; then
4752 ls -d /c/rtools* 2>/dev/null || echo "No rtools found in /c/"
@@ -55,11 +60,153 @@ jobs:
5560 - name : Install R packages
5661 shell : bash
5762 run : |
58- R -e "install.packages(c('remotes'), lib=Sys.getenv('R_LIBS '), repos='https://cloud.r-project.org/')"
63+ R -e "install.packages(c('remotes'), lib=Sys.getenv('R_LIBS_USER '), repos='https://cloud.r-project.org/')"
5964 - name : Build and test
6065 shell : bash
6166 env :
6267 ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS : 2
6368 run : |
64- R -e "Sys.setenv(MAKEJ=2); remotes::install_git(c('.'), lib=Sys.getenv('R_LIBS') )"
69+ R -e "Sys.setenv(MAKEJ=2); remotes::install_git(c('.'), lib=Sys.getenv('R_LIBS_USER'), upgrade='never', INSTALL_opts='--build' )"
6570 R -e "library(SimpleITK); Version()"
71+ - name : Rename package artifact
72+ # The original artifact name is SimpleITK_<sitk_version>.zip (windows),
73+ # SimpleITK_<sitk_version>.tgz (macOS), or SimpleITK_<sitk_version>.tar.gz (Linux).
74+ # This is irrespective of the R version. We need to rename them so that they are
75+ # unique. Otherwise we could not upload artifacts for different
76+ # R versions because the names collide.
77+ id : rename_package
78+ shell : bash
79+ run : |
80+ # canonical approach to collecting build artifacts in a directory for upload
81+ mkdir -p artifacts
82+
83+ # remotes::install_git(..., INSTALL_opts='--build') writes a valid package
84+ # file into the current working directory (GITHUB_WORKSPACE).
85+ PKG_PATH=$(find "${GITHUB_WORKSPACE}" -maxdepth 1 -type f \
86+ \( -name 'SimpleITK_*.tgz' -o -name 'SimpleITK_*.zip' -o -name 'SimpleITK_*.tar.gz' \) \
87+ | head -n 1)
88+
89+ if [[ -z "${PKG_PATH}" ]]; then
90+ echo "No built package artifact found in ${GITHUB_WORKSPACE}."
91+ exit 1
92+ fi
93+
94+ # package naming is SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_${OS_ARCHIVE_EXT}
95+ R_VERSION_SHORT=$(echo "${{ matrix.R }}" | cut -d'.' -f1,2)
96+ PKG_VERSION=$(Rscript -e "cat(read.dcf('DESCRIPTION', 'Version')[1])")
97+
98+ if [[ "$RUNNER_OS" == "macOS" ]]; then
99+ PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_macos-x86_64.tgz"
100+ elif [[ "$RUNNER_OS" == "Linux" ]]; then
101+ PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_linux-x86_64.tar.gz"
102+ elif [[ "$RUNNER_OS" == "Windows" ]]; then
103+ PKG_NAME="SimpleITK_${PKG_VERSION}_R${R_VERSION_SHORT}_windows-x86_64.zip"
104+ else
105+ echo "Unsupported OS: $RUNNER_OS"
106+ exit 1
107+ fi
108+
109+ mv "${PKG_PATH}" "${GITHUB_WORKSPACE}/artifacts/${PKG_NAME}"
110+ ls -lh artifacts/
111+
112+ # Export PKG_NAME as output for use in upload step
113+ echo "pkg_name=${PKG_NAME}" >> $GITHUB_OUTPUT
114+ - name : Upload binary package
115+ if : steps.rename_package.outcome == 'success'
116+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
117+ with :
118+ name : ${{ steps.rename_package.outputs.pkg_name }}
119+ path : artifacts/*
120+ retention-days : 30
121+
122+ create-release :
123+ name : Create GitHub Draft Release
124+ # Only run this job for tag pushes after the R-build job completes
125+ # successfully.
126+ if : startsWith(github.ref, 'refs/tags/v')
127+ needs : R-build
128+ runs-on : ubuntu-latest
129+ permissions :
130+ contents : write
131+
132+ steps :
133+ - name : Checkout repository
134+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
135+ with :
136+ fetch-depth : 1
137+
138+ - name : Verify tag matches SITK_TARGET
139+ id : verify_tag
140+ run : |
141+ SITK_TARGET=$(grep '^SITK_TARGET:' DESCRIPTION | awk '{print $2}')
142+ TAG_NAME="${{ github.ref_name }}"
143+ if [ "${TAG_NAME}" != "${SITK_TARGET}" ]; then
144+ echo "Tag ${TAG_NAME} does not match SITK_TARGET ${SITK_TARGET}"
145+ echo "Skipping draft release creation."
146+ echo "draft_release=false" >> $GITHUB_OUTPUT
147+ else
148+ echo "draft_release=true" >> $GITHUB_OUTPUT
149+ fi
150+
151+ - name : Download all artifacts
152+ if : steps.verify_tag.outputs.draft_release == 'true'
153+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
154+ with :
155+ path : release-artifacts
156+ pattern : SimpleITK_*
157+ merge-multiple : true
158+
159+ - name : Display downloaded artifacts
160+ if : steps.verify_tag.outputs.draft_release == 'true'
161+ run : |
162+ echo "Downloaded artifacts:"
163+ ls -lhR release-artifacts/
164+
165+ # This action automatically creates the release if it doesn't exist,
166+ # or updates it if it does.
167+ - name : Create or Update Draft Release
168+ if : steps.verify_tag.outputs.draft_release == 'true'
169+ uses : softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
170+ env :
171+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
172+ with :
173+ draft : true
174+ name : SimpleITK ${{ github.ref_name }} R Package Release
175+ body : |
176+ **Please review and test the packages before publishing this release. Then remove this line and make it public.**
177+
178+ Detailed release notes are available on the [main SimpleITK repository](https://github.com/SimpleITK/SimpleITK/releases/${{ github.ref_name }}).
179+
180+ 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.
181+
182+ To install the latest SimpleITK version to your primary library directory, first element of `.libPaths()`, run the following:
183+
184+ ```r
185+ # install the SimpleITK foyer package
186+ install.packages(
187+ "SimpleITK.foyer",
188+ repos = c("https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/"),
189+ type = "source"
190+ )
191+
192+ # Use foyer to install SimpleITK
193+ library(SimpleITK.foyer)
194+ install_simpleitk()
195+ ```
196+ Now you can load the SimpleITK library as usual:
197+
198+ ```r
199+ library(SimpleITK)
200+ ```
201+
202+ The `install_simpleitk` function provides finer installation control such as SimpleITK version, library installation location and more. To see all options:
203+
204+ ```r
205+ help(install_simpleitk)
206+ ```
207+
208+ 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_<version>.zip` (windows), `SimpleITK_<version>.tgz` (macOS), or `SimpleITK_<version>.tar.gz` (Linux) to match the expected file name format.
209+
210+ files : |
211+ release-artifacts/*
212+ fail_on_unmatched_files : true
0 commit comments