Skip to content

fix(frontend): clear runtime critical and high advisories #3435

fix(frontend): clear runtime critical and high advisories

fix(frontend): clear runtime critical and high advisories #3435

name: Package Version Guard
# A published package's version is the ONLY check available from outside this
# repo. When source ships without a version bump, that check silently passes
# while the artifact and the repo disagree — and nobody can tell.
#
# It has happened twice:
# #979 @commonlyai/mcp npm 0.3.0 and main 0.3.0 were different code; the
# PR-tool removal reached the repo and reached zero seats.
# #1017 @commonlyai/cli npm 0.1.9 and main 0.1.9 were different code, with
# SEVEN source commits since the bump — including #995, the quota
# misclassification that had seats probing a dead provider every 5s.
#
# Both were found by hand, months and hours late respectively. This makes the
# third one go red instead.
on:
pull_request:
branches: [ main ]
# `edited` catches base-branch retargeting — see the note in
# pr-base-freshness.yml. A stacked PR retargeted to main after its parent
# merges enters this guard's population without any event in the list
# below ever firing for it.
types: [opened, synchronize, reopened, ready_for_review, edited]
permissions:
contents: read
pull-requests: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
version-guard:
name: Source changed ⇒ version bumped
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Every published package whose source moved must bump its version
shell: bash
run: |
set -euo pipefail
BASE="origin/${{ github.event.pull_request.base.ref }}"
# NO --depth here. `checkout` above already fetched full history
# (fetch-depth: 0); a --depth=1 fetch of the base UNDOES that by
# shallowing the ref, and once the base is one commit deep the fork
# point is unreachable. `git diff BASE...HEAD` then dies with
# "fatal: <base>...HEAD: no merge base" — which reads like a problem
# with the PR's diff and is entirely a problem with this fetch.
#
# It only fires once the base has advanced past the fork point, which
# is why the guard worked for weeks and then failed on #1113. Locally
# reproducible: full clone, advance base 12 commits past a feature
# branch, `git fetch --depth=1 origin <base>`, and the very next
# three-dot diff fails.
#
# Also dropped the `|| true`. A base we cannot fetch means every
# comparison below is meaningless, so it must stop rather than
# silently compare against whatever ref happens to be on disk — the
# failure mode this whole guard exists to prevent.
git fetch --no-tags origin "${{ github.event.pull_request.base.ref }}"
# Prove the base is usable before trusting any diff against it. A
# guard that cannot see its own baseline must say so, not pass.
if ! git merge-base "$BASE" HEAD >/dev/null 2>&1; then
echo "::error::No merge base between $BASE and HEAD — the checkout is too shallow for this guard to compare anything. Not passing on an unusable baseline."
exit 1
fi
fail=0
# pkg_dir : the published package root (holds package.json)
for pkg in cli commonly-mcp; do
# Did any SOURCE file move? Docs and tests do not require a release.
changed=$(git diff --name-only "$BASE"...HEAD -- "$pkg/src" | wc -l | tr -d ' ')
if [ "$changed" = "0" ]; then
echo "· $pkg: no src changes"
continue
fi
base_v=$(git show "$BASE:$pkg/package.json" 2>/dev/null | sed -n 's/.*"version": "\([^"]*\)".*/\1/p' | head -1)
head_v=$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' "$pkg/package.json" | head -1)
# `sort -V` is not semver. It orders 1.0.0 BEFORE 1.0.0-beta.1,
# reading a prerelease as NEWER than its own release, and it
# inverts in both directions: base=1.0.0 head=1.0.0-beta.1 would
# PASS — the exact backwards walk this check exists to stop — and
# the legitimate promotion 1.0.0-beta.1 → 1.0.0 would FAIL.
# No version ever committed to either package carries a
# prerelease, so this is latent today. It fails OPEN in the
# direction that matters, so the guard refuses to judge rather
# than guessing, on the same principle as the merge-base check
# above: a guard that cannot compare its inputs must say so.
case "$base_v$head_v" in
*-*)
echo "::error file=$pkg/package.json::$pkg version comparison involves a prerelease ($base_v → $head_v). \`sort -V\` orders a prerelease as NEWER than its release, so this guard reaches the wrong answer in BOTH directions. Teach it semver before landing a prerelease; do not merge on this check alone."
fail=1
continue
;;
esac
# An INCREASE, not merely a difference. A long-lived branch that
# bumped while the base moved further ahead leaves head_v BELOW
# base_v — different, so an equality test passes it, and merging
# then walks the version backwards on the base. Observed on two
# open PRs at once (base 0.1.21, heads 0.1.20 and 0.1.19), both
# showing this check green.
newest=$(printf '%s\n%s\n' "$base_v" "$head_v" | sort -V | tail -1)
if [ "$base_v" = "$head_v" ]; then
echo "::error file=$pkg/package.json::$pkg/src changed ($changed file(s)) but version is still $head_v. A published version that maps to two different artifacts defeats the only check available from outside this repo — bump it, or move the change out of $pkg/src."
fail=1
elif [ "$newest" != "$head_v" ]; then
echo "::error file=$pkg/package.json::$pkg/src changed ($changed file(s)) and $head_v is BELOW the base's $base_v. Merging would walk the published version backwards. Rebase and bump above $base_v."
fail=1
else
echo "✓ $pkg: src changed and version rose $base_v → $head_v"
fi
done
exit $fail
# The check above compares this PR against the base. It cannot see a
# SECOND open PR bumping the same package to the same version, because
# neither branch contains the other's commit — and that pair merges
# CLEAN. Measured, not assumed: two branches both taking cli 0.1.30 to
# 0.1.31 while touching different files under cli/src merge with no
# conflict, and the result is one 0.1.31 holding both PRs' source. Each
# PR's guard was green the whole time. npm then has a version that maps
# to an artifact neither PR alone produced, which is the exact defect
# #979 and #1017 were.
#
# Older PR keeps the version, newer picks the next one — so it is always
# fixable by one author alone. Failing both would be a deadlock.
- name: No older open PR is taking this package to the same version
env:
GH_TOKEN: ${{ github.token }}
PR: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
shell: bash
run: |
set -euo pipefail
# Every gh call is checked. An unchecked failure yields an empty
# version list, which reads as "this PR bumps nothing" and PASSES —
# the guard at its most reassuring exactly when it has gone blind.
# Same reason the `|| true` came off the fetch above.
proposed() {
local pr="$1" pkg="$2" patch
if ! patch=$(gh api "repos/$REPO/pulls/$pr/files" --paginate \
--jq ".[] | select(.filename == \"$pkg/package.json\") | .patch"); then
echo "::error::gh api failed reading PR #$pr. Not passing on a check that could not run." >&2
return 1
fi
# Only an ADDED version line counts. A PR that merely carries an
# old package.json (every stale branch does) proposes nothing.
printf '%s\n' "$patch" | sed -n 's/^+.*"version": "\([^"]*\)".*/\1/p' | head -1
}
if ! older=$(gh api "repos/$REPO/pulls?state=open&per_page=100" --paginate \
--jq ".[] | select(.number < $PR) | .number"); then
echo "::error::gh api failed listing open PRs. Not passing on a blind check."
exit 1
fi
fail=0
for pkg in cli commonly-mcp; do
mine=$(proposed "$PR" "$pkg")
[ -z "$mine" ] && { echo "· $pkg: this PR proposes no version"; continue; }
echo "· $pkg: this PR proposes $mine"
for other in $older; do
theirs=$(proposed "$other" "$pkg")
[ "$theirs" = "$mine" ] || continue
echo "::error file=$pkg/package.json::$pkg $mine is already claimed by the older open PR #$other. Both bumps merge clean — git sees the same line changed the same way — so npm would carry one $mine built from both PRs' source. #$other keeps $mine; pick the next version here."
fail=1
done
done
if [ "$fail" = "0" ]; then
echo "✓ no older open PR claims these versions"
fi
exit $fail