Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dependabot-lock-regen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
sudo apt-get install -y -qq gawk >/dev/null
gh extension install github/gh-actions-lock --pin v0.1.6
gh extension install github/gh-actions-lock --pin v0.2.0

- name: Regenerate Dependabot PR lockfiles
env:
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/governance-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1491,8 +1491,13 @@ jobs:
# refs made GitHub's native resolver accept them again.
if [ -f .github/workflows/actions.lock ]; then
# Pinned: an unpinned install let a new verifier release change every
# caller's verdict overnight. Bump deliberately, with the gate tests.
gh extension install github/gh-actions-lock --pin v0.1.6
# caller's verdict overnight. Bump deliberately, with the gate tests:
# scripts/tests/gh-actions-lock-contract-test.sh runs the real
# binary and requires every pin in .github/workflows/ to agree.
# v0.2.0, not v0.1.6: v0.1.6 refuses to read a lockfile v0.0.3,
# which every current `gh actions-lock` writes, so a lock refreshed
# on an upgraded laptop failed this gate (proof-burrower#112).
gh extension install github/gh-actions-lock --pin v0.2.0
fi

# The gate delegates lockfile verification to the authoritative
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scorecard-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh extension install github/gh-actions-lock --pin v0.1.6
gh extension install github/gh-actions-lock --pin v0.2.0
# Exit 3: the reconciled SARIF was written, but some workflows failed
# native lock verification and keep their findings. Exit 2: usage or
# SARIF-structure error, nothing written. The code is passed on so
Expand Down Expand Up @@ -219,7 +219,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
gh extension install github/gh-actions-lock --pin v0.1.6
gh extension install github/gh-actions-lock --pin v0.2.0
# Exit 3: the reconciled SARIF was written, but some workflows failed
# native lock verification and keep their findings. Exit 2: usage or
# SARIF-structure error, nothing written. The code is passed on so
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/self-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ jobs:
- name: Install ijson-jcs
run: cargo install --git https://github.com/hyperpolymath/ijson-jcs --rev 0fdeea716fd558e9807362acf6f8202d56d8d88f --locked ijson-jcs

# scripts/tests/gh-actions-lock-contract-test.sh runs the real binary; it
# exits 2 without it. The version must match every `--pin` in this tree
# (the test fails when they disagree); the hash is the release asset's.
- name: Install gh-actions-lock
run: |
set -euo pipefail
curl -sSfL --proto '=https' --proto-redir '=https' --tlsv1.2 --retry 3 -o "$RUNNER_TEMP/gh-actions-lock" https://github.com/github/gh-actions-lock/releases/download/v0.2.0/linux-amd64
echo "79ec84c191667fd935a277e6fd3662cf5d3669cccc9e99998731d8f306f373b6 $RUNNER_TEMP/gh-actions-lock" | sha256sum --check
chmod u+x "$RUNNER_TEMP/gh-actions-lock"
echo "GH_ACTIONS_LOCK_BIN=$RUNNER_TEMP/gh-actions-lock" >> "$GITHUB_ENV"

- name: Run tests/*.sh and scripts/tests/*.sh
run: bash scripts/run-shell-test-suite.sh

Expand Down
2 changes: 1 addition & 1 deletion scripts/check-lock-sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#
# Why this exists rather than `gh actions-lock --verify-local` alone:
# `gh actions-lock` v0.1.6 cannot see a job-level `uses:` (a reusable-workflow
# call). Measured on this repo, 2026-09-22:
# call); v0.2.0 still cannot (re-measured 2026-10-14). Measured on this repo, 2026-09-22:
# * mirror.yml's lock entry was stale by a whole SHA and died at startup with
# jobs=0, yet --verify-local reported "All 30 workflows have complete
# lockfile coverage" and fix mode did not repair it;
Expand Down
3 changes: 2 additions & 1 deletion scripts/complete-job-refs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#
# complete-job-refs.sh — add job-level reusable-workflow refs, and the refs a
# workflow uses through its local composite actions, to actions.lock.
# `gh actions-lock` v0.1.6 is blind to job-level `uses:` (upstream #129), so the
# `gh actions-lock` v0.1.6 is blind to job-level `uses:` (upstream #129; v0.2.0
# still is, re-measured 2026-10-14), so the
# entries it cannot write are written here. Idempotent; run from a repo root.
#
# Lock repair order (each step idempotent, run from a repo root):
Expand Down
206 changes: 206 additions & 0 deletions scripts/tests/gh-actions-lock-contract-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
#
# The contract the estate's lock tooling needs from the REAL gh-actions-lock
# binary, checked against the one version every workflow here pins. The other
# lock tests stub `gh`; this one is what makes a pin bump deliberate.
#
# 1. Every gh-actions-lock pin in .github/workflows/ names the same version,
# and the binary under test is that version.
# 2. It reads lockfile v0.0.2 and v0.0.3. v0.1.6 refused v0.0.3, which every
# current `gh actions-lock` writes, so one lock refreshed on an upgraded
# laptop failed every reader pinned to v0.1.6 (proof-burrower#112).
# 3. A lockfile newer than the binary is refused loudly, never read as valid.
# 4. `--verify-local --json=valid,findings` prints one object with a boolean
# `valid` and a `findings` array, and names the categories that
# scripts/update-actions-lock.sh and reconcile-scorecard-actions-lock.rb
# key on: sha-as-ref, ref-changed, stale (dangling) and stale (a
# reusable-workflow dependency the tool cannot see).
# 5. scripts/update-actions-lock.sh --verify-local, driving the real binary,
# accepts the three v0.2.0 false positives (reusable-workflow `stale`,
# `not-pinned` for a workflow with nothing to pin, `local-action` for a
# ./ action present in the checkout) and rejects a real desync, an
# unlisted workflow with a remote action, and a missing ./ action.
#
# Offline: --verify-local makes no network call. Needs the binary in
# $GH_ACTIONS_LOCK_BIN (self-test.yml downloads the pinned release and checks
# its SHA-256) and mikefarah yq v4 on PATH. Exit 2 when it cannot run.
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT

pass=0; fail=0
ok() { pass=$((pass+1)); echo " ok $1"; }

Check warning on line 33 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem01&open=AaE52lxDt0UEoTYzem01&pullRequest=1250
bad() { fail=$((fail+1)); echo " FAIL $1"; }

Check warning on line 34 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem02&open=AaE52lxDt0UEoTYzem02&pullRequest=1250

BIN="${GH_ACTIONS_LOCK_BIN:-}"
if [ -z "$BIN" ] || [ ! -x "$BIN" ]; then

Check failure on line 37 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem04&open=AaE52lxDt0UEoTYzem04&pullRequest=1250

Check failure on line 37 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem03&open=AaE52lxDt0UEoTYzem03&pullRequest=1250
echo "gh-actions-lock-contract-test: set GH_ACTIONS_LOCK_BIN to the pinned gh-actions-lock binary" >&2
exit 2
fi
yq --version 2>/dev/null | grep -q 'mikefarah/yq' || {
echo "gh-actions-lock-contract-test: mikefarah yq v4 is required" >&2; exit 2; }

CHECKOUT=3d3c42e5aac5ba805825da76410c181273ba90b1
UPLOAD_OLD=043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
STANDARDS=8f2ee50841e216cd8c192eeb68953118190f105c

echo "1. one pinned version"
mapfile -t pins < <(grep -rhoE 'gh-actions-lock --pin v[0-9]+\.[0-9]+\.[0-9]+|gh-actions-lock/releases/download/v[0-9]+\.[0-9]+\.[0-9]+/' \
"$ROOT/.github/workflows" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | sort -u)
if [ "${#pins[@]}" -eq 1 ]; then ok "every workflow pins ${pins[0]}"

Check failure on line 51 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem05&open=AaE52lxDt0UEoTYzem05&pullRequest=1250
else bad "workflows pin ${#pins[@]} versions: ${pins[*]:-none}"; fi
PIN="${pins[0]:-none}"
version="$("$BIN" --version 2>&1)"
if [[ "$version" == *" $PIN" ]]; then ok "the binary under test is $PIN"
else bad "the binary under test reports '$version', not $PIN"; fi

# A repository with one workflow and its lock. <variant> picks the workflow:
# clean — one locked tag ref, nothing else
# reusable — clean plus a SHA ref and a reusable-workflow call
# desync — reusable, but the tag was bumped without relocking
fixture() { # fixture <dir> <lock-version> <variant>

Check warning on line 62 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem0_&open=AaE52lxDt0UEoTYzem0_&pullRequest=1250
local d=$1 v=$2 variant=$3 upload=v7.0.1
rm -rf "$d"; mkdir -p "$d/.github/workflows"; git -C "$d" init -q
[ "$variant" = desync ] && upload=v7.0.2

Check failure on line 65 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem06&open=AaE52lxDt0UEoTYzem06&pullRequest=1250
{
printf '# SPDX-License-Identifier: MPL-2.0\non: push\npermissions: read-all\njobs:\n'
printf ' a:\n runs-on: ubuntu-latest\n steps:\n'
printf ' - uses: actions/upload-artifact@%s\n' "$upload"
if [ "$variant" != clean ]; then

Check failure on line 70 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem07&open=AaE52lxDt0UEoTYzem07&pullRequest=1250
printf ' - uses: actions/checkout@%s\n' "$CHECKOUT"
printf ' r:\n uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@%s\n' "$STANDARDS"
fi
} > "$d/.github/workflows/ci.yml"
{
printf "# This file is machine-generated by \`gh actions-lock\`.\n"
printf "# Do not edit by hand; run \`gh actions-lock\` to update.\n"
printf "# Docs: https://gh.io/actions-lockfile\nversion: '%s'\nworkflows:\n" "$v"
printf " '.github/workflows/ci.yml':\n"
printf " - 'actions/upload-artifact@v7.0.1'\n"
if [ "$variant" != clean ]; then

Check failure on line 81 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem08&open=AaE52lxDt0UEoTYzem08&pullRequest=1250
printf " - 'actions/checkout@%s'\n" "$CHECKOUT"
printf " - 'hyperpolymath/standards@%s'\n" "$STANDARDS"
fi
printf "dependencies:\n"
if [ "$variant" != clean ]; then

Check failure on line 86 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem09&open=AaE52lxDt0UEoTYzem09&pullRequest=1250
printf " 'actions/checkout@%s':\n ref: '%s'\n commit: 'sha1-%s'\n owner_id: 44036562\n repo_id: 197814629\n" \
"$CHECKOUT" "$CHECKOUT" "$CHECKOUT"
fi
printf " 'actions/upload-artifact@v7.0.1':\n ref: 'v7.0.1'\n commit: 'sha1-%s'\n owner_id: 44036562\n repo_id: 239134591\n" \
"$UPLOAD_OLD"
if [ "$variant" != clean ]; then

Check failure on line 92 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem0-&open=AaE52lxDt0UEoTYzem0-&pullRequest=1250
printf " 'hyperpolymath/standards@%s':\n ref: '%s'\n commit: 'sha1-%s'\n owner_id: 6759885\n repo_id: 1\n" \
"$STANDARDS" "$STANDARDS" "$STANDARDS"
fi
} > "$d/.github/workflows/actions.lock"
}

# Run --verify-local in <dir>; JSON to $WORK/out.json, stderr to $WORK/err.
verify() { (cd "$1" && "$BIN" --verify-local --json=valid,findings >"$WORK/out.json" 2>"$WORK/err"); }

Check warning on line 100 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1B&open=AaE52lxDt0UEoTYzem1B&pullRequest=1250

Check warning on line 100 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1A&open=AaE52lxDt0UEoTYzem1A&pullRequest=1250

echo "2. reads every current lockfile version"
for v in v0.0.2 v0.0.3; do
fixture "$WORK/r" "$v" clean
before="$(sha256sum "$WORK/r/.github/workflows/actions.lock")"
verify "$WORK/r"; rc=$?
if [ "$rc" -eq 0 ] && jq -e '.valid == true and .findings == []' "$WORK/out.json" >/dev/null 2>&1; then

Check failure on line 107 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1C&open=AaE52lxDt0UEoTYzem1C&pullRequest=1250
ok "a complete lockfile $v verifies valid"
else bad "a complete lockfile $v did not verify (exit $rc): $(head -c 300 "$WORK/err")"; fi
if [ "$before" = "$(sha256sum "$WORK/r/.github/workflows/actions.lock")" ]; then

Check failure on line 110 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1D&open=AaE52lxDt0UEoTYzem1D&pullRequest=1250
ok "--verify-local left the $v lockfile byte-identical"
else bad "--verify-local rewrote the $v lockfile"; fi
done

echo "3. a lockfile newer than the binary is refused"
fixture "$WORK/r" v9.9.9 clean
verify "$WORK/r"; rc=$?
if [ "$rc" -ne 0 ] && grep -q 'newer than this binary supports' "$WORK/err"; then

Check failure on line 118 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1E&open=AaE52lxDt0UEoTYzem1E&pullRequest=1250
ok "lockfile v9.9.9 is refused (exit $rc) and says why"
else bad "lockfile v9.9.9 was not refused loudly (exit $rc): $(head -c 300 "$WORK/err")"; fi

echo "4. JSON shape and finding categories"
fixture "$WORK/r" v0.0.3 desync
verify "$WORK/r"
if jq -e -s 'length == 1 and (.[0] | type == "object" and (.valid | type == "boolean")
and (.findings | type == "array")
and all(.findings[]; (.category | type == "string") and (.workflow | type == "string")
and (.dependency | type == "string")))' "$WORK/out.json" >/dev/null 2>&1; then
ok "one object: boolean valid, findings with category/workflow/dependency"
else bad "unexpected JSON shape: $(head -c 300 "$WORK/out.json")"; fi
got="$(jq -r '.findings[] | "\(.category) \(.dependency)"' "$WORK/out.json" 2>/dev/null | sort)"
want="$(printf '%s\n' \
"ref-changed actions/upload-artifact@v7.0.2" \
"sha-as-ref actions/checkout@$CHECKOUT" \
"stale actions/upload-artifact@v7.0.1" \
"stale hyperpolymath/standards@$STANDARDS" | sort)"
if [ "$got" = "$want" ]; then ok "sha-as-ref, ref-changed, stale and reusable stale, by category"

Check failure on line 137 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1F&open=AaE52lxDt0UEoTYzem1F&pullRequest=1250
else bad "categories differ"; diff <(echo "$want") <(echo "$got") | sed 's/^/ /'; fi
if jq -e '.valid == false' "$WORK/out.json" >/dev/null 2>&1; then ok "a desync is valid:false"
else bad "a desync was not valid:false"; fi

echo "5. update-actions-lock.sh --verify-local on the real binary"
mkdir -p "$WORK/bin"
printf '#!/usr/bin/env bash\n[ "$1" = actions-lock ] && shift\nexec "%s" "$@"\n' "$BIN" > "$WORK/bin/gh"
chmod +x "$WORK/bin/gh"
fixture "$WORK/r" v0.0.3 reusable
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1 &&
grep -q "Accepted reusable-workflow lock coverage: .github/workflows/ci.yml -> hyperpolymath/standards@$STANDARDS" "$WORK/log"; then
ok "reusable-workflow coverage and an advisory sha-as-ref are accepted"
else bad "the reusable fixture was rejected"; sed 's/^/ /' "$WORK/log" | tail -8; fi
fixture "$WORK/r" v0.0.3 desync
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1; then
bad "a bumped-but-not-relocked tag was accepted"; sed 's/^/ /' "$WORK/log" | tail -8
else ok "a bumped-but-not-relocked tag is rejected"; fi

# A v0.1.6-written lock has no entry for a workflow with nothing to pin. v0.2.0
# reports it `not-pinned` with no dependency; GitHub runs it regardless.
fixture "$WORK/r" v0.0.2 clean
printf 'on: push\npermissions: {}\njobs:\n a:\n runs-on: ubuntu-latest\n steps:\n - run: echo ok\n' \
> "$WORK/r/.github/workflows/runonly.yml"
printf 'on: workflow_call\npermissions: {}\njobs:\n a:\n uses: ./.github/workflows/runonly.yml\n' \
> "$WORK/r/.github/workflows/localcall.yml"
verify "$WORK/r"
if jq -e '[.findings[] | select(.category != "not-pinned" or .dependency != null)] == []' \
"$WORK/out.json" >/dev/null 2>&1; then
ok "an unlisted run-only or ./-only workflow yields at most not-pinned with no dependency"
else bad "unexpected findings for unlisted workflows: $(head -c 300 "$WORK/out.json")"; fi
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1; then
ok "update-actions-lock.sh accepts workflows with nothing to pin"
else bad "workflows with nothing to pin were rejected"; sed 's/^/ /' "$WORK/log" | tail -8; fi
# A same-repository composite action. v0.2.0 calls `./` unsupported; the estate
# runs it, and fails the `$/` rewrite instead (check-lock-sync.sh).
printf 'on: push\npermissions: {}\njobs:\n a:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/upload-artifact@v7.0.1\n - uses: ./.github/actions/thing\n' \
> "$WORK/r/.github/workflows/localaction.yml"
# v0.2.0 flags `./` only in a workflow the lock lists, so list this one.
awk -v q="'" '/^dependencies:/ {
print " " q ".github/workflows/localaction.yml" q ":"
print " - " q "actions/upload-artifact@v7.0.1" q
} { print }' "$WORK/r/.github/workflows/actions.lock" > "$WORK/lock.tmp" &&
mv "$WORK/lock.tmp" "$WORK/r/.github/workflows/actions.lock"
verify "$WORK/r"
if jq -e '[.findings[] | select(.category == "local-action" and .dependency == null)] | length == 1' \
"$WORK/out.json" >/dev/null 2>&1; then
ok "a listed workflow with a ./ action yields local-action with no dependency"
else bad "a listed workflow with a ./ action did not yield local-action"; fi
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1; then
bad "a ./ action that does not exist was accepted"; sed 's/^/ /' "$WORK/log" | tail -8
else ok "a ./ action that does not exist is rejected"; fi
mkdir -p "$WORK/r/.github/actions/thing"
printf 'name: thing\nruns:\n using: composite\n steps:\n - run: echo ok\n shell: bash\n' \
> "$WORK/r/.github/actions/thing/action.yml"
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1; then
ok "a ./ action present in the checkout is accepted"
else bad "a ./ action present in the checkout was rejected"; sed 's/^/ /' "$WORK/log" | tail -8; fi
if grep -q 'uses: ./.github/actions/thing' "$WORK/r/.github/workflows/localaction.yml"; then
ok "--verify-local left the ./ reference unrewritten"
else bad "--verify-local rewrote the ./ reference"; fi
printf 'on: push\npermissions: {}\njobs:\n a:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/upload-artifact@v7.0.1\n' \
> "$WORK/r/.github/workflows/remote.yml"
if (cd "$WORK/r" && GH_BIN="$WORK/bin/gh" bash "$ROOT/scripts/update-actions-lock.sh" --verify-local) >"$WORK/log" 2>&1; then
bad "an unlisted workflow with a remote action was accepted"; sed 's/^/ /' "$WORK/log" | tail -8

Check warning on line 201 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of using the literal 's/^/ /' 7 times.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE55eI5kUCtO9nB2tGp&open=AaE55eI5kUCtO9nB2tGp&pullRequest=1250
else ok "an unlisted workflow with a remote action is rejected"; fi

echo
echo "Total: $pass passed, $fail failed"
[ "$fail" -eq 0 ]

Check failure on line 206 in scripts/tests/gh-actions-lock-contract-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaE52lxDt0UEoTYzem1G&open=AaE52lxDt0UEoTYzem1G&pullRequest=1250
Loading
Loading