-
Notifications
You must be signed in to change notification settings - Fork 65
199 lines (173 loc) · 8.18 KB
/
Copy pathcmake-macos.yml
File metadata and controls
199 lines (173 loc) · 8.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
name: CI macOS
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
release:
types: [ published ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-macos:
runs-on: ${{ matrix.runner }}
# So far, a full superbuild (no caches) has always been complete in < 45 minutes.
timeout-minutes: 45
permissions:
contents: write
actions: write
packages: write
strategy:
matrix:
include:
- arch: x86_64
runner: macos-15-intel
cmake_arch: x86_64
- arch: arm64
runner: macos-15
cmake_arch: arm64
# Checkout and install python
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v7
with:
python-version: '3.10.11'
# Install build tools (cmake and ninja) as well as jsondiff
- name: "Install jsondiff"
run: pip install jsondiff
- name: "Install cmake"
run: |
cmake --version
echo ${PATH}
wget --no-check-certificate https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-mac.zip
unzip ninja-mac.zip && sudo cp ninja /usr/local/bin/
# Make sure all directories required for computing the hash actually exist
- name: "Prepare cache directories"
run: |
mkdir -p ${{ github.workspace }}/dcmqi-build/DCMTK-build
mkdir -p ${{ github.workspace }}/dcmqi-build/DCMTK
mkdir -p ${{ github.workspace }}/dcmqi-build/ITK
mkdir -p ${{ github.workspace }}/dcmqi-build/ITK-build
mkdir -p ${{ github.workspace }}/dcmqi-build/zlib-install
# Prepare the cache directories, which are DCMTK/ITK source and build directories
# since dcmqi build later requires DCMTK/ITK headers from source, and libraries from
# build directories. For ZLIB, installation directory is sufficient since it contains
# both, headers and libraries.
- name: Check for cached DCMTK, ITK and ZLIB
id: cache-dcmtk-itk-zlib
uses: actions/cache/restore@v6
env:
cache-name: cache-dcmtk-itk-zlib-v2
with:
# The recursive content of these directories goes into the cache
path: |
${{ github.workspace }}/dcmqi-build/DCMTK
${{ github.workspace }}/dcmqi-build/DCMTK-build
${{ github.workspace }}/dcmqi-build/ITK
${{ github.workspace }}/dcmqi-build/ITK-build
${{ github.workspace }}/dcmqi-build/zlib-install
# The hash key decides whether cache entry is out of date or can be used.
# We use the hash of the CMakeExternals files to decide whether
# we must rebuild it. Also a change in the OS will trigger cash rebuild.
# A hashkey will have the form of macOS-<arch>-build-cache-dcmtk-itk-zlib-v2-<hash>
key: ${{ runner.os }}-${{ matrix.arch }}-build-${{ env.cache-name }}-${{ hashFiles('CMakeExternals/DCMTK.cmake','CMakeExternals/ITK.cmake', 'CMakeExternals/zlib.cmake') }}
# Report cache status for monitoring
- name: Report cache status
run: |
if [ "${{ steps.cache-dcmtk-itk-zlib.outputs.cache-hit }}" == "true" ]; then
echo "✓ Cache hit! Using cached DCMTK, ITK, and zlib"
echo "Cache key: ${{ steps.cache-dcmtk-itk-zlib.outputs.cache-primary-key }}"
du -sh ${{ github.workspace }}/dcmqi-build/DCMTK* ${{ github.workspace }}/dcmqi-build/ITK* ${{ github.workspace }}/dcmqi-build/zlib-install 2>/dev/null || true
else
echo "✗ Cache miss. Will build DCMTK, ITK, and zlib from source"
fi
- name: Validate restored cache
id: validate-cache
run: |
CACHE_OK=false
if [ "${{ steps.cache-dcmtk-itk-zlib.outputs.cache-hit }}" == "true" ]; then
CACHE_OK=true
if [ ! -f "$GITHUB_WORKSPACE/dcmqi-build/ITK-build/ITKConfig.cmake" ]; then
echo "Missing ITK config: $GITHUB_WORKSPACE/dcmqi-build/ITK-build/ITKConfig.cmake"
CACHE_OK=false
fi
if [ ! -f "$GITHUB_WORKSPACE/dcmqi-build/DCMTK-build/DCMTKConfig.cmake" ]; then
echo "Missing DCMTK config: $GITHUB_WORKSPACE/dcmqi-build/DCMTK-build/DCMTKConfig.cmake"
CACHE_OK=false
fi
if [ ! -d "$GITHUB_WORKSPACE/dcmqi-build/zlib-install/include" ] || [ ! -d "$GITHUB_WORKSPACE/dcmqi-build/zlib-install/lib" ]; then
echo "Missing zlib install directories: $GITHUB_WORKSPACE/dcmqi-build/zlib-install/include and/or $GITHUB_WORKSPACE/dcmqi-build/zlib-install/lib"
CACHE_OK=false
fi
fi
echo "cache_ok=$CACHE_OK" >> "$GITHUB_OUTPUT"
echo "Validated cache usability: $CACHE_OK"
# This is step executed if a cache entry is found
- name: "Configure dcmqi w/ cached DCMTK/ITK/ZLIB"
if: ${{ steps.cache-dcmtk-itk-zlib.outputs.cache-hit == 'true' && steps.validate-cache.outputs.cache_ok == 'true' }}
# Make sure to set ITK, DCMTK and ZLIB directories to dcmqi cmake configuration step
run: |
cd ${{ github.workspace }}/dcmqi-build && cmake -G Ninja ${{ github.workspace }} -DDCMTK_DIR=${{ github.workspace }}/dcmqi-build/DCMTK-build -DITK_DIR=${{ github.workspace }}/dcmqi-build/ITK-build -DZLIB_ROOT=${{ github.workspace }}/dcmqi-build/zlib-install
# If we don't have a matching cache entry, configure for full rebuild (regular dcmqi superbuild)
- name: "Configure dcmqi w/o cached DCMTK/ITK/ZLIB"
if: ${{ steps.cache-dcmtk-itk-zlib.outputs.cache-hit != 'true' || steps.validate-cache.outputs.cache_ok != 'true' }}
run: |
cd ${{ github.workspace }}/dcmqi-build && cmake -G Ninja ${{ github.workspace }}
# Build dcmqi
- name: "Build dcmqi"
run: |
cd ${{ github.workspace }}/dcmqi-build && ninja
- name: "Test dcmqi"
run: |
cd ${{ github.workspace }}/dcmqi-build/dcmqi-build
ctest -VV -DCTEST_MODEL=$CTEST_MODEL -DCTEST_EMPTY_BINARY_DIRECTORY=FALSE .
# ...and finally package it.
- name: "Package dcmqi"
run: |
cd ${{ github.workspace }}/dcmqi-build/dcmqi-build && ninja package
- name: "Upload package as artifact"
id: upload-artifact
uses: actions/upload-artifact@v7
continue-on-error: true
with:
name: dcmqi-macos-${{ matrix.arch }}-package
# Example:
# /Users/runner/work/dcmqi/dcmqi/dcmqi-build/dcmqi-build/dcmqi-1.4.0-mac-20260104-9b9b2be.tar.gz
path: ${{ github.workspace }}/dcmqi-build/dcmqi-build/dcmqi-*-mac*.tar.gz
- name: "Upload package as artifact (retry)"
if: steps.upload-artifact.outcome == 'failure'
uses: actions/upload-artifact@v7
with:
name: dcmqi-macos-${{ matrix.arch }}-package
path: ${{ github.workspace }}/dcmqi-build/dcmqi-build/dcmqi-*-mac*.tar.gz
# Save cache even if a later step (test, package) failed, so deps don't need rebuilding next run
- name: Save DCMTK, ITK and ZLIB cache
if: always() && steps.cache-dcmtk-itk-zlib.outputs.cache-hit != 'true'
uses: actions/cache/save@v6
with:
path: |
${{ github.workspace }}/dcmqi-build/DCMTK
${{ github.workspace }}/dcmqi-build/DCMTK-build
${{ github.workspace }}/dcmqi-build/ITK
${{ github.workspace }}/dcmqi-build/ITK-build
${{ github.workspace }}/dcmqi-build/zlib-install
key: ${{ steps.cache-dcmtk-itk-zlib.outputs.cache-primary-key }}
- name: Publish package
# Publish tagged (stable) releases only. The rolling "latest" prerelease is
# (re)created by the finalize-latest workflow once all platforms finish building.
# The repository-owner check prevents forks from publishing packages even if the
# owner's token would have sufficient privileges.
if: ${{ (github.event_name == 'release') && (github.repository_owner == 'QIICR') }}
env:
GH_TOKEN: ${{ secrets.GA_TOKEN }}
run: |
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
if [ -n "$TAG" ] && [ "$TAG" != "latest" ]; then
gh release upload "$TAG" \
${{ github.workspace }}/dcmqi-build/dcmqi-build/dcmqi-*-mac-${{ matrix.arch }}.tar.gz \
--clobber
fi