Skip to content

docs(281): design plan for PR-comment LLM synthesis layer #189

docs(281): design plan for PR-comment LLM synthesis layer

docs(281): design plan for PR-comment LLM synthesis layer #189

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
shellcheck:
name: shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run shellcheck
run: |
shellcheck --version
shellcheck \
pipeline/queries/_tests/test_canonical.sh \
pipeline/queries/_tests/test_queries_integration.sh \
pipeline/queries/_tests/test_gojq_parity.sh \
pipeline/queries/_tests/test_cross_repo_ops.sh \
pipeline/queries/_tests/smoke_test_real_catalog.sh \
pipeline/fetch-catalogs.sh \
pipeline/publish-catalog.sh \
pipeline/verify-index.sh \
pipeline/run-cross-repo-query.sh \
pipeline/_tests/test_substrate.sh \
pipeline/_tests/test_audit_core.sh \
.github/actions/audit-core/scripts/detect-languages.sh \
extractors/swift/tests/test_package_graph.sh \
extractors/swift/tests/test_type_catalog_heritage.sh \
extractors/typescript/tests/test_smoke.sh
pipeline:
name: pipeline + typescript extractor
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: extractors/typescript/package-lock.json
- name: Cache gojq
# gojq is the engine the binary will embed (per ADR-0005). The parity
# test below verifies every query produces semantically equivalent
# output under gojq and system jq, so the binary is safe to ship.
id: cache-gojq
uses: actions/cache@v5
with:
path: /usr/local/bin/gojq
key: gojq-${{ runner.os }}-0.12.19
- name: Install gojq
if: steps.cache-gojq.outputs.cache-hit != 'true'
run: |
GOJQ_VERSION=0.12.19
curl -sSL "https://github.com/itchyny/gojq/releases/download/v${GOJQ_VERSION}/gojq_v${GOJQ_VERSION}_linux_amd64.tar.gz" \
| tar -xz -C /tmp
sudo mv "/tmp/gojq_v${GOJQ_VERSION}_linux_amd64/gojq" /usr/local/bin/gojq
- name: Verify toolchain
run: |
jq --version
gojq --version
node --version
- name: Install TypeScript extractor deps
working-directory: extractors/typescript
run: npm ci
- name: Syntax-check extractor entrypoints
run: |
node --check extractors/typescript/type-catalog.mjs
node --check extractors/typescript/function-catalog.mjs
node --check extractors/file-hashes/file-hashes.mjs
node --check hooks/pre-commit-audit.mjs
- name: Run TypeScript extractor unit tests
working-directory: extractors/typescript
run: npm test
- name: Run pre-commit hook tests
# Hook tests spawn the type-catalog extractor as a subprocess; reuse
# the npm-ci'd node_modules under extractors/typescript/ rather than
# installing a duplicate at repo root.
run: node --test hooks/test/*.test.mjs
- name: Smoke-test TypeScript extractor
run: extractors/typescript/tests/test_smoke.sh
- name: jq canonical helper tests
run: pipeline/queries/_tests/test_canonical.sh
- name: jq query integration tests
run: pipeline/queries/_tests/test_queries_integration.sh
- name: gojq / jq parity tests
run: pipeline/queries/_tests/test_gojq_parity.sh
- name: cross-repo substrate tests (hermetic, file:// backend)
run: pipeline/_tests/test_substrate.sh
- name: audit-core helper tests (detect-languages.sh)
run: pipeline/_tests/test_audit_core.sh
- name: cross-repo operational-safety tests (preflight + coverage + wrapper)
run: pipeline/queries/_tests/test_cross_repo_ops.sh
go:
name: go binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Generate embedded queries
run: go generate ./...
- name: Verify embedded queries + extractors are in sync with canonical sources
# The committed copies under cmd/code-audit/{queries,extractors}/ are
# what the Go module proxy ships at a tagged commit. If a PR touches
# pipeline/queries/*.jq or extractors/<lang>/* without regenerating and
# committing the embeds, `go install ...@tag` would ship a stale (or
# broken) binary. This gate forces the regen-and-commit step into the
# same PR.
#
# Uses `git status --porcelain` rather than `git diff --exit-code` so
# NEW embed files appear in the gate output — `git diff` only inspects
# tracked paths and would silently ignore an untracked
# cmd/code-audit/queries/foo.jq produced by `go generate`.
run: |
status="$(git status --porcelain -- cmd/code-audit/queries cmd/code-audit/extractors)"
if [ -n "$status" ]; then
echo "::error::cmd/code-audit/{queries,extractors}/ are out of sync with pipeline/queries/ or extractors/. Run 'go generate ./...' locally and commit the result." >&2
echo "$status" >&2
exit 1
fi
- name: Go vet
run: go vet ./...
- name: Go test
run: go test ./...
- name: Go build
run: go build -o /tmp/code-audit ./cmd/code-audit
- name: Verify ldflags Version override is wired
# The release pipeline injects the tag via `-ldflags -X cli.Version=...`.
# `-X` only works against `var` symbols — a `const` target is silently
# ignored at link time. Catch the regression here rather than at the
# first tag push, where it would ship a binary stamped with the
# build-time default.
run: |
go build -ldflags="-X github.com/jakebromberg/code-audit-pipeline/internal/cli.Version=ci-verify" -o /tmp/code-audit-version ./cmd/code-audit
got=$(/tmp/code-audit-version version | tr -d '[:space:]')
if [ "$got" != "ci-verify" ]; then
echo "ldflags -X cli.Version was ignored (got=$got). Is Version a const? It must be a var." >&2
exit 1
fi
- name: Goreleaser config check
# Catches schema errors and build misconfig without needing a tag or
# touching publish credentials. Skips publish/sign so it's safe on PRs.
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: check
python:
name: python extractor
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
# 3.12 is the floor that exercises PEP 695 `type X = ...` aliases —
# 3.11 silently skips that test class. The extractor itself works on
# 3.9+ (declared in manifest.toml); CI just pins the upper end of
# the supported matrix so we don't drift.
python-version: '3.12'
- name: Verify toolchain
run: |
python3 --version
jq --version
- name: Syntax-check extractor entrypoints
run: |
python3 -m py_compile extractors/python/type_catalog.py
python3 -m py_compile extractors/python/function_catalog.py
python3 -m py_compile extractors/python/_lib.py
- name: Run Python extractor unit tests
working-directory: extractors/python
# Stdlib `unittest` discovery; no third-party deps required (the
# extractor is itself stdlib-only).
run: python3 -m unittest discover -s tests -t . -v
- name: Smoke-test Python extractor against fixtures
# Both catalogs should be non-empty and jq must accept the JSON
# output — surfaces any regression in stdout framing or wrapper
# shape before the unit-test layer reports it.
run: |
python3 extractors/python/type_catalog.py \
--root extractors/python/fixtures --output /tmp/py-cat.json
python3 extractors/python/function_catalog.py \
--root extractors/python/fixtures --output /tmp/py-fn.json
jq -e '.entries | length > 0' /tmp/py-cat.json > /dev/null
jq -e '.entries | length > 0' /tmp/py-fn.json > /dev/null
swift:
name: swift extractor
runs-on: macos-latest
defaults:
run:
working-directory: extractors/swift
steps:
- uses: actions/checkout@v6
- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode.app
- name: Verify toolchain
run: |
swift --version
jq --version
- name: Cache SwiftPM build
uses: actions/cache@v5
with:
path: |
extractors/swift/.build
~/Library/Caches/org.swift.swiftpm
key: ${{ runner.os }}-swiftpm-${{ hashFiles('extractors/swift/Package.resolved') }}
restore-keys: |
${{ runner.os }}-swiftpm-
- name: Build
run: swift build
- name: Integration tests (package-graph)
run: tests/test_package_graph.sh
- name: Integration tests (type-catalog heritage — extends, conforms_to, wraps_notification_name)
run: tests/test_type_catalog_heritage.sh