diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 8a660f5..c157436 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -56,7 +56,8 @@ workflows: - 'hyperpolymath/standards@8f2ee50841e216cd8c192eeb68953118190f105c' '.github/workflows/security-policy.yml': - 'actions/checkout@v7.0.1' - '.github/workflows/standards-pipeline.yml': [] + '.github/workflows/standards-pipeline.yml': + - 'hyperpolymath/standards@2eb9bb19d43b6285466ca36b92d1324a09e7a207' '.github/workflows/static-analysis-gate.yml': - 'actions/checkout@v7.0.1' - 'actions/download-artifact@v8.0.1' @@ -67,11 +68,6 @@ workflows: '.github/workflows/workflow-linter.yml': - 'actions/checkout@v7.0.1' dependencies: - 'Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6': - ref: '6323deb102c322ba6fcbdcafc7e3dddab59af2b6' - commit: 'sha1-6323deb102c322ba6fcbdcafc7e3dddab59af2b6' - owner_id: 580492 - repo_id: 298565987 'actions/attest-build-provenance@v4.2.2': ref: 'v4.2.2' commit: 'sha1-4d101475d8b20a2381f78447822ac1eab6504dd8' @@ -176,11 +172,31 @@ dependencies: commit: 'sha1-abea47f85e598557f500fa1fd2ab7464fcb39406' owner_id: 1006268 repo_id: 212984112 + 'haskell-actions/setup@6037f33647c3f17758a2356c80fc4a53d7e0685d': + ref: '6037f33647c3f17758a2356c80fc4a53d7e0685d' + commit: 'sha1-6037f33647c3f17758a2356c80fc4a53d7e0685d' + owner_id: 75048950 + repo_id: 623796603 'hyperpolymath/smtp-notify-action@v0.3.0': ref: 'v0.3.0' commit: 'sha1-22e7bdb322c430c1d0dac6b3bb307f4bb139d0be' owner_id: 6759885 repo_id: 1352485172 + 'hyperpolymath/standards@2eb9bb19d43b6285466ca36b92d1324a09e7a207': + ref: '2eb9bb19d43b6285466ca36b92d1324a09e7a207' + commit: 'sha1-2eb9bb19d43b6285466ca36b92d1324a09e7a207' + owner_id: 6759885 + repo_id: 1116521501 + uses: + - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1' + - 'haskell-actions/setup@6037f33647c3f17758a2356c80fc4a53d7e0685d' + - 'hyperpolymath/standards@571cc734cd69fb846032ec77a662aa8ee4fc32cd' + - 'oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6' + 'hyperpolymath/standards@571cc734cd69fb846032ec77a662aa8ee4fc32cd': + ref: '571cc734cd69fb846032ec77a662aa8ee4fc32cd' + commit: 'sha1-571cc734cd69fb846032ec77a662aa8ee4fc32cd' + owner_id: 6759885 + repo_id: 1116521501 'hyperpolymath/standards@8f2ee50841e216cd8c192eeb68953118190f105c': ref: '8f2ee50841e216cd8c192eeb68953118190f105c' commit: 'sha1-8f2ee50841e216cd8c192eeb68953118190f105c' @@ -193,7 +209,7 @@ dependencies: - 'editorconfig-checker/action-editorconfig-checker@51f63319f592f97930c73d9c46184d20bd206393' - 'erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124' - 'goto-bus-stop/setup-zig@abea47f85e598557f500fa1fd2ab7464fcb39406' - - 'Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6' + - 'swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6' - 'webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555' 'hyperpolymath/standards@da2c748aad55c1a1dcba00b60fe4a35017bc6540': ref: 'da2c748aad55c1a1dcba00b60fe4a35017bc6540' @@ -212,6 +228,11 @@ dependencies: commit: 'sha1-2d1146689b8cda280b9bc96326124645441f03bc' owner_id: 67707773 repo_id: 421101922 + 'oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6': + ref: '0c5077e51419868618aeaa5fe8019c62421857d6' + commit: 'sha1-0c5077e51419868618aeaa5fe8019c62421857d6' + owner_id: 108928776 + repo_id: 512644635 'softprops/action-gh-release@v3.0.3': ref: 'v3.0.3' commit: 'sha1-efb35369e0ad2afab669f228072c1b0d510eae64' @@ -222,6 +243,11 @@ dependencies: commit: 'sha1-fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594' owner_id: 88700172 repo_id: 422287306 + 'swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6': + ref: '6323deb102c322ba6fcbdcafc7e3dddab59af2b6' + commit: 'sha1-6323deb102c322ba6fcbdcafc7e3dddab59af2b6' + owner_id: 580492 + repo_id: 298565987 'webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555': ref: 'e83874834305fe9a4a2997156cb26c5de65a8555' commit: 'sha1-e83874834305fe9a4a2997156cb26c5de65a8555' diff --git a/.github/workflows/lock-sync-gate.yml b/.github/workflows/lock-sync-gate.yml index b7da1b6..936c873 100644 --- a/.github/workflows/lock-sync-gate.yml +++ b/.github/workflows/lock-sync-gate.yml @@ -1,5 +1,4 @@ # SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. name: Lock Sync Gate # Fails any pull request whose .github/workflows/actions.lock has drifted from diff --git a/scripts/check-lock-sync.sh b/scripts/check-lock-sync.sh index 977f893..6ab01cc 100755 --- a/scripts/check-lock-sync.sh +++ b/scripts/check-lock-sync.sh @@ -70,16 +70,14 @@ if [ ! -f "$LOCK" ]; then fi shopt -s nullglob -WORKFLOWS=("$WF_DIR"/*.yml "$WF_DIR"/*.yaml) -if [[ "${#WORKFLOWS[@]}" -eq 0 ]]; then +mapfile -t WORKFLOWS < <(printf '%s\n' "$WF_DIR"/*.yml "$WF_DIR"/*.yaml | sort -u) +if [ "${#WORKFLOWS[@]}" -eq 0 ]; then echo "check-lock-sync: FATAL: no workflow files under $WF_DIR" >&2 exit 1 fi read -r -d '' PROG <<'AWK' || true -# Normalise an external `uses:` reference to owner/repository@ref, -# discarding any action subpath. Return an empty string for local actions or -# values without a repository path and ref. +# owner/repo[/subpath...]@ref -> owner/repo@ref ("" if not an external ref) function norm(r, at, path, ref, n, parts) { at = 0 for (n = length(r); n > 0; n--) { if (substr(r, n, 1) == "@") { at = n; break } } @@ -91,6 +89,20 @@ function norm(r, at, path, ref, n, parts) { return parts[1] "/" parts[2] "@" ref } +# Fold case on the OWNER/REPO segment only, for comparison keys. GitHub resolves +# owner and repository names case-insensitively, and this is measured, not assumed: +# metadatastician/pong-ping's lockfile records sonarsource/sonarqube-scan-action@v8.2.1 +# while sonarqube.yml says SonarSource/..., and at commit cd5f90f that workflow ran +# SUCCESS while codeql.yml at the SAME commit was startup_failure. A same-commit +# control, so the case difference is provably not what kills a run. +# The REF is NOT folded: git tags and branch names are case-sensitive. +function ck(r, at, s) { + at = 0 + for (s = length(r); s > 0; s--) { if (substr(r, s, 1) == "@") { at = s; break } } + if (at == 0) return tolower(r) + return tolower(substr(r, 1, at - 1)) substr(r, at) +} + # ---------- pass 1: the lockfile ---------- FILENAME == lockfile { if ($0 ~ /^workflows:[[:space:]]*$/) { inwf = 1; indep = 0; next } @@ -102,12 +114,12 @@ FILENAME == lockfile { # " 'owner/repo@ref':" -- a top-level dependency record if (match($0, /^ '([^']+)':/, m)) { depkey = m[1] - haverec[depkey] = 1 + haverec[ck(depkey)] = 1; disp[ck(depkey)] = depkey next } # " - 'owner/repo@ref'" -- a nested uses: of that record if (match($0, /^ - '([^']+)'/, m) && depkey != "") { - r = m[1] + r = ck(m[1]); disp[r] = m[1] want[r] = 1 wantsrc[r] = wantsrc[r] " dependencies:" depkey next @@ -124,10 +136,10 @@ FILENAME == lockfile { next } if (match($0, /^ - '([^']+)'[[:space:]]*$/, m) && cur != "") { - lock[cur, m[1]] = 1 + lr = ck(m[1]); disp[lr] = m[1]; lock[cur, lr] = 1 lockcount[cur]++ - want[m[1]] = 1 # clause 3: this must resolve too - wantsrc[m[1]] = wantsrc[m[1]] " " cur + want[lr] = 1 + wantsrc[lr] = wantsrc[lr] " " cur next } next @@ -144,7 +156,7 @@ FNR == 1 { wf = FILENAME } gsub(/[[:space:]]+$/, "", raw) if (raw ~ /^\$\//) { dollar[wf] = dollar[wf] " " raw; next } # known corruption n = norm(raw) - if (n != "") { uses[wf, n] = 1; useslist[wf] = useslist[wf] " " n } + if (n != "") { uses[wf, ck(n)] = 1; useslist[wf] = useslist[wf] " " n } } } @@ -168,7 +180,7 @@ END { for (j = 1; j <= nu; j++) { if (u[j] == "" || (u[j] in uniq)) continue uniq[u[j]] = 1 - if (!((key SUBSEP u[j]) in lock)) missing = missing " " u[j] + if (!((key SUBSEP ck(u[j])) in lock)) missing = missing " " u[j] } if (missing != "") { if (!(key in seen_path)) @@ -183,7 +195,7 @@ END { for (k in lock) { split(k, kp, SUBSEP) if (kp[1] != key) continue - if (!((wf SUBSEP kp[2]) in uses)) orphan = orphan " " kp[2] + if (!((wf SUBSEP kp[2]) in uses)) orphan = orphan " " (kp[2] in disp ? disp[kp[2]] : kp[2]) } if (orphan != "") { printf "FAIL %s\n stale lockfile entries, no uses: references them:%s\n", key, orphan @@ -210,7 +222,7 @@ END { if (r !~ /^[^\/]+\/[^\/@]+@/) continue # not an OWNER/REPO@REF pin; not ours to resolve if (r in haverec) continue ndang++ - dang = dang sprintf("\n %s\n named by:%s", r, wantsrc[r]) + dang = dang sprintf("\n %s\n named by:%s", (r in disp ? disp[r] : r), wantsrc[r]) } if (ndang > 0) { printf "FAIL actions.lock: DANGLING EDGES\n"