Skip to content

Unify track-spack-packages detection around packages/files matrix i… #4

Unify track-spack-packages detection around packages/files matrix i…

Unify track-spack-packages detection around packages/files matrix i… #4

name: Track spack-packages updates
on:
schedule:
- cron: '17 6 * * 1'
workflow_dispatch:
inputs:
target:
description: 'Matrix entry to run (all = every entry)'
required: false
default: all
type: choice
options:
- all
- shared-ci
- cached-cmake
permissions:
contents: read
issues: write
jobs:
track:
name: Track ${{ matrix.name }}
runs-on: ubuntu-latest
if: >-
github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch'
&& (inputs.target == 'all' || inputs.target == matrix.name))
strategy:
fail-fast: false
matrix:
include:
# Watch a curated list of packages used by this env.
- name: shared-ci
spack_yaml: .gitlab/spack/envs/shared-ci/spack.yaml
packages: |
camp
umpire
raja
raja-perf
chai
care
caliper
# Watch a specific upstream file.
- name: cached-cmake
spack_yaml: .gitlab/spack/envs/cached-cmake/spack.yaml
files: |
repos/spack_repo/builtin/build_systems/cached_cmake.py
env:
SPACK_PACKAGES_REPO: https://github.com/spack/spack-packages.git
SPACK_YAML: ${{ matrix.spack_yaml }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Resolve current and latest spack-packages commits
id: commits
shell: bash
run: |
set -euo pipefail
# Read the upstream pin from spack.repos.builtin.commit.
# Spack stores full 40-character SHA-1 hashes here.
CURRENT_COMMIT=$(yq '.spack.repos.builtin.commit' "${SPACK_YAML}")
if [[ -z "${CURRENT_COMMIT}" || "${CURRENT_COMMIT}" == "null" ]]; then
echo "Missing .spack.repos.builtin.commit in ${SPACK_YAML}." >&2
exit 1
fi
if ! [[ "${CURRENT_COMMIT}" =~ ^[0-9a-f]{40}$ ]]; then
echo "Invalid commit hash in ${SPACK_YAML}: ${CURRENT_COMMIT}" >&2
exit 1
fi
SPACK_PACKAGES_DIR="${RUNNER_TEMP}/spack-packages"
git clone "${SPACK_PACKAGES_REPO}" "${SPACK_PACKAGES_DIR}"
DEFAULT_BRANCH=$(git -C "${SPACK_PACKAGES_DIR}" remote show origin \
| sed -n '/HEAD branch/s/.*: //p')
if [[ -z "${DEFAULT_BRANCH}" ]]; then
echo "Unable to determine default branch of ${SPACK_PACKAGES_REPO}." >&2
exit 1
fi
LATEST_COMMIT=$(git -C "${SPACK_PACKAGES_DIR}" rev-parse "origin/${DEFAULT_BRANCH}")
if [[ -z "${LATEST_COMMIT}" || ! "${LATEST_COMMIT}" =~ ^[0-9a-f]{40}$ ]]; then
echo "Unable to resolve latest commit on ${DEFAULT_BRANCH}." >&2
exit 1
fi
LATEST_COMMIT_SHORT=$(git -C "${SPACK_PACKAGES_DIR}" rev-parse --short=12 "${LATEST_COMMIT}")
echo "current_commit=${CURRENT_COMMIT}" >> "${GITHUB_OUTPUT}"
echo "latest_commit=${LATEST_COMMIT}" >> "${GITHUB_OUTPUT}"
echo "latest_commit_short=${LATEST_COMMIT_SHORT}" >> "${GITHUB_OUTPUT}"
- name: Resolve watched paths
id: paths
shell: bash
env:
PACKAGES: ${{ matrix.packages }}
FILES: ${{ matrix.files }}
run: |
set -euo pipefail
PACKAGES_PREFIX="repos/spack_repo/builtin/packages"
WATCHED_PATHS_FILE="${RUNNER_TEMP}/watched_paths.txt"
: > "${WATCHED_PATHS_FILE}"
# Each watched package becomes its upstream directory.
# Spack maps hyphens to underscores (raja-perf -> raja_perf).
while IFS= read -r PKG; do
[[ -z "${PKG// /}" ]] && continue
echo "${PACKAGES_PREFIX}/${PKG//-/_}" >> "${WATCHED_PATHS_FILE}"
done <<< "${PACKAGES:-}"
# Literal files under spack-packages.
while IFS= read -r FILE; do
[[ -z "${FILE// /}" ]] && continue
echo "${FILE}" >> "${WATCHED_PATHS_FILE}"
done <<< "${FILES:-}"
if [[ ! -s "${WATCHED_PATHS_FILE}" ]]; then
echo "Matrix entry declared neither packages nor files." >&2
exit 1
fi
echo "Watched paths:"
cat "${WATCHED_PATHS_FILE}"
- name: Detect relevant upstream changes
id: detect
shell: bash
env:
CURRENT_COMMIT: ${{ steps.commits.outputs.current_commit }}
LATEST_COMMIT: ${{ steps.commits.outputs.latest_commit }}
run: |
set -euo pipefail
SPACK_PACKAGES_DIR="${RUNNER_TEMP}/spack-packages"
WATCHED_PATHS_FILE="${RUNNER_TEMP}/watched_paths.txt"
CHANGED_PATHS_FILE="${RUNNER_TEMP}/changed-paths.txt"
DIFF_FILE="${RUNNER_TEMP}/spack-packages-diff.txt"
: > "${CHANGED_PATHS_FILE}"
: > "${DIFF_FILE}"
if [[ "${CURRENT_COMMIT}" == "${LATEST_COMMIT}" ]]; then
echo "should_update=false" >> "${GITHUB_OUTPUT}"
echo "reason=already_up_to_date" >> "${GITHUB_OUTPUT}"
exit 0
fi
readarray -t WATCH < "${WATCHED_PATHS_FILE}"
if ! git -C "${SPACK_PACKAGES_DIR}" rev-parse --verify --quiet "${CURRENT_COMMIT}^{commit}" >/dev/null; then
echo "Current commit ${CURRENT_COMMIT} not in upstream history; forcing update." >&2
echo "should_update=true" >> "${GITHUB_OUTPUT}"
echo "reason=current_commit_not_found" >> "${GITHUB_OUTPUT}"
exit 0
fi
CHANGED=$(git -C "${SPACK_PACKAGES_DIR}" diff --name-only \
"${CURRENT_COMMIT}..${LATEST_COMMIT}" -- "${WATCH[@]}")
if [[ -z "${CHANGED}" ]]; then
echo "should_update=false" >> "${GITHUB_OUTPUT}"
echo "reason=no_relevant_changes" >> "${GITHUB_OUTPUT}"
exit 0
fi
# Surface which watched paths actually changed (file or prefix match).
TRACKED_AND_CHANGED=()
for W in "${WATCH[@]}"; do
while IFS= read -r C; do
if [[ "${C}" == "${W}" || "${C}" == "${W}/"* ]]; then
TRACKED_AND_CHANGED+=("${W}")
break
fi
done <<< "${CHANGED}"
done
printf '%s\n' "${TRACKED_AND_CHANGED[@]}" > "${CHANGED_PATHS_FILE}"
git -C "${SPACK_PACKAGES_DIR}" diff "${CURRENT_COMMIT}..${LATEST_COMMIT}" \
-- "${TRACKED_AND_CHANGED[@]}" > "${DIFF_FILE}"
echo "should_update=true" >> "${GITHUB_OUTPUT}"
echo "reason=relevant_changes_found" >> "${GITHUB_OUTPUT}"
- name: Create issue
if: steps.detect.outputs.should_update == 'true'
env:
GH_TOKEN: ${{ github.token }}
CURRENT_COMMIT: ${{ steps.commits.outputs.current_commit }}
LATEST_COMMIT: ${{ steps.commits.outputs.latest_commit }}
LATEST_COMMIT_SHORT: ${{ steps.commits.outputs.latest_commit_short }}
MATRIX_NAME: ${{ matrix.name }}
run: |
set -euo pipefail
CHANGED_PATHS_FILE="${RUNNER_TEMP}/changed-paths.txt"
DIFF_FILE="${RUNNER_TEMP}/spack-packages-diff.txt"
if [[ ! -s "${CHANGED_PATHS_FILE}" ]]; then
CHANGED_SECTION="_Could not determine changed paths (current commit not found in upstream history)._"
else
CHANGED_SECTION=""
while IFS= read -r P; do
CHANGED_SECTION+="- \`${P}\`"$'\n'
done < "${CHANGED_PATHS_FILE}"
fi
DIFF_CONTENT=$(cat "${DIFF_FILE}")
if [[ -z "${DIFF_CONTENT}" ]]; then
DIFF_SECTION="_Diff unavailable (current commit not found in upstream history)._"
else
# GitHub issue bodies are capped at 65536 characters; leave headroom
# for surrounding markdown by truncating the diff earlier.
MAX_DIFF_CHARS=60000
if [[ "${#DIFF_CONTENT}" -gt "${MAX_DIFF_CHARS}" ]]; then
DIFF_CONTENT="${DIFF_CONTENT:0:${MAX_DIFF_CHARS}}"$'\n'"... _(truncated, diff exceeds ${MAX_DIFF_CHARS} characters)_"
fi
DIFF_SECTION='```diff'$'\n'"${DIFF_CONTENT}"$'\n''```'
fi
ISSUE_BODY="Automated weekly check detected relevant changes in \`spack/spack-packages\` for **${MATRIX_NAME}**.
## spack-packages references
| | Commit |

Check failure on line 228 in .github/workflows/track-spack-packages.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/track-spack-packages.yml

Invalid workflow file

You have an error in your yaml syntax on line 228
|---|---|
| Current | \`${CURRENT_COMMIT}\` |
| New | \`${LATEST_COMMIT}\` |
## Changed paths
${CHANGED_SECTION}
## Diff
Changes in \`spack/spack-packages\` from \`${CURRENT_COMMIT}\` to \`${LATEST_COMMIT}\`:
${DIFF_SECTION}"
gh issue create \
--repo "${GITHUB_REPOSITORY}" \
--title "[${MATRIX_NAME}] Update spack-packages reference to ${LATEST_COMMIT_SHORT}" \
--body "${ISSUE_BODY}" \
--label "dependencies" \
--label "automation"
- name: Log decision
if: steps.detect.outputs.should_update != 'true'
run: |
echo "No issue created. Reason: ${{ steps.detect.outputs.reason }}"