#!/bin/sh # CI lint: flags tracker references — a `#N` tag or a full `.../issues/N` # forge URL — anywhere in tracked text, source or docs. Prose, not tracker # references: in code because tags rot; in markdown because the forge's # public mirror carries no issue/PR data at all, so bare/qualified/glued # `#N` and a full link are equally dead weight for a public reader — a # full URL is the same problem spelled out longer, not a safer swap for a # short tag. No markdown exemption: one used to exist, dropped once that # read as still allowing exactly this. # # Emits a CI error annotation per hit, exits 1 if any hit is found. Its own # required CI job (branch protection) — a hit blocks merge. # # Scope: every tracked `*.rs *.nix *.js *.ts *.tsx *.css *.html *.md`. Two # alternatives: a hash, 2-5 digits, then non-alphanumeric-or-EOL (skips # letter-bearing hex colours and digit-runs-then-letter, e.g. `#24h`; # residual: a pure-numeric short hex trips it, write the six-digit form to # dodge); or an `/issues/N` path segment, catching a full link via # `$HIVE_FORGE_URL` or a literal domain alike. # # Escape hatch: a line with the marker `lint:allow` is exempt. Reserve it # for a genuine non-tag hit (a `#123` heading example, test-input data) and # keep a short reason next to it — not for a real reference of either # form; rewrite those to prose that stands on its own instead. set -eu pattern='#[0-9]{2,5}([^0-9a-zA-Z]|$)|/issues/[0-9]+([^0-9a-zA-Z]|$)' # `/dev/null` forces grep to always print a filename prefix, even when # xargs hands it a single file. `-r`/`-0` keep it robust to odd paths and # an empty file list. Lines carrying the `lint:allow` marker are dropped # (legitimate non-tracker hit; see the header). hits="$( git ls-files -z '*.rs' '*.nix' '*.js' '*.ts' '*.tsx' '*.css' '*.html' '*.md' \ | xargs -0 -r grep -nE "$pattern" /dev/null 2>/dev/null \ | grep -v 'lint:allow' || true )" if [ -n "$hits" ]; then echo "$hits" | while IFS=: read -r file lineno _; do printf '::error file=%s,line=%s::tracker reference — write prose that stands on its own, not a hash-number tag or a full issue URL (see /knowledge/hive-rules.md)\n' "$file" "$lineno" done count="$(printf '%s\n' "$hits" | wc -l | tr -d ' ')" printf 'check-issue-refs: %s tracker reference(s) found\n' "$count" >&2 exit 1 fi exit 0