diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b10a22..99cb613 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -86,6 +86,17 @@ jobs: # SAST (Static Application Security Testing) using Semgrep. # Semgrep scans the codebase for security vulnerabilities, hardcoded secrets, and bad practices # using pattern matching. It is fast and catches common mistakes. + doclint: + name: Doc/Code Lint: implementation-term leaks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2 + with: + bun-version: "1.3.10" + - run: bun install --frozen-lockfile + - run: ./scripts/check-impl-term-leaks.sh + sast-semgrep: name: Semgrep SAST runs-on: ubuntu-latest diff --git a/scripts/check-impl-term-leaks.sh b/scripts/check-impl-term-leaks.sh new file mode 100755 index 0000000..b7acb25 --- /dev/null +++ b/scripts/check-impl-term-leaks.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Define the patterns to search for +# Bead IDs: ops-[a-z0-9]{4,} +# Implementation labels: post-#.# or pre-#.# (where # is digit) +# Harper bare references: \bHarper\b +PATTERNS='ops-[a-z0-9]{4,}|\\bpost-[0-9]+\\.[0-9]+\\b|\\bpre-[0-9]+\\.[0-9]+\\b|\\bHarper\\b' + +# Temporary file for list of files +TMPFILE=$(mktemp) +trap "rm -f $TMPFILE" EXIT + +# Find files to search: +# 1. All files under packages/*/dist/ +find packages -type f -path '*/dist/*' -not -path '*/.github/*' -not -path '*/specs/*' -not -path '*/test/*' 2>/dev/null >> "$TMPFILE" +# 2. All packages/*/README.md +find packages -type f -name 'README.md' -path 'packages/*' -not -path '*/.github/*' -not -path '*/specs/*' -not -path '*/test/*' 2>/dev/null >> "$TMPFILE" +# 3. Root README.md +if [[ -f README.md && ! README.md -ef */.github/* && ! README.md -ef */specs/* && ! README.md -ef */test/* ]]; then + echo "README.md" >> "$TMPFILE" +fi +# 4. All files under docs/ +find docs -type f -not -path '*/.github/*' -not -path '*/specs/*' -not -path '*/test/*' 2>/dev/null >> "$TMPFILE" + +# Sort and remove duplicates +sort -u "$TMPFILE" > "${TMPFILE}.sorted" +mv "${TMPFILE}.sorted" "$TMPFILE" + +# If no files found, exit 0 +if [[ ! -s "$TMPFILE" ]]; then + echo "No files to search." + exit 0 +fi + +# Search for patterns in the collected files +echo "Searching for implementation term leaks in:" +cat "$TMPFILE" +echo "---" + +# Use grep with line numbers and filename +# We use command substitution to pass the list of files as arguments +OUTPUT=$(grep -n -E "$PATTERNS" $(cat "$TMPFILE") 2>/dev/null || true) + +if [[ -n "$OUTPUT" ]]; then + echo "$OUTPUT" + exit 1 +else + echo "No leaks found." + exit 0 +fi \ No newline at end of file