From 21458e3192d992626198ce82b938a644ff67e4df Mon Sep 17 00:00:00 2001 From: Nathan Gillett Date: Sat, 30 May 2026 17:49:30 -0500 Subject: [PATCH] Trim obsolete Python SDK release and gate tooling Remove PyPI release workflows, OSV/allowlist scripts, coverage gate scripts, and pytest-cov defaults. CI remains pytest conformance. --- .github/codeql-allowlist.yml | 4 - .github/deps-allowlist.yml | 6 - .github/workflows/release-pypi.yml | 227 ------------------ .github/workflows/release-signing-dry-run.yml | 83 ------- .osv-scanner.toml | 4 - pyproject.toml | 13 - scripts/README-coverage-tiers.md | 8 - scripts/check-allowlist-expiry.sh | 111 --------- scripts/check-codeql-allowlist.sh | 3 - scripts/check-coverage.sh | 136 ----------- .../check-coverage_critical_prefix_test.sh | 48 ---- scripts/check-coverage_display_test.sh | 21 -- scripts/check-coverage_path_test.sh | 42 ---- scripts/check-deps-allowlist.sh | 3 - scripts/coverage-tiers.conf | 7 - scripts/run-coverage-gate.sh | 27 --- scripts/run-osv-scanner-gate.sh | 101 -------- 17 files changed, 844 deletions(-) delete mode 100644 .github/codeql-allowlist.yml delete mode 100644 .github/deps-allowlist.yml delete mode 100644 .github/workflows/release-pypi.yml delete mode 100644 .github/workflows/release-signing-dry-run.yml delete mode 100644 .osv-scanner.toml delete mode 100644 scripts/README-coverage-tiers.md delete mode 100755 scripts/check-allowlist-expiry.sh delete mode 100755 scripts/check-codeql-allowlist.sh delete mode 100755 scripts/check-coverage.sh delete mode 100755 scripts/check-coverage_critical_prefix_test.sh delete mode 100755 scripts/check-coverage_display_test.sh delete mode 100755 scripts/check-coverage_path_test.sh delete mode 100755 scripts/check-deps-allowlist.sh delete mode 100644 scripts/coverage-tiers.conf delete mode 100755 scripts/run-coverage-gate.sh delete mode 100755 scripts/run-osv-scanner-gate.sh diff --git a/.github/codeql-allowlist.yml b/.github/codeql-allowlist.yml deleted file mode 100644 index 2d26ba8..0000000 --- a/.github/codeql-allowlist.yml +++ /dev/null @@ -1,4 +0,0 @@ -# CodeQL finding allowlist with expiry model. -# New entries require security on-call approval. -# Expired entries fail CI via scripts/check-codeql-allowlist.sh. -allowlist: [] diff --git a/.github/deps-allowlist.yml b/.github/deps-allowlist.yml deleted file mode 100644 index ab83a63..0000000 --- a/.github/deps-allowlist.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Dependency vulnerability allowlist with expiry model. -# HIGH-severity exceptions require security on-call approval. -# Mirror approved entries into .osv-scanner.toml [[IgnoredVulns]] with -# matching ignoreUntil dates. Expired entries fail CI via -# scripts/check-deps-allowlist.sh. -allowlist: [] diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml deleted file mode 100644 index fbfcf78..0000000 --- a/.github/workflows/release-pypi.yml +++ /dev/null @@ -1,227 +0,0 @@ -name: release pypi - -on: - push: - tags: - - 'v*' - workflow_dispatch: - inputs: - release_ref: - description: Git ref to build and publish from. - required: true - default: refs/heads/main - type: string - release_version: - description: SemVer version for dry-run metadata (without v prefix). - required: true - default: 0.0.0-dryrun - type: string - publish_to_pypi: - description: Publish to PyPI with PEP 740 attestations (requires trusted publisher). - required: true - default: true - type: boolean - -permissions: - contents: write - id-token: write - -jobs: - test: - name: "IntentProof Release: Test Python Package" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_ref || github.ref }} - - - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Install dependencies - run: pip install -e ".[dev]" - - - name: Enforce coverage threshold - run: bash ./scripts/run-coverage-gate.sh - - build: - name: "IntentProof Release: Build Python Distributions" - needs: test - runs-on: ubuntu-latest - outputs: - artifact_paths: ${{ steps.dists.outputs.artifact_paths }} - release_ref: ${{ steps.release.outputs.release_ref }} - release_version: ${{ steps.release.outputs.release_version }} - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_ref || github.ref }} - - - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - - name: Resolve release metadata - id: release - env: - INPUT_RELEASE_REF: ${{ inputs.release_ref }} - INPUT_RELEASE_VERSION: ${{ inputs.release_version }} - run: | - set -euo pipefail - semver_tag='^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' - - if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then - release_ref="$INPUT_RELEASE_REF" - release_version="$INPUT_RELEASE_VERSION" - else - release_ref="${GITHUB_REF}" - release_version="${GITHUB_REF_NAME#v}" - if [[ ! "$release_ref" =~ $semver_tag ]]; then - echo "tag ref must match vMAJOR.MINOR.PATCH: ${release_ref}" >&2 - exit 1 - fi - fi - - { - echo "release_ref=${release_ref}" - echo "release_version=${release_version}" - } >> "$GITHUB_OUTPUT" - - - name: Sync package version - env: - RELEASE_VERSION: ${{ steps.release.outputs.release_version }} - run: | - set -euo pipefail - python3 - <<'PY' - import os - import re - from pathlib import Path - - version = os.environ["RELEASE_VERSION"] - path = Path("pyproject.toml") - text = path.read_text(encoding="utf-8") - updated, count = re.subn( - r'^version = "[^"]+"$', - f'version = "{version}"', - text, - count=1, - flags=re.MULTILINE, - ) - if count != 1: - raise SystemExit("failed to update pyproject.toml version") - path.write_text(updated, encoding="utf-8") - PY - - - name: Build Python distributions - run: | - python -m pip install --upgrade build - python -m build --outdir dist . - - - name: Export distribution paths - id: dists - run: | - set -euo pipefail - mapfile -t files < <(find dist -maxdepth 1 -type f | sort) - test "${#files[@]}" -gt 0 - { - echo "artifact_paths<> "$GITHUB_OUTPUT" - - - uses: actions/upload-artifact@v7 - with: - name: python-release-package - path: dist/* - - publish: - name: "IntentProof Release: Publish Python Package" - needs: build - if: github.event_name != 'workflow_dispatch' || inputs.publish_to_pypi - runs-on: ubuntu-latest - permissions: - attestations: write - contents: read - id-token: write - packages: write - steps: - - uses: actions/download-artifact@v8 - with: - name: python-release-package - path: dist - - - uses: actions/setup-python@v6 - with: - python-version: '3.12' - - - name: Validate Python distributions - run: | - set -euo pipefail - python -m pip install --upgrade twine - test -d dist - twine check dist/* - - - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: dist - attestations: true - - sign: - name: "IntentProof Release: Sign Python Distributions" - needs: build - permissions: - attestations: write - contents: write - id-token: write - packages: write - uses: IntentProof/intentproof-tools/.github/workflows/release-build-sign.yml@e982df238d9f111bc1f59b7473988c0d538dabb6 - with: - artifact_kind: generic - subject_name: intentproof - release_version: ${{ needs.build.outputs.release_version }} - release_ref: ${{ needs.build.outputs.release_ref }} - artifact_paths: ${{ needs.build.outputs.artifact_paths }} - artifact_download_name: python-release-package - artifact_download_path: dist - attest_to_rekor: ${{ github.event_name != 'workflow_dispatch' }} - - upload-release: - name: "IntentProof Release: Publish Python Release Artifacts" - needs: - - build - - sign - - publish - if: >- - github.event_name != 'workflow_dispatch' - && needs.build.result == 'success' - && needs.sign.result == 'success' - && needs.publish.result == 'success' - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/download-artifact@v8 - with: - name: python-release-package - path: release-package - - - uses: actions/download-artifact@v8 - with: - name: release-signing-metadata - path: release-signing-metadata - - - name: Upload distributions and signing metadata to GitHub Release - env: - GH_TOKEN: ${{ github.token }} - GH_REPO: ${{ github.repository }} - RELEASE_TAG: ${{ github.ref_name }} - run: | - set -euo pipefail - mapfile -t files < <(find release-package release-signing-metadata -type f | sort) - test "${#files[@]}" -gt 0 - - if ! gh release view "$RELEASE_TAG" >/dev/null 2>&1; then - gh release create "$RELEASE_TAG" --generate-notes - fi - gh release upload "$RELEASE_TAG" "${files[@]}" --clobber diff --git a/.github/workflows/release-signing-dry-run.yml b/.github/workflows/release-signing-dry-run.yml deleted file mode 100644 index 6d6f110..0000000 --- a/.github/workflows/release-signing-dry-run.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: release signing dry run - -on: - workflow_dispatch: - inputs: - release_version: - description: SemVer version to place in dry-run attestations. - required: true - default: 0.0.0-dryrun - type: string - release_ref: - description: Git ref to check out for the dry run. - required: true - default: refs/heads/main - type: string - -jobs: - build-python-dists: - name: "IntentProof Release: Build Python Distributions" - permissions: - contents: read - runs-on: ubuntu-latest - outputs: - artifact_paths: ${{ steps.dists.outputs.artifact_paths }} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - with: - ref: ${{ inputs.release_ref }} - - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 - with: - python-version: '3.11' - - - name: Install dependencies - run: | - python -m pip install --upgrade build - if [ -f pyproject.toml ]; then - pip install -e . - elif [ -f requirements.txt ]; then - pip install -r requirements.txt - fi - - - name: Install test dependencies - run: pip install -e ".[dev]" - - - name: Run tests with coverage - run: pytest -q - - - name: Build Python distributions - run: python -m build --outdir dist . - - - name: Export distribution paths - id: dists - run: | - { - echo 'artifact_paths<> "$GITHUB_OUTPUT" - - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a - with: - name: python-release-dry-run - path: dist/* - - sign-python-dists: - name: "IntentProof Release: Sign Python Distributions" - needs: build-python-dists - permissions: - attestations: write - contents: write - id-token: write - packages: write - uses: IntentProof/intentproof-tools/.github/workflows/release-build-sign.yml@e982df238d9f111bc1f59b7473988c0d538dabb6 - with: - artifact_kind: generic - subject_name: intentproof - release_version: ${{ inputs.release_version }} - release_ref: ${{ inputs.release_ref }} - artifact_paths: ${{ needs.build-python-dists.outputs.artifact_paths }} - artifact_download_name: python-release-dry-run - artifact_download_path: dist - attest_to_rekor: false diff --git a/.osv-scanner.toml b/.osv-scanner.toml deleted file mode 100644 index 393cdb0..0000000 --- a/.osv-scanner.toml +++ /dev/null @@ -1,4 +0,0 @@ -# IntentProof OSV-Scanner configuration. -# CRITICAL and HIGH findings fail CI via deps-scan workflow severity filter. -# Time-bounded HIGH allowlist entries live in .github/deps-allowlist.yml and -# must be mirrored here under [[IgnoredVulns]] with matching ignoreUntil dates. diff --git a/pyproject.toml b/pyproject.toml index 802933c..c57aaa5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,24 +25,11 @@ Issues = "https://github.com/IntentProof/intentproof-sdk-python/issues" [project.optional-dependencies] dev = [ "pytest>=8.0.0", - "pytest-cov>=5.0.0", ] [tool.setuptools.packages.find] where = ["src"] -[tool.coverage.run] -source = ["intentproof"] -omit = [] - -[tool.coverage.report] -show_missing = true -skip_empty = true - [tool.pytest.ini_options] testpaths = ["tests"] pythonpath = ["src"] -addopts = [ - "--cov=intentproof", - "--cov-report=term-missing", -] diff --git a/scripts/README-coverage-tiers.md b/scripts/README-coverage-tiers.md deleted file mode 100644 index 390caec..0000000 --- a/scripts/README-coverage-tiers.md +++ /dev/null @@ -1,8 +0,0 @@ -# Tiered coverage policy (intentproof-sdk-python) - -| Tier | Minimum | Scope | -|------|---------|--------| -| **Total** | 90% | `src/intentproof/` | -| **Critical** | 95% | Same — public SDK surface | - -Configuration: `scripts/coverage-tiers.conf`. diff --git a/scripts/check-allowlist-expiry.sh b/scripts/check-allowlist-expiry.sh deleted file mode 100755 index db93e7c..0000000 --- a/scripts/check-allowlist-expiry.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash -# Validate allowlist YAML expiry dates (minimal parser, no PyYAML). -# Usage: check-allowlist-expiry.sh [id-field...] -set -euo pipefail - -if [[ $# -lt 1 || -z "${1:-}" ]]; then - echo "usage: check-allowlist-expiry.sh [id-field...]" >&2 - exit 1 -fi - -ALLOWLIST_FILE="$1" -shift -ID_FIELDS=("$@") -if ((${#ID_FIELDS[@]} == 0)); then - ID_FIELDS=(rule_id) -fi - -if [[ ! -f "$ALLOWLIST_FILE" ]]; then - echo "No allowlist file at $ALLOWLIST_FILE; skipping expiry check." - exit 0 -fi - -if ! command -v python3 >/dev/null 2>&1; then - echo "python3 is required to validate $ALLOWLIST_FILE" >&2 - exit 1 -fi - -python3 - "$ALLOWLIST_FILE" "${ID_FIELDS[*]}" <<'PY' -import datetime -import re -import sys - -path = sys.argv[1] -id_fields = sys.argv[2].split() -patterns = { - "rule_id": re.compile(r"rule_id:\s*(\S+)"), - "cve_id": re.compile(r"cve_id:\s*(\S+)"), - "id": re.compile(r"(?:^|\s)id:\s*(\S+)"), -} - - -def extract_id(text, anchored=False): - for field in id_fields: - pattern = patterns.get(field) - if pattern is None: - continue - match = pattern.match(text) if anchored else pattern.search(text) - if match: - return match.group(1) - return None - - -text = open(path, encoding="utf-8").read() -entries = [] -current = None -for line in text.splitlines(): - stripped = line.strip() - if stripped.startswith("- "): - if current is not None: - entries.append(current) - current = {} - item = stripped[2:].strip() - entry_id = extract_id(item, anchored=False) - if entry_id: - current["id"] = entry_id - match = re.search(r"expires:\s*(\S+)", item) - if match: - current["expires"] = match.group(1) - continue - if current is None: - continue - match = re.match(r"expires:\s*(\S+)", stripped) - if match: - current["expires"] = match.group(1) - entry_id = extract_id(stripped, anchored=True) - if entry_id: - current["id"] = entry_id -if current is not None: - entries.append(current) - -today = datetime.date.today() -expired = [] -for idx, entry in enumerate(entries): - expires_raw = entry.get("expires") - if not expires_raw: - print( - f"{path}: allowlist[{idx}] missing expires date " - "(required for security on-call approval model)", - file=sys.stderr, - ) - sys.exit(1) - try: - expires = datetime.date.fromisoformat(str(expires_raw)) - except ValueError: - print( - f"{path}: allowlist[{idx}] has invalid expires date: {expires_raw!r}", - file=sys.stderr, - ) - sys.exit(1) - if expires < today: - entry_id = entry.get("id", "") - expired.append(f"{entry_id} (expired {expires.isoformat()})") - -if expired: - print("Allowlist expired; contact security on-call to extend or remove:", file=sys.stderr) - for item in expired: - print(f" - {item}", file=sys.stderr) - sys.exit(1) - -print(f"PASS: {len(entries)} allowlist entries are current.") -PY diff --git a/scripts/check-codeql-allowlist.sh b/scripts/check-codeql-allowlist.sh deleted file mode 100755 index 9e58438..0000000 --- a/scripts/check-codeql-allowlist.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -# Validate .github/codeql-allowlist.yml expiry dates. -exec "$(dirname "$0")/check-allowlist-expiry.sh" "${1:-.github/codeql-allowlist.yml}" rule_id diff --git a/scripts/check-coverage.sh b/scripts/check-coverage.sh deleted file mode 100755 index fa51007..0000000 --- a/scripts/check-coverage.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# Tiered statement coverage using coverage.py JSON output. -# -# Usage: check-coverage.sh [coverage_json] -# Default: coverage.json (run pytest with --cov first) - -set -euo pipefail - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -CONF="${ROOT}/scripts/coverage-tiers.conf" -COVERAGE_JSON_ARG="${1:-coverage.json}" - -if [[ "$COVERAGE_JSON_ARG" == /* ]]; then - COVERAGE_JSON_PATH="$COVERAGE_JSON_ARG" -else - COVERAGE_JSON_PATH="${ROOT}/${COVERAGE_JSON_ARG}" -fi - -if [[ ! -f "$CONF" ]]; then - echo "coverage tiers config not found: $CONF" >&2 - exit 2 -fi - -# shellcheck disable=SC1090 -source "$CONF" - -if [[ -z "${TOTAL_MIN:-}" ]]; then - echo "coverage-tiers.conf must set TOTAL_MIN" >&2 - exit 2 -fi - -if [[ ! -f "$COVERAGE_JSON_PATH" ]]; then - echo "coverage json not found: $COVERAGE_JSON_PATH (run pytest with --cov first)" >&2 - exit 2 -fi - -rules_file="$(mktemp)" -trap 'rm -f "$rules_file"' EXIT -printf '%s\n' "${CRITICAL_RULES[@]}" >"$rules_file" - -coverage_percent_display() { - awk -v c="$1" -v t="$2" 'BEGIN { - if (t == 0) { print "0.0"; exit } - printf "%.1f", int(1000 * c / t) / 10 - }' -} - -threshold_met() { - awk -v c="$1" -v t="$2" -v min="$3" \ - 'BEGIN { exit !(t > 0 && c * 100 >= t * min) }' -} - -report_threshold() { - local label="$1" covered="$2" total="$3" min="$4" - local pct - pct="$(coverage_percent_display "$covered" "$total")" - echo "${label}: ${pct}% (${covered}/${total} statements), minimum ${min}%" - if threshold_met "$covered" "$total" "$min"; then - echo " PASS" - return 0 - fi - echo " FAIL" >&2 - return 1 -} - -stats_for_prefix() { - local prefix="$1" - python3 - "$COVERAGE_JSON_PATH" "$prefix" <<'PY' -import json -import sys - -path = sys.argv[1] -prefix = sys.argv[2] -data = json.load(open(path)) -covered = 0 -total = 0 - -def covered_statements(summary, entry, stmts): - if "covered_lines" in summary: - return int(summary["covered_lines"]) - missing_lines = entry.get("missing_lines") - if isinstance(missing_lines, list): - return stmts - len(missing_lines) - missing_count = summary.get("missing_lines") - if isinstance(missing_count, int): - return stmts - missing_count - return 0 - -for file_path, entry in data.get("files", {}).items(): - if prefix not in file_path.replace("\\", "/"): - continue - summary = entry.get("summary", {}) - stmts = int(summary.get("num_statements", 0)) - if stmts == 0: - continue - total += stmts - covered += covered_statements(summary, entry, stmts) -print(covered, total) -PY -} - -read -r TOTAL_COVERED TOTAL_STMTS <&2 - exit 2 -fi - -fail=0 -report_threshold "Total coverage" "$TOTAL_COVERED" "$TOTAL_STMTS" "$TOTAL_MIN" || fail=1 - -echo "Critical tiers:" -while IFS= read -r rule; do - [[ -n "$rule" ]] || continue - min="${rule%%:*}" - prefix="${rule#*:}" - read -r c t <&2 - fail=1 - continue - fi - report_threshold " ${prefix}" "$c" "$t" "$min" || fail=1 -done <"$rules_file" - -if [[ "$fail" -ne 0 ]]; then - echo "FAIL: coverage threshold not met" >&2 - exit 1 -fi - -echo "PASS: coverage thresholds met" -exit 0 diff --git a/scripts/check-coverage_critical_prefix_test.sh b/scripts/check-coverage_critical_prefix_test.sh deleted file mode 100755 index 1c27645..0000000 --- a/scripts/check-coverage_critical_prefix_test.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -# Regression test: critical tiers must fail when a prefix matches nothing. -set -euo pipefail - -root="$(mktemp -d)" -trap 'rm -rf "$root"' EXIT - -mkdir -p "$root/scripts" -cp "$(dirname "$0")/check-coverage.sh" "$root/scripts/" - -cat >"$root/scripts/coverage-tiers.conf" <<'EOF' -TOTAL_MIN=50 -CRITICAL_RULES=( - "95:src/intentproof/missing/" -) -EOF - -cat >"$root/coverage.json" <<'EOF' -{ - "files": { - "src/intentproof/canon.py": { - "summary": { - "covered_lines": 2, - "num_statements": 2, - "percent_covered": 66.66666666666666 - } - } - } -} -EOF - -output="" -code=0 -output="$(cd "$root" && bash scripts/check-coverage.sh coverage.json 2>&1)" || code=$? - -if [[ "$code" -ne 1 ]]; then - echo "FAIL: expected exit 1 for missing critical prefix, got ${code}" >&2 - echo "$output" >&2 - exit 1 -fi - -if ! grep -q "no statements in profile, FAIL" <<<"$output"; then - echo "FAIL: expected critical-prefix failure message, got:" >&2 - echo "$output" >&2 - exit 1 -fi - -echo "PASS: missing critical prefix fails the gate" diff --git a/scripts/check-coverage_display_test.sh b/scripts/check-coverage_display_test.sh deleted file mode 100755 index 4c22b30..0000000 --- a/scripts/check-coverage_display_test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# Regression test: displayed percent must not round up past a failing gate. -set -euo pipefail - -pct="$(awk -v c=9399 -v t=10000 'BEGIN { - if (t == 0) { print "0.0"; exit } - printf "%.1f", int(1000 * c / t) / 10 -}')" - -if [[ "$pct" != "93.9" ]]; then - echo "FAIL: expected truncated display 93.9%, got ${pct}%" >&2 - exit 1 -fi - -if awk -v c=9399 -v t=10000 -v min=94 \ - 'BEGIN { exit !(t > 0 && c * 100 >= t * min) }'; then - echo "FAIL: expected integer gate to fail at 9399/10000 min 94%" >&2 - exit 1 -fi - -echo "PASS: display percent matches integer gate semantics" diff --git a/scripts/check-coverage_path_test.sh b/scripts/check-coverage_path_test.sh deleted file mode 100755 index ce1d3aa..0000000 --- a/scripts/check-coverage_path_test.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -# Regression test: absolute and relative coverage JSON paths resolve correctly. -set -euo pipefail - -root="$(mktemp -d)" -trap 'rm -rf "$root"' EXIT - -mkdir -p "$root/scripts" -cp "$(dirname "$0")/check-coverage.sh" "$root/scripts/" - -cat >"$root/scripts/coverage-tiers.conf" <<'EOF' -TOTAL_MIN=50 -CRITICAL_RULES=( - "95:src/intentproof/" -) -EOF - -cat >"$root/coverage.json" <<'EOF' -{ - "files": { - "src/intentproof/canon.py": { - "summary": { - "covered_lines": 2, - "num_statements": 2, - "percent_covered": 100.0 - } - } - } -} -EOF - -if ! (cd "$root" && bash scripts/check-coverage.sh coverage.json >/dev/null); then - echo "FAIL: relative coverage.json path should pass" >&2 - exit 1 -fi - -if ! bash "$root/scripts/check-coverage.sh" "$root/coverage.json" >/dev/null; then - echo "FAIL: absolute coverage.json path should pass" >&2 - exit 1 -fi - -echo "PASS: coverage JSON path resolution" diff --git a/scripts/check-deps-allowlist.sh b/scripts/check-deps-allowlist.sh deleted file mode 100755 index 698999e..0000000 --- a/scripts/check-deps-allowlist.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -# Validate .github/deps-allowlist.yml expiry dates. -exec "$(dirname "$0")/check-allowlist-expiry.sh" "${1:-.github/deps-allowlist.yml}" rule_id cve_id id diff --git a/scripts/coverage-tiers.conf b/scripts/coverage-tiers.conf deleted file mode 100644 index 97696ba..0000000 --- a/scripts/coverage-tiers.conf +++ /dev/null @@ -1,7 +0,0 @@ -# IntentProof tiered coverage (intentproof-sdk-python) - -TOTAL_MIN=90 - -CRITICAL_RULES=( - "95:/intentproof/" -) diff --git a/scripts/run-coverage-gate.sh b/scripts/run-coverage-gate.sh deleted file mode 100755 index 67cae7b..0000000 --- a/scripts/run-coverage-gate.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -# CI-parity coverage gate for local checkpoints and manual runs. -set -euo pipefail - -ROOT="$(cd "$(dirname "$0")/.." && pwd)" -cd "$ROOT" - -if [[ -x "$ROOT/.venv/bin/python" ]]; then - PYTHON="$ROOT/.venv/bin/python" - export PATH="$ROOT/.venv/bin:$PATH" -else - PYTHON=python3 -fi - -COVERAGE=() -if command -v coverage >/dev/null 2>&1; then - COVERAGE=(coverage) -elif "$PYTHON" -m coverage --version >/dev/null 2>&1; then - COVERAGE=("$PYTHON" -m coverage) -else - echo "coverage CLI not found; install dev deps with: pip install -e \".[dev]\"" >&2 - exit 2 -fi - -"$PYTHON" -m pytest -q -"${COVERAGE[@]}" json -o coverage.json -exec bash ./scripts/check-coverage.sh coverage.json diff --git a/scripts/run-osv-scanner-gate.sh b/scripts/run-osv-scanner-gate.sh deleted file mode 100755 index 8d1cece..0000000 --- a/scripts/run-osv-scanner-gate.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash -# Run OSV-Scanner and fail only on CRITICAL or HIGH findings. -# MEDIUM and LOW are reported but non-blocking per SECURITY-PROCESS.md. -set -euo pipefail - -ROOT="${1:-.}" -CONFIG="${2:-.osv-scanner.toml}" -if (( $# > 2 )); then - EXTRA_LOCKFILES=("${@:3}") -else - EXTRA_LOCKFILES=() -fi -OSV_VERSION="${OSV_SCANNER_VERSION:-v2.2.2}" - -if ! command -v osv-scanner >/dev/null 2>&1; then - arch=linux_amd64 - case "$(uname -m)" in - aarch64 | arm64) arch=linux_arm64 ;; - x86_64 | amd64) arch=linux_amd64 ;; - esac - tmp="$(mktemp)" - curl -sSfL \ - "https://github.com/google/osv-scanner/releases/download/${OSV_VERSION}/osv-scanner_${arch}" \ - -o "$tmp" - chmod +x "$tmp" - sudo install -m 755 "$tmp" /usr/local/bin/osv-scanner - rm -f "$tmp" -fi - -args=(scan source --format=table --no-call-analysis=all --allow-no-lockfiles) -if [[ -f "$CONFIG" ]]; then - args+=(--config="$CONFIG") -fi - -if ((${#EXTRA_LOCKFILES[@]} > 0)); then - for lockfile in "${EXTRA_LOCKFILES[@]}"; do - args+=(--lockfile="$lockfile") - done -else - args+=(--recursive "$ROOT") -fi - -output_file="$(mktemp)" -trap 'rm -f "$output_file"' EXIT - -set +e -osv-scanner "${args[@]}" >"$output_file" 2>&1 -status=$? -set -e - -cat "$output_file" - -if [[ "$status" -eq 128 ]] && grep -q "No package sources found" "$output_file"; then - echo "PASS: no scannable dependency manifests (OSV skipped)" - exit 0 -fi - -if [[ "$status" -gt 1 ]]; then - echo "osv-scanner failed unexpectedly (exit $status)" >&2 - exit "$status" -fi - -python3 - "$output_file" <<'PY' -import re -import sys - -with open(sys.argv[1], encoding="utf-8") as fh: - text = fh.read() - -if "No issues found" in text: - print("PASS: no OSV findings") - raise SystemExit(0) - -match = re.search( - r"\((\d+) Critical, (\d+) High, (\d+) Medium, (\d+) Low", - text, -) -if not match: - if re.search(r"\b(GHSA-[a-z0-9-]+|GO-\d{4}-\d+|CVE-\d{4}-\d+)\b", text): - print( - "FAIL: OSV findings present but severity summary missing", - file=sys.stderr, - ) - raise SystemExit(1) - print("PASS: no parseable HIGH/CRITICAL OSV findings") - raise SystemExit(0) - -critical = int(match.group(1)) -high = int(match.group(2)) -if critical or high: - print( - f"FAIL: OSV found {critical} Critical and {high} High findings", - file=sys.stderr, - ) - raise SystemExit(1) - -print( - "PASS: OSV gate " - f"(Critical={critical}, High={high}; Medium/Low non-blocking)" -) -PY