mirror of
https://github.com/awalsh128/cache-apt-pkgs-action.git
synced 2026-11-14 05:46:50 +00:00
Add scripts/ops/check_tsapt_pin.sh, which fails when node_modules/ts-apt is a symlink, package.json does not pin ts-apt to a full commit SHA, or package-lock.json resolves ts-apt to a link or a different SHA. Run it from a .githooks/pre-push hook (installed by the npm prepare script via core.hooksPath) and from the CI action-deps-pinned job, and document the rule in AGENTS.md. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
66 lines
2.2 KiB
Bash
Executable file
66 lines
2.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Fails when ts-apt is not resolved from a pushed commit SHA pin.
|
|
#
|
|
# Guards against shipping code built or tested against a local ts-apt link
|
|
# (npm run dev:tsapt:link), which CI cannot see. Checks that:
|
|
# 1. node_modules/ts-apt is not a symlink (skipped if node_modules is absent).
|
|
# 2. package.json pins ts-apt to a full commit SHA.
|
|
# 3. package-lock.json resolves ts-apt to that same SHA and not a link.
|
|
#
|
|
# Used by .githooks/pre-push and the CI action-deps-pinned job.
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(git rev-parse --show-toplevel)"
|
|
cd "${ROOT_DIR}"
|
|
|
|
errors=0
|
|
error() {
|
|
echo "ERROR: $*" >&2
|
|
errors=$((errors + 1))
|
|
}
|
|
|
|
if [[ -L node_modules/ts-apt ]]; then
|
|
error "node_modules/ts-apt is a symlink to $(readlink node_modules/ts-apt); run 'npm run dev:tsapt:unlink' first."
|
|
fi
|
|
|
|
# Prints one problem per line; package.json and package-lock.json are parsed
|
|
# with node to avoid a jq dependency.
|
|
lock_problems="$(node --input-type=module - <<'EOF'
|
|
import { readFileSync } from "node:fs";
|
|
const pin = /^git\+https:\/\/github\.com\/awalsh128\/ts-apt\.git#([0-9a-f]{40})$/;
|
|
const spec = JSON.parse(readFileSync("package.json", "utf8")).dependencies?.["ts-apt"];
|
|
const match = pin.exec(spec ?? "");
|
|
if (!match) {
|
|
console.log(`package.json ts-apt '${spec}' is not pinned to a full commit SHA.`);
|
|
process.exit(0);
|
|
}
|
|
const sha = match[1];
|
|
const lock = JSON.parse(readFileSync("package-lock.json", "utf8"));
|
|
const rootSpec = lock.packages?.[""]?.dependencies?.["ts-apt"];
|
|
if (rootSpec !== spec) {
|
|
console.log(`package-lock.json root ts-apt '${rootSpec}' does not match package.json '${spec}'.`);
|
|
}
|
|
const entry = lock.packages?.["node_modules/ts-apt"];
|
|
if (!entry) {
|
|
console.log("package-lock.json has no node_modules/ts-apt entry.");
|
|
} else if (entry.link) {
|
|
console.log(`package-lock.json ts-apt is a link to '${entry.resolved}'.`);
|
|
} else if (!entry.resolved?.endsWith(`#${sha}`)) {
|
|
console.log(`package-lock.json ts-apt resolved '${entry.resolved}' does not match pin ${sha}.`);
|
|
}
|
|
EOF
|
|
)"
|
|
|
|
if [[ -n "${lock_problems}" ]]; then
|
|
while IFS= read -r problem; do
|
|
error "${problem}"
|
|
done <<<"${lock_problems}"
|
|
fi
|
|
|
|
if ((errors > 0)); then
|
|
echo "ts-apt pin check failed with ${errors} error(s)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "ts-apt pin check passed."
|