Skip to content

Commit 390ee59

Browse files
committed
testing sanitizer workflow with json matrix
1 parent 59a052b commit 390ee59

5 files changed

Lines changed: 185 additions & 42 deletions

File tree

.github/workflows/docker.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,15 @@ jobs:
219219
IMAGE: ${{ needs.discover.outputs.image }}
220220
TAG: ${{ format('{0}-{1}-{2}-{3}', matrix.gemc_tag, matrix.geant4_tag, matrix.image, matrix.image_tag) }}
221221
run: |
222-
: "${GITHUB_STEP_SUMMARY:=$RUNNER_TEMP/manifest_summary.md}"
222+
SUMMARY_FILE="${GITHUB_STEP_SUMMARY:-$RUNNER_TEMP/manifest_summary.md}"
223+
echo "MANIFEST_SUMMARY_FILE=$SUMMARY_FILE" >> "$GITHUB_ENV"
224+
223225
{
224226
echo "## \`${IMAGE}:${TAG}\`"
225227
echo ""
226228
echo "Includes:"
227229
if docker buildx imagetools inspect "${IMAGE}:${TAG}-amd64" >/dev/null 2>&1; then echo "- amd64"; fi
228-
if docker buildx imagetools inspect "${IMAGE}:${TAG}-arm64" >/dev/null 2>&1; then echo "- arm64"; else echo "no arm64. Run with --platform=linux/amd64 in arm64 CPUs"; fi
230+
if docker buildx imagetools inspect "${IMAGE}:${TAG}-arm64" >/dev/null 2>&1; then echo "- arm64"; else echo "- no arm64. Run with --platform=linux/amd64 in arm64 CPUs"; fi
229231
echo ""
230232
echo "### Pull"
231233
echo '```bash'
@@ -243,19 +245,19 @@ jobs:
243245
echo '```bash'
244246
echo "docker run --rm -it \$VPORTS \$VNC_BIND \$VNC_PASS \$GEO_FLAGS ${IMAGE}:${TAG}"
245247
echo '```'
246-
} >> "$GITHUB_STEP_SUMMARY"
248+
} >> "$SUMMARY_FILE"
247249
248250
# Also save a copy inside the workspace for artifact upload
249251
mkdir -p "$GITHUB_WORKSPACE/summaries"
250-
cp "$GITHUB_STEP_SUMMARY" "$GITHUB_WORKSPACE/summaries/summary-${{ matrix.gemc_tag }}-${{ matrix.geant4_tag }}-${{ matrix.image }}-${{ matrix.image_tag }}-${{ job.status }}.md" || true
252+
cp "$SUMMARY_FILE" "$GITHUB_WORKSPACE/summaries/summary-${{ matrix.gemc_tag }}-${{ matrix.geant4_tag }}-${{ matrix.image }}-${{ matrix.image_tag }}-${{ job.status }}.md" || true
251253
echo "Wrote $GITHUB_WORKSPACE/summaries/summary-${{ matrix.gemc_tag }}-${{ matrix.geant4_tag }}-${{ matrix.image }}-${{ matrix.image_tag }}-${{ job.status }}.md"
252254
ls -l "$GITHUB_WORKSPACE/summaries"
253255
254256
- name: Upload summary artifact (manifest)
255257
uses: actions/upload-artifact@v4
256258
with:
257259
name: summary-${{ matrix.gemc_tag }}-${{ matrix.geant4_tag }}-${{ matrix.image }}-${{ matrix.image_tag }}-manifest
258-
path: |
259-
${{ runner.temp }}/manifest_summary.md
260+
path: ${{ env.MANIFEST_SUMMARY_FILE }}
260261
if-no-files-found: warn
261262

263+

.github/workflows/sanitize.yaml

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,53 @@
11
name: Sanitize
22
permissions:
33
contents: read
4-
pull-requests: write
4+
packages: write
5+
6+
# default varsions. This is overwritten by distros_tags.sh
7+
env:
8+
GEMC_TAG: dev # default gemc tag
9+
GEANT4_TAG: 11.4.0 # default geant4 tag
10+
11+
concurrency:
12+
group: gemc-images-${{ github.ref }}
13+
cancel-in-progress: true
514

6-
# Controls when the workflow will run
715
on:
8-
# Triggers the workflow on all pushes
916
push:
10-
branches:
11-
- '*'
17+
branches: [ main ] # publish on main updates
18+
tags: [ 'v*' ] # also publish on version tags
19+
pull_request: # PRs: build only (no push)
1220

13-
# Allows you to run this workflow manually from the Actions tab
14-
workflow_dispatch:
1521

1622
jobs:
23+
discover:
24+
name: Create Job Matrices
25+
runs-on: ubuntu-latest
26+
outputs:
27+
matrix_sanitize: ${{ steps.scan.outputs.matrix_sanitize }}
28+
image: ${{ steps.scan.outputs.image }}
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
- id: scan
33+
name: Build matrix
34+
run: ci/distros_tags.sh
35+
1736
build-with-sanitizer:
37+
name: ${{ matrix.image }}:${{ matrix.image_tag }} ${{ matrix.image_tag }}
38+
needs: [ discover ]
1839
strategy:
19-
# max-parallel: 4
20-
matrix:
21-
container:
22-
- name: ubuntu24
23-
image: jeffersonlab/geant4:g4v11.3.2-ubuntu24
24-
- name: fedora40
25-
image: jeffersonlab/geant4:g4v11.3.2-fedora40
26-
- name: almalinux94
27-
image: jeffersonlab/geant4:g4v11.3.2-almalinux94
28-
# NOTE: additional packages needed for the sanitizer: libasan libubsan libtsan
29-
# MacOS: address, thread, undefined
30-
# Linux: address, hwaddress, leak, undefined, integer, thread, cfi, kcfi, shadowcallstack
31-
sanitize: [ none, address, hwaddress, leak, undefined, integer, thread, cfi, kcfi, shadowcallstack ]
32-
runs-on: ubuntu-latest
33-
continue-on-error: true
34-
container: ${{ matrix.container.image }}
35-
name: ${{ matrix.container.name }}-${{ matrix.sanitize }}
40+
fail-fast: false
41+
matrix: ${{ fromJSON(needs.discover.outputs.matrix_sanitize) }}
42+
runs-on: ${{ matrix.runner }}
43+
container: ${{ matrix.container }}
3644

3745
steps:
3846
- name: Checkout
39-
uses: actions/checkout@main
40-
- name: Fix Ownership
41-
run: |
42-
# recent versions of Git refuse to touch a repository whose on-disk owner
43-
# doesn’t match the UID that is running the command
44-
# mark the workspace (and any nested path) as safe
45-
git config --global --add safe.directory "$GITHUB_WORKSPACE"
46-
git config --global --add safe.directory "$GITHUB_WORKSPACE"/src
47+
uses: actions/checkout@v4
4748
- name: Build ${{ matrix.sanitize }}
4849
run: |
49-
./ci/build.sh ${{ matrix.sanitize }}
50+
./ci/build.sh ${{ matrix.sanitizer }}
5051
5152
build_with_sanitizert-final:
5253
needs:

ci/distros_tags.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ get_runner() {
1111
"amd64") echo "ubuntu-latest" ;;
1212
*)
1313
echo "ERROR: unsupported arch $arch" >&2
14-
return 2
14+
return 2
1515
;;
1616
esac
1717
}
@@ -34,7 +34,7 @@ build_matrix_build() {
3434
arch_list="$(get_cpu_architectures)"
3535
gemc_list="$(get_gemc_tags)"
3636

37-
local -a g4_tags arch_tags
37+
local -a g4_tags arch_tags gemc_tags
3838
read -r -a g4_tags <<<"$g4_list"
3939
read -r -a arch_tags <<<"$arch_list"
4040
read -r -a gemc_tags <<<"$gemc_list"

ci/env.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ function meson_setup_options {
4242

4343
meson_options=""
4444
buildtype=" -Dbuildtype=debug "
45-
interactive_option=""
4645

4746
case $1 in
4847
"address")

ci/sanitizers_tags.sh

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
get_geant4_tag() { echo "11.4.0"; } # only one allowed
5+
get_gemc_tags() { echo "dev"; }
6+
get_cpu_architectures() { echo "arm64 amd64"; } # space separated list.
7+
get_runner() {
8+
local arch=$1
9+
case "$arch" in
10+
"arm64") echo "ubuntu-24.04-arm" ;;
11+
"amd64") echo "ubuntu-latest" ;;
12+
*)
13+
echo "ERROR: unsupported arch $arch" >&2
14+
return 2
15+
;;
16+
esac
17+
}
18+
lc() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; } # portable lowercasing
19+
20+
# Single source of truth (order preserved)
21+
OS_VERSIONS=(
22+
"ubuntu=24.04"
23+
"fedora=40"
24+
"almalinux=9.4"
25+
"debian=12"
26+
"archlinux=latest"
27+
)
28+
29+
# full sanitizers:
30+
# on macOS, LeakSanitizer (LSan) support is materially less uniform and
31+
# more fragile across toolchains and architectures than ASan/UBSan/TSan.
32+
# macos: address, thread, undefined
33+
# linux: address, thread, undefined, leak
34+
#
35+
# In the CI we first run one sanitizer at a time until all issues are solved
36+
# Then we can run them all
37+
get_sanitizers() {
38+
local choice_of_sanitizer="address"
39+
local baseos=$1
40+
case "$baseos" in
41+
"macos") echo $choice_of_sanitizer ;;
42+
"ubuntu" | "fedora" | "almalinux" | "debian" | "archlinux") echo $choice_of_sanitizer ;;
43+
*)
44+
echo "ERROR: unsupported baseos $baseos" >&2
45+
return 2
46+
;;
47+
esac
48+
49+
}
50+
51+
build_matrix_build() {
52+
53+
local arch_list gemc_list
54+
arch_list="$(get_cpu_architectures)"
55+
gemc_list="$(get_gemc_tags)"
56+
57+
local -a arch_tags gemc_tags
58+
read -r -a arch_tags <<<"$arch_list"
59+
read -r -a gemc_tags <<<"$gemc_list"
60+
61+
g4v="$(get_geant4_tag)"
62+
63+
local body="" sep="" pair os ver
64+
for cpuv in "${arch_tags[@]}"; do
65+
for gemcv in "${gemc_tags[@]}"; do
66+
for pair in "${OS_VERSIONS[@]}"; do
67+
os="${pair%%=*}"
68+
ver="${pair#*=}"
69+
70+
local runner="$(get_runner "$cpuv")"
71+
72+
local sanitizer_list="$(get_sanitizers "$os")"
73+
local sanitizer_tags
74+
read -r -a sanitizer_tags <<<"$sanitizer_list"
75+
for sanitizer in "${sanitizer_tags[@]}"; do
76+
77+
# archlinux is amd64-only
78+
if [[ "$os" == "archlinux" && "$cpuv" == "arm64" ]]; then
79+
continue
80+
fi
81+
82+
body+="${sep}{"
83+
body+="\"container\":\"ghcr.io/gemc/g4install:${g4v}-${os}-${ver}\","
84+
body+="\"runner\":\"${runner}\","
85+
body+="\"sanitizer\":\"${sanitizer}\""
86+
body+="}"
87+
sep=","
88+
done
89+
done
90+
done
91+
done
92+
93+
local json="{\"include\":[${body}]}"
94+
if command -v jq >/dev/null 2>&1; then
95+
# printf '%s' "$json"
96+
printf '%s' "$json" | jq -c .
97+
else
98+
printf '%s' "$json"
99+
fi
100+
}
101+
102+
103+
104+
105+
build_image_ref() {
106+
# Owner from env (Actions sets this). Fallback for local runs.
107+
local owner="${GITHUB_REPOSITORY_OWNER:-gemc}"
108+
109+
# Repo name = LAST segment of GITHUB_REPOSITORY (strip any "owner/" prefix).
110+
# Fallback to a default if env is missing during local runs.
111+
local repo_full="${GITHUB_REPOSITORY:-gemc/src}"
112+
local repo="${repo_full##*/}" # strip anything up to and including the last slash
113+
114+
# Lowercase both parts (GHCR requires lowercase)
115+
printf 'ghcr.io/%s/%s' "$(lc "$owner")" "$(lc "$repo")"
116+
}
117+
118+
# the separate matrices are needed so that manifest is not run twice
119+
main() {
120+
local image_ref
121+
image_ref="$(build_image_ref)"
122+
123+
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
124+
local DELIM_BUILD="MATRIX_BUILD_$(date +%s%N)"
125+
local DELIM_MANIFEST="MATRIX_MANIFEST_$(date +%s%N)"
126+
{
127+
echo "matrix_build<<$DELIM_BUILD"
128+
build_matrix_build
129+
echo "$DELIM_BUILD"
130+
131+
echo "image=$image_ref"
132+
} >>"$GITHUB_OUTPUT"
133+
else
134+
echo "== matrix_sanitize =="
135+
build_matrix_build
136+
echo
137+
fi
138+
139+
}
140+
141+
main "$@"

0 commit comments

Comments
 (0)