CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
214 lines
8.7 KiB
Bash
Executable File
214 lines
8.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Copyright (c) Advanced Micro Devices, Inc. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# Single source of truth for the "which images do we build" logic used by the
|
|
# Precheck job in .github/workflows/hipfile-ci-toplevel.yml ("Compute images to
|
|
# build" step). compute_build_set decides the matrix of images to (re)build:
|
|
# - a Dockerfile change rebuilds the whole catalog;
|
|
# - otherwise only nightly rows may need building (other versions reuse their
|
|
# latest-rocm<ver> images from hipfile-image-update.yml), and a nightly row
|
|
# is built only when its base or nvidia image isn't already published.
|
|
#
|
|
# Two ways to use it:
|
|
# Sourced (CI): source build-ci-images-matrix.sh
|
|
# -> sets shell var build_CI_images_matrix from the env vars
|
|
# CHANGED_DOCKERFILE, FULL_CI_IMAGES_MATRIX, CI_IMAGES
|
|
# (querying GHCR for nightly rows)
|
|
# Tests: bash build-ci-images-matrix.sh --test
|
|
#
|
|
# The only impurity is the registry-existence check, isolated behind
|
|
# _image_published so --test can override it and run offline. Everything else is
|
|
# pure; because the same code is shipped to CI and exercised by --test, the two
|
|
# can never drift.
|
|
|
|
# --- pure helpers: the jq, one copy each ----------------------------------
|
|
|
|
# Keep only the nightly rows of a matrix (rocm_versions == "nightly") -- the
|
|
# only rows whose target moves daily and so may need (re)building this run.
|
|
# Args: matrix (JSON {include:[...]})
|
|
filter_nightly_rows() {
|
|
local matrix="$1"
|
|
printf '%s' "${matrix}" \
|
|
| jq -c '{include: [.include[] | select(.rocm_versions == "nightly")]}'
|
|
}
|
|
|
|
# Keep only candidate rows whose "<supported_platforms>-<rocm_versions>" key is
|
|
# present in to_build.
|
|
# Args: candidate (JSON {include:[...]}) to_build (space-separated keys)
|
|
select_to_build() {
|
|
local candidate="$1" to_build="$2"
|
|
printf '%s' "${candidate}" | jq -c --arg tb "${to_build}" \
|
|
'($tb | split(" ") | map(select(length > 0))) as $b
|
|
| {include: [.include[]
|
|
| select((.supported_platforms + "-" + .rocm_versions) as $k | $b | index($k))]}'
|
|
}
|
|
|
|
# --- impurity seam --------------------------------------------------------
|
|
|
|
# Returns 0 if the image ref already exists in the registry. This is the one
|
|
# I/O point; --test overrides it to keep the suite offline.
|
|
# Args: image_ref
|
|
_image_published() {
|
|
docker buildx imagetools inspect "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
# --- orchestration --------------------------------------------------------
|
|
|
|
# Emit the matrix of images to (re)build on stdout. Progress notes go to stderr
|
|
# so stdout carries only the JSON result.
|
|
# Args: changed_dockerfile ("1" or other) full_ci_images_matrix (JSON)
|
|
# ci_images (JSON map: "<sp>-<rv>" -> {ci_image, ci_image_nvidia, ...})
|
|
compute_build_set() {
|
|
local changed_dockerfile="$1" full_ci_images_matrix="$2" ci_images="$3"
|
|
|
|
if [ "${changed_dockerfile}" = "1" ]; then
|
|
printf '%s' "${full_ci_images_matrix}"
|
|
return
|
|
fi
|
|
|
|
local nightly_matrix to_build="" key img img_nvidia
|
|
nightly_matrix=$(filter_nightly_rows "${full_ci_images_matrix}")
|
|
|
|
# A nightly row is (re)built when its base OR nvidia image is missing.
|
|
for key in $(printf '%s' "${nightly_matrix}" \
|
|
| jq -r '.include[] | "\(.supported_platforms)-\(.rocm_versions)"'); do
|
|
img=$(printf '%s' "${ci_images}" | jq -r --arg k "${key}" '.[$k].ci_image')
|
|
img_nvidia=$(printf '%s' "${ci_images}" | jq -r --arg k "${key}" '.[$k].ci_image_nvidia')
|
|
if ! _image_published "${img}" || ! _image_published "${img_nvidia}"; then
|
|
echo "Nightly image not yet published, will build: ${key}" >&2
|
|
to_build="${to_build}${key} "
|
|
fi
|
|
done
|
|
|
|
select_to_build "${nightly_matrix}" "${to_build}"
|
|
}
|
|
|
|
# --- test suite -----------------------------------------------------------
|
|
|
|
_assert_eq() {
|
|
local label="$1" actual="$2" expected="$3"
|
|
local a_norm e_norm
|
|
a_norm=$(printf '%s' "${actual}" | jq -cS '.include |= sort')
|
|
e_norm=$(printf '%s' "${expected}" | jq -cS '.include |= sort')
|
|
if [ "${a_norm}" = "${e_norm}" ]; then
|
|
printf ' PASS %s\n -> %s\n' "${label}" "${a_norm}"
|
|
else
|
|
printf ' FAIL %s\n expected: %s\n got: %s\n' \
|
|
"${label}" "${e_norm}" "${a_norm}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
_run_tests() {
|
|
set -uo pipefail
|
|
local failures=0
|
|
|
|
# Offline seam: treat refs listed in _PUBLISHED as already published, so the
|
|
# compute_build_set tests need no registry. Visible to _image_published via
|
|
# bash dynamic scoping.
|
|
local _PUBLISHED=""
|
|
_image_published() {
|
|
case " ${_PUBLISHED} " in
|
|
*" $1 "*) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
local CI_IMAGES_FIX='{
|
|
"ubuntu-nightly":{"ci_image":"reg/ubuntu:nightly","ci_image_nvidia":"reg/ubuntu:nightly-nvidia"},
|
|
"rocky-nightly":{"ci_image":"reg/rocky:nightly","ci_image_nvidia":"reg/rocky:nightly-nvidia"}
|
|
}'
|
|
local FULL='{"include":[{"supported_platforms":"ubuntu","rocm_versions":"7.2.2"},{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}'
|
|
local TWO_NIGHTLY='{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"},{"supported_platforms":"rocky","rocm_versions":"nightly"}]}'
|
|
|
|
echo "Test 1: filter_nightly_rows keeps only nightly rows"
|
|
_assert_eq " output" \
|
|
"$(filter_nightly_rows "${FULL}")" \
|
|
'{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 2: filter_nightly_rows with no nightly row -> empty"
|
|
_assert_eq " output" \
|
|
"$(filter_nightly_rows '{"include":[{"supported_platforms":"ubuntu","rocm_versions":"7.2.2"}]}')" \
|
|
'{"include":[]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 3: select_to_build keeps only rows whose key is in to_build"
|
|
_assert_eq " output" \
|
|
"$(select_to_build "${TWO_NIGHTLY}" 'rocky-nightly')" \
|
|
'{"include":[{"supported_platforms":"rocky","rocm_versions":"nightly"}]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 4: select_to_build with empty to_build -> empty"
|
|
_assert_eq " output" \
|
|
"$(select_to_build "${TWO_NIGHTLY}" '')" \
|
|
'{"include":[]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 5: select_to_build ignores keys not in the candidate set"
|
|
_assert_eq " output" \
|
|
"$(select_to_build '{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}' 'rocky-nightly')" \
|
|
'{"include":[]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 6: compute_build_set with Dockerfile change -> full catalog"
|
|
_PUBLISHED="reg/ubuntu:nightly reg/ubuntu:nightly-nvidia"
|
|
_assert_eq " output" \
|
|
"$(compute_build_set "1" "${FULL}" "${CI_IMAGES_FIX}")" \
|
|
"${FULL}" || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 7: compute_build_set, nightly fully published -> empty (skip)"
|
|
_PUBLISHED="reg/ubuntu:nightly reg/ubuntu:nightly-nvidia"
|
|
_assert_eq " output" \
|
|
"$(compute_build_set "0" "${FULL}" "${CI_IMAGES_FIX}")" \
|
|
'{"include":[]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 8: compute_build_set, nightly base missing -> build it"
|
|
_PUBLISHED="reg/ubuntu:nightly-nvidia"
|
|
_assert_eq " output" \
|
|
"$(compute_build_set "0" "${FULL}" "${CI_IMAGES_FIX}")" \
|
|
'{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 9: compute_build_set, nightly nvidia missing -> build it"
|
|
_PUBLISHED="reg/ubuntu:nightly"
|
|
_assert_eq " output" \
|
|
"$(compute_build_set "0" "${FULL}" "${CI_IMAGES_FIX}")" \
|
|
'{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
echo "Test 10: compute_build_set, two nightly rows, only the unpublished one is built"
|
|
_PUBLISHED="reg/rocky:nightly reg/rocky:nightly-nvidia"
|
|
_assert_eq " output" \
|
|
"$(compute_build_set "0" "${TWO_NIGHTLY}" "${CI_IMAGES_FIX}")" \
|
|
'{"include":[{"supported_platforms":"ubuntu","rocm_versions":"nightly"}]}' || failures=$((failures+1))
|
|
|
|
echo
|
|
if [ "${failures}" -eq 0 ]; then
|
|
echo "All tests passed."
|
|
else
|
|
echo "${failures} test(s) FAILED."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# --- dispatch -------------------------------------------------------------
|
|
# When sourced, ${BASH_SOURCE[0]} (this file) differs from ${0} (the caller's
|
|
# shell); when executed they are equal. So "!=" means "we are being sourced".
|
|
# Do NOT set shell options at top level: sourcing must not mutate the caller.
|
|
if [ "${BASH_SOURCE[0]}" != "${0}" ]; then
|
|
# SC2034: build_CI_images_matrix is consumed by the sourcing CI step.
|
|
# SC2153: the UPPER_CASE names are CI env vars, not typos of the lowercase args.
|
|
# shellcheck disable=SC2034,SC2153
|
|
build_CI_images_matrix=$(compute_build_set "${CHANGED_DOCKERFILE}" "${FULL_CI_IMAGES_MATRIX}" "${CI_IMAGES}")
|
|
else
|
|
case "${1:-}" in
|
|
--test) _run_tests ;;
|
|
*) echo "usage: source build-ci-images-matrix.sh | bash build-ci-images-matrix.sh --test" >&2; exit 2 ;;
|
|
esac
|
|
fi
|