diff --git a/.github/workflows/cora-review.yml b/.github/workflows/cora-review.yml index 039ba0b..5a221d2 100644 --- a/.github/workflows/cora-review.yml +++ b/.github/workflows/cora-review.yml @@ -24,14 +24,21 @@ jobs: # CORA_API_KEY (pull_request_target). A PR-supplied .cora.yaml could set # provider.base_url and exfiltrate the key. CORA_BASE_URL (env) always # takes precedence over project config, so require it to be pinned. - - name: Require pinned CORA_BASE_URL + - name: Require the review secrets env: + CORA_API_KEY: ${{ secrets.CORA_API_KEY }} CORA_BASE_URL: ${{ secrets.CORA_BASE_URL }} + CORA_MODEL: ${{ secrets.CORA_MODEL }} run: | - if [ -z "$CORA_BASE_URL" ]; then - echo "::error::Secret CORA_BASE_URL must be set so a PR-supplied .cora.yaml cannot redirect the API key." - exit 1 - fi + # An empty secret must fail the job: a skipped or fallback review is not a pass. + missing=0 + for name in CORA_API_KEY CORA_BASE_URL CORA_MODEL; do + if [ -z "${!name}" ]; then + echo "::error::Secret $name is empty or missing. Cora Review cannot run, and that must not pass silently." + missing=1 + fi + done + exit "$missing" - name: Checkout PR head uses: actions/checkout@v4 diff --git a/AGENTS.md b/AGENTS.md index e179a20..ee1f7dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,9 @@ code structure are in `AGENT.md`. - CI runs the same gates: `cargo fmt --all -- --check` and `cargo clippy --all-targets --features tree-sitter -- -D warnings`. - User-visible changes go under `## [Unreleased]` in `CHANGELOG.md`. +- Before committing: review the staged diff (`cora review --staged`, or the + `/cora-review` skill) and run `scripts/setup-hooks.sh` once per clone so the + pre-commit hook enforces the same gates. Never `--no-verify` past a finding. ## Conventions enforced by CI diff --git a/CHANGELOG.md b/CHANGELOG.md index fcd9dcd..1d27a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- The `Cora Review` workflow now fails with an error naming each empty secret (`CORA_API_KEY`, `CORA_BASE_URL`, `CORA_MODEL`) instead of running without them. - The `Cora Review` job no longer gets cancelled on larger pull requests: its time limit is 30 minutes (the review action allows up to three LLM attempts of 10 minutes each). ## [0.19.0] - 2026-10-16 diff --git a/scripts/hooks/pre-commit b/scripts/hooks/pre-commit new file mode 100755 index 0000000..21850a6 --- /dev/null +++ b/scripts/hooks/pre-commit @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Repo pre-commit hook: fmt, clippy (when Rust files are staged), then the cora gate. +# Enable once per clone with scripts/setup-hooks.sh. +set -uo pipefail + +CORA_BIN="${CORA_BIN:-cora}" + +if ! cargo fmt --all -- --check >/dev/null 2>&1; then + echo "cargo fmt --all -- --check failed. Run: cargo fmt --all" >&2 + exit 1 +fi + +if git diff --cached --name-only | grep -q '\.rs$'; then + if ! cargo clippy --all-targets --features tree-sitter -- -D warnings >/dev/null 2>&1; then + echo "cargo clippy failed. Run it and fix the warnings before committing." >&2 + exit 1 + fi +fi + +# Already reviewed (by an agent or by `cora review --staged`)? Then it passes. +"$CORA_BIN" hook verify --quiet +case $? in + 0) exit 0 ;; + 10) + echo "cora: the staged diff was reviewed and the verdict blocks the commit." >&2 + exit 2 + ;; +esac + +"$CORA_BIN" review --staged --ci --severity major --format compact +case $? in + 0) exit 0 ;; + 2) + echo "cora review found blocking issues. Do not use --no-verify to get past them." >&2 + exit 2 + ;; + *) + echo "cora review hit a tooling error. That is not a pass." >&2 + exit 0 + ;; +esac diff --git a/scripts/setup-hooks.sh b/scripts/setup-hooks.sh new file mode 100755 index 0000000..774c1ba --- /dev/null +++ b/scripts/setup-hooks.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# Point git at the committed hooks in scripts/hooks (once per clone). +set -euo pipefail +cd "$(git rev-parse --show-toplevel)" +chmod +x scripts/hooks/pre-commit +git config core.hooksPath scripts/hooks +echo "git hooks now come from scripts/hooks"