From 652ceb55f07c4b77124a68b45b70f355ee404220 Mon Sep 17 00:00:00 2001 From: OpenCode Test Date: Sun, 4 Jan 2026 13:06:31 -0800 Subject: [PATCH] Add PR validation before creating PRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create validate-pr.sh: runs shellcheck, JSON/YAML/Python syntax checks - Update gitea-pr.sh: runs validation before creating PR - Update CLAUDE.md: document PR review policy - ~/.claude repo: linting/validation only - Code repos: full code-reviewer agent review 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 8 ++++ automation/gitea-pr.sh | 10 +++++ automation/validate-pr.sh | 82 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100755 automation/validate-pr.sh diff --git a/CLAUDE.md b/CLAUDE.md index b364e79..d605c0f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,6 +98,14 @@ Notes: - Stash uncommitted state files before switching branches - Delete feature branches after merge - Gitea token stored at `~/.config/gitea-token` +- PRs show as "closed" (not "merged") after rebase - expected + +### PR Review Policy + +| Repo Type | Review Process | +|-----------|----------------| +| ~/.claude | Linting/validation only (shellcheck, JSON/YAML syntax, Python syntax) | +| Code repos | Full review via code-reviewer agent before user approval | ## Component Formats diff --git a/automation/gitea-pr.sh b/automation/gitea-pr.sh index f64f349..eb2f626 100755 --- a/automation/gitea-pr.sh +++ b/automation/gitea-pr.sh @@ -1,9 +1,11 @@ #!/bin/bash # Create a PR in Gitea for the current branch # Usage: gitea-pr.sh [title] [body] +# Runs validation before creating PR set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" GITEA_URL="https://gitea-http.taildb3494.ts.net" REPO="will/claude-code" TOKEN_FILE="$HOME/.config/gitea-token" @@ -23,6 +25,14 @@ if [[ "$BRANCH" == "main" ]]; then exit 1 fi +# Run validation +echo "Running pre-PR validation..." +if ! "$SCRIPT_DIR/validate-pr.sh"; then + echo "Error: Validation failed. Fix issues before creating PR." >&2 + exit 1 +fi +echo "" + # Default title from branch name TITLE="${1:-$BRANCH}" BODY="${2:-Auto-generated PR for $BRANCH}" diff --git a/automation/validate-pr.sh b/automation/validate-pr.sh new file mode 100755 index 0000000..a3f1a85 --- /dev/null +++ b/automation/validate-pr.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# Validate changed files before PR creation +# Runs: shellcheck, JSON validation, Python syntax check + +set -euo pipefail + +ERRORS=0 + +# Get changed files compared to main +CHANGED_FILES=$(git diff --name-only origin/main 2>/dev/null || git diff --name-only HEAD~1) + +echo "Validating changed files..." + +for file in $CHANGED_FILES; do + [[ -f "$file" ]] || continue + + case "$file" in + *.sh) + if command -v shellcheck &>/dev/null; then + if ! shellcheck -S warning "$file" 2>/dev/null; then + echo "FAIL: shellcheck $file" + ((ERRORS++)) + else + echo "OK: $file" + fi + else + echo "SKIP: shellcheck not installed" + fi + ;; + *.json) + if ! python3 -m json.tool "$file" >/dev/null 2>&1; then + echo "FAIL: invalid JSON $file" + ((ERRORS++)) + else + echo "OK: $file" + fi + ;; + *.yaml|*.yml) + if command -v yamllint &>/dev/null; then + if ! yamllint -d relaxed "$file" 2>/dev/null; then + echo "FAIL: yamllint $file" + ((ERRORS++)) + else + echo "OK: $file" + fi + elif python3 -c "import yaml" 2>/dev/null; then + if ! python3 -c "import yaml; yaml.safe_load(open('$file'))" 2>/dev/null; then + echo "FAIL: invalid YAML $file" + ((ERRORS++)) + else + echo "OK: $file" + fi + else + echo "SKIP: no YAML validator" + fi + ;; + *.py) + if ! python3 -m py_compile "$file" 2>/dev/null; then + echo "FAIL: Python syntax $file" + ((ERRORS++)) + else + echo "OK: $file" + fi + ;; + *.md) + echo "OK: $file (markdown, no validation)" + ;; + *) + echo "SKIP: $file (no validator)" + ;; + esac +done + +if [[ $ERRORS -gt 0 ]]; then + echo "" + echo "Validation failed with $ERRORS error(s)" + exit 1 +fi + +echo "" +echo "All validations passed" +exit 0