Skip to content

Identifier identity and validation, DPoP htu ;params, verbatim PRM hooks, pinned conformance catalog #13

Identifier identity and validation, DPoP htu ;params, verbatim PRM hooks, pinned conformance catalog

Identifier identity and validation, DPoP htu ;params, verbatim PRM hooks, pinned conformance catalog #13

name: Release tooling
# Catches workflow YAML / shell-in-`run:` regressions at PR time so a
# typo can't reach a release tag and surface only when a publish run
# fails. The shell scripts under scripts/ are in the same category — a
# break in them surfaces only when someone reaches for them after a
# release, which is the worst moment to discover it — so they are linted
# and tested here too. Scoped to those two paths to keep CI overhead off
# unrelated PRs.
#
# The scripts trigger is `scripts/**`, not `scripts/*.sh`: a single-level
# glob would leave a future scripts/lib/*.sh both untriggered here and
# unlinted below, in each case silently.
on:
pull_request:
paths:
- ".github/workflows/**"
- "scripts/**"
push:
branches:
- main
paths:
- ".github/workflows/**"
- "scripts/**"
permissions:
contents: read
jobs:
actionlint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Pulls the matching actionlint binary release from GitHub Releases
# via the upstream download script. The script is fetched by commit
# SHA (not a mutable tag) and sha256-verified before it runs — this
# closes Scorecard's "downloadThenRun not pinned by hash" gap. The
# script then checksum-verifies the actionlint binary it pulls from
# the matching release.
#
# To bump: change ACTIONLINT_VERSION, set ACTIONLINT_SCRIPT_SHA to the
# commit the new tag points at (`gh api repos/rhysd/actionlint/commits/vX.Y.Z -q .sha`),
# and update ACTIONLINT_SCRIPT_SHA256 to that file's sha256.
#
# Install dir is passed explicitly as the script's second positional
# arg so the workflow doesn't couple to the script's internal default
# of $PWD (which happens to be $GITHUB_WORKSPACE after checkout —
# a coincidence, not a contract).
- name: Install actionlint
env:
ACTIONLINT_VERSION: "1.7.7"
ACTIONLINT_SCRIPT_SHA: "03d0035246f3e81f36aed592ffb4bebf33a03106"
ACTIONLINT_SCRIPT_SHA256: "221d1d16c03e4e4fcd867de34104e8d479bdce20ccdfa553b9a5c0dc29bf6af2"
ACTIONLINT_INSTALL_DIR: ${{ runner.temp }}/actionlint
run: |
mkdir -p "${ACTIONLINT_INSTALL_DIR}"
script="${ACTIONLINT_INSTALL_DIR}/download-actionlint.bash"
curl -fsSL -o "${script}" \
"https://raw.githubusercontent.com/rhysd/actionlint/${ACTIONLINT_SCRIPT_SHA}/scripts/download-actionlint.bash"
echo "${ACTIONLINT_SCRIPT_SHA256} ${script}" | sha256sum -c -
bash "${script}" "${ACTIONLINT_VERSION}" "${ACTIONLINT_INSTALL_DIR}"
echo "${ACTIONLINT_INSTALL_DIR}" >> "${GITHUB_PATH}"
"${ACTIONLINT_INSTALL_DIR}/actionlint" -version
# Both steps below resolve `shellcheck` off the runner image's $PATH —
# actionlint via `-shellcheck=shellcheck`, the script lint directly.
# Asserting it once, up front, is what makes that dependency explicit:
# naming the binary in actionlint's flag only changes which lookup
# fails, and neither step announces the version it linted with. If the
# Ubuntu image ever drops shellcheck, this fails first and says so,
# rather than actionlint quietly degrading to no shell analysis.
- name: Check shellcheck is available
run: shellcheck --version
- name: Run actionlint
run: actionlint -color -shellcheck=shellcheck
- name: Shellcheck the release scripts
# find, not `scripts/*.sh`: the single-level glob would silently skip
# a future scripts/lib/*.sh, the same blind spot the path trigger had.
# An empty result is an error rather than a green no-op, so a moved or
# renamed directory cannot pass as a clean lint.
run: |
mapfile -d '' -t sh_files < <(find scripts -type f -name '*.sh' -print0)
if [[ ${#sh_files[@]} -eq 0 ]]; then
echo "error: no shell scripts found under scripts/" >&2
exit 1
fi
printf 'shellcheck: %s\n' "${sh_files[@]}"
shellcheck "${sh_files[@]}"
# backport-fixes.sh accepts a branch or a tag as --from, and only the
# branch form has a remote-tracking ref. The tag form is what the release
# flow tells you to use once release.yml has deleted the branch, so it is
# the form least likely to be exercised before it is needed.
- name: Test backport-fixes.sh
run: scripts/backport-fixes.test.sh