Skip to content

Commit 3bc4a23

Browse files
committed
added macos tarball generation
1 parent a381e45 commit 3bc4a23

2 files changed

Lines changed: 186 additions & 1 deletion

File tree

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Build a GEMC binary tarball natively on macOS (Apple Silicon).
2+
#
3+
# macOS has no Docker base image, so unlike the Linux Deploy/Binary Tarballs
4+
# pipeline this does NOT build/push an image. Instead it consumes the prebuilt
5+
# Geant4 macOS tarball produced by gemc/g4install's "macos_tarball" workflow,
6+
# unpacks it, downloads the Geant4 physics data, then compiles and tests GEMC
7+
# exactly as the Linux container does (via ci/build.sh). The resulting install
8+
# tree is repackaged with ci/package_install.sh into a relocatable GEMC tarball
9+
# that is attached to the rolling "dev" prerelease.
10+
name: macOS GEMC Binary Tarball
11+
12+
run-name: macOS GEMC binary tarball
13+
14+
permissions:
15+
contents: write
16+
17+
concurrency:
18+
group: gemc-macos-tarball-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
on:
22+
# Run after the nightly dev release (44 1 * * *) has anchored the "dev"
23+
# prerelease and after g4install's macOS Geant4 tarball (0 2 * * *) has been
24+
# attached to its own dev release.
25+
schedule:
26+
- cron: '0 5 * * *'
27+
workflow_dispatch:
28+
inputs:
29+
geant4_tarball_repo:
30+
description: 'Repository hosting the Geant4 macOS tarball release'
31+
required: false
32+
default: 'gemc/g4install'
33+
geant4_tarball_tag:
34+
description: 'Release tag holding the Geant4 macOS tarball'
35+
required: false
36+
default: 'dev'
37+
38+
jobs:
39+
build-tarball:
40+
name: gemc macos arm64
41+
# macos-26 (Tahoe) matches the macosx26 OSRELEASE the Geant4 tarball is
42+
# built with; GitHub's macOS runners are Apple Silicon (arm64).
43+
runs-on: macos-26
44+
env:
45+
TAG_NAME: dev
46+
GEANT4_TARBALL_REPO: ${{ github.event.inputs.geant4_tarball_repo || 'gemc/g4install' }}
47+
GEANT4_TARBALL_TAG: ${{ github.event.inputs.geant4_tarball_tag || 'dev' }}
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v6
51+
with:
52+
# Full history so ci/gemc_version.sh / git describe behave like the
53+
# other build jobs.
54+
fetch-depth: 0
55+
56+
- name: Install build dependencies (Homebrew)
57+
env:
58+
# GitHub macOS runners pre-tap aws/azure/hashicorp; newer Homebrew
59+
# refuses untrusted taps and aborts. We use none of those taps, so
60+
# skip the trust check and the auto-update tap scan.
61+
HOMEBREW_NO_REQUIRE_TAP_TRUST: "1"
62+
HOMEBREW_NO_AUTO_UPDATE: "1"
63+
run: |
64+
# meson/ninja/cmake + pkg-config drive the build; qt6 and root supply
65+
# the GUI and analysis dependencies; sqlite/expat/zlib/tbb are the
66+
# remaining libraries GEMC links against. XQuartz provides the X11/GL
67+
# runtime the Geant4 tarball was built against.
68+
brew install meson ninja cmake pkg-config qt root sqlite expat zlib tbb
69+
brew install --cask xquartz
70+
71+
- name: Download the Geant4 macOS tarball
72+
env:
73+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
shell: bash
75+
run: |
76+
set -euo pipefail
77+
dest="${RUNNER_TEMP}/geant4-download"
78+
mkdir -p "${dest}"
79+
gh release download "${GEANT4_TARBALL_TAG}" \
80+
--repo "${GEANT4_TARBALL_REPO}" \
81+
--pattern 'geant4-*-macosx*-arm64.tar.gz' \
82+
--dir "${dest}"
83+
tarball="$(ls "${dest}"/geant4-*-macosx*-arm64.tar.gz | head -1)"
84+
echo "GEANT4_TARBALL=${tarball}" >> "$GITHUB_ENV"
85+
ls -l "${dest}"
86+
87+
- name: Build, test and package GEMC
88+
id: build
89+
shell: zsh {0}
90+
env:
91+
# Headless runner: skip the interactive (GUI) meson tests (see ci/env.sh).
92+
GEMC_INTERACTIVE_TESTS: "false"
93+
run: |
94+
set -e
95+
96+
# --- Unpack the Geant4 tarball and derive its versions -------------
97+
# The asset name encodes both versions: geant4-<g4ver>-<osrelease>.tar.gz
98+
base="${GEANT4_TARBALL:t:r:r}" # strip dir + .tar + .gz
99+
rest="${base#geant4-}" # <g4ver>-<osrelease>
100+
g4ver="${rest%%-*}" # e.g. 11.4.2
101+
osrelease="${rest#*-}" # e.g. macosx26-clang17-arm64
102+
echo "Geant4 version: ${g4ver}"
103+
echo "OSRELEASE: ${osrelease}"
104+
105+
g4home="${RUNNER_TEMP}/geant4"
106+
mkdir -p "${g4home}"
107+
tar -xzf "${GEANT4_TARBALL}" -C "${g4home}" --strip-components=1
108+
109+
# Download the Geant4 physics data, then activate the relocated stack.
110+
export GEANT4_HOME="${g4home}"
111+
"${g4home}/install_geant4_data.sh"
112+
source "${g4home}/geant4.env"
113+
114+
# --- Compose the build environment --------------------------------
115+
# geant4.env sets G4INSTALL / CLHEP_BASE_DIR / XERCESCROOT and the
116+
# G4*DATA variables but not PKG_CONFIG_PATH; GEMC's meson build resolves
117+
# CLHEP (and Xerces-C) through pkg-config, so expose those .pc dirs.
118+
# Homebrew's sqlite/expat/zlib are keg-only, so add their .pc dirs and
119+
# qt6's too.
120+
export PKG_CONFIG_PATH="${CLHEP_BASE_DIR}/lib/pkgconfig:${XERCESCROOT}/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
121+
for f in qt sqlite expat zlib; do
122+
export PKG_CONFIG_PATH="$(brew --prefix ${f})/lib/pkgconfig:${PKG_CONFIG_PATH}"
123+
done
124+
export PATH="$(brew --prefix qt)/bin:${PATH}"
125+
126+
# ROOT: thisroot.sh exports ROOTSYS, PATH and the dyld search path so
127+
# root-config is found at build time and the libs load when tests run.
128+
source "$(brew --prefix root)/bin/thisroot.sh"
129+
130+
echo " > geant4-config: $(command -v geant4-config) ($(geant4-config --version))"
131+
echo " > root-config: $(command -v root-config) ($(root-config --version))"
132+
133+
# --- Compile + install + test (same script as the Linux jobs) ------
134+
export SIM_HOME="${RUNNER_TEMP}/gemc-sim"
135+
mkdir -p "${SIM_HOME}"
136+
./ci/build.sh
137+
138+
# --- Repackage the install tree into a relocatable GEMC tarball -----
139+
package_name="gemc-$(ci/gemc_version.sh)-geant4-${g4ver}-${osrelease}"
140+
GEANT4_VERSION="${g4ver}" \
141+
ci/package_install.sh "${SIM_HOME}/gemc/dev" dist "${package_name}"
142+
143+
echo "package_name=${package_name}" >> "$GITHUB_OUTPUT"
144+
echo "tarball=dist/${package_name}.tar.gz" >> "$GITHUB_OUTPUT"
145+
146+
- name: Smoke test the GEMC tarball
147+
shell: bash
148+
run: |
149+
set -euo pipefail
150+
tarball="${{ steps.build.outputs.tarball }}"
151+
work="$(mktemp -d)"
152+
tar -xzf "${tarball}" -C "${work}" --strip-components=1
153+
# Structural check only; the functional suite already ran under
154+
# 'meson test'. Running gemc here would re-download the Geant4 data.
155+
test -x "${work}/install_geant4_data.sh"
156+
test -f "${work}/gemc.env"
157+
test -x "${work}/bin/gemc"
158+
otool -L "${work}/bin/gemc"
159+
160+
- name: Upload tarball artifact
161+
uses: actions/upload-artifact@v7
162+
with:
163+
name: gemc-tarball-${{ steps.build.outputs.package_name }}
164+
path: ${{ steps.build.outputs.tarball }}
165+
if-no-files-found: error
166+
167+
- name: Attach tarball to dev release
168+
env:
169+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
170+
REPO: ${{ github.repository }}
171+
shell: bash
172+
run: |
173+
set -euo pipefail
174+
tarball="${{ steps.build.outputs.tarball }}"
175+
gh release view "${TAG_NAME}" --repo "$REPO" >/dev/null 2>&1 || \
176+
gh release create "${TAG_NAME}" \
177+
--repo "$REPO" \
178+
--title "Dev Nightly" \
179+
--prerelease \
180+
--notes "Dev nightly release."
181+
gh release upload "${TAG_NAME}" --repo "$REPO" "${tarball}" --clobber

ci/env.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ test_interactive_option=""
119119
# if we are in the docker container, we need to load the modules
120120
if [[ -z "${AUTOBUILD}" ]]; then
121121
echo "\nNot in container"
122-
test_interactive_option="-Di_test=true"
122+
# Local developer machines run the interactive (GUI) tests by default.
123+
# Headless CI (e.g. the macOS tarball workflow) opts out with GEMC_INTERACTIVE_TESTS=false.
124+
if [[ "${GEMC_INTERACTIVE_TESTS:-true}" == "true" ]]; then
125+
test_interactive_option="-Di_test=true"
126+
fi
123127
else
124128
echo "\nIn docker container."
125129
# recent versions of Git refuse to touch a repository whose on-disk owner

0 commit comments

Comments
 (0)