#!/usr/bin/env bash # Self-test for pr-touches-paths.py, run by the workflow-hygiene job. # # A gate that decides whether tests run is itself load-bearing: a wrong `false` # silently skips a whole workflow. These cases pin both directions and, most # importantly, that every way of failing fails OPEN. set -euo pipefail cd "$(dirname "$0")/.." G=scripts/pr-touches-paths.py tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT fail=0 check() { # name expected actual if [ "$2" = "$3" ]; then printf ' ok %s\n' "$1" else printf ' FAIL %s: expected %s, got %s\n' "$1" "$2" "$3"; fail=1; fi } # A throwaway repo, so the diffs are real git diffs and not a mock. repo="$tmp/r"; mkdir -p "$repo/wai/wai-pack" "$repo/jcp" git -C "$repo" init -q git -C "$repo" config user.email t@e; git -C "$repo" config user.name t echo x > "$repo/jcp/SPEC.md"; echo y > "$repo/wai/wai-pack/lib.rs" git -C "$repo" add -A; git -C "$repo" commit -qm base BASE=$(git -C "$repo" rev-parse HEAD) echo changed > "$repo/jcp/SPEC.md" git -C "$repo" add -A; git -C "$repo" commit -qm jcp-only JCP=$(git -C "$repo" rev-parse HEAD) echo changed > "$repo/wai/wai-pack/lib.rs" git -C "$repo" add -A; git -C "$repo" commit -qm wai-too WAI=$(git -C "$repo" rev-parse HEAD) wf="$tmp/w.yml" cat > "$wf" <<'Y' on: pull_request: paths: - 'wai/wai-pack/**' Y run() { ( cd "$repo" && python3 "$OLDPWD/$G" "$1" "$2" "$3" ); } check "a jcp-only diff does not touch a wai filter" false "$(run "$wf" "$BASE" "$JCP")" check "a diff that touches the filter runs" true "$(run "$wf" "$BASE" "$WAI")" # Every failure mode must fail OPEN. check "a missing workflow file" true "$(run "$tmp/nope.yml" "$BASE" "$JCP")" check "a workflow with no filter" true "$(printf 'on:\n pull_request:\n' > "$tmp/nofilter.yml"; run "$tmp/nofilter.yml" "$BASE" "$JCP")" check "an empty base sha" true "$(run "$wf" "" "$JCP")" check "a sha git cannot resolve" true "$(run "$wf" "$BASE" deadbeefdeadbeefdeadbeefdeadbeefdeadbeef)" check "too few arguments" true "$( cd "$repo" && python3 "$OLDPWD/$G" "$wf" )" check "an empty diff" true "$(run "$wf" "$JCP" "$JCP")" # `**` spans separators; `*` does not. cat > "$tmp/star.yml" <<'Y' on: pull_request: paths: - 'jcp/*.md' Y # Only the NESTED file changes, so `jcp/*.md` must not match it. (A top-level # .md in the same commit would match legitimately and prove nothing — which is # how this case failed the first time it was written.) mkdir -p "$repo/jcp/sub"; echo z > "$repo/jcp/sub/x.md" git -C "$repo" add -A >/dev/null; git -C "$repo" commit -qm sub >/dev/null SUB=$(git -C "$repo" rev-parse HEAD) check "a single star does not span a separator" false "$(run "$tmp/star.yml" "$WAI" "$SUB")" # And it does match a file at that level, so the glob is not simply never matching. echo z > "$repo/jcp/top.md" git -C "$repo" add -A >/dev/null; git -C "$repo" commit -qm top >/dev/null check "a single star matches at its own level" true "$(run "$tmp/star.yml" "$SUB" "$(git -C "$repo" rev-parse HEAD)")" [ "$fail" = 0 ] && echo "pr-touches-paths self-test: all cases pass" || { echo "pr-touches-paths self-test FAILED"; exit 1; }