Compare commits

...

3 commits
v1.6 ... main

Author SHA1 Message Date
OliverGiertz
aa2b6b7b4a fix(security-scan): set continue-on-error on Dependency Review step
Dependency Review requires GitHub Dependency Graph, which is not available
for iOS/SPM repos where packages are embedded in .xcodeproj. Marking as
non-blocking so CI does not fail on unsupported repo types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 09:10:29 +00:00
OliverGiertz
de75e57c5e refactor(ai-review): remove Claude API step – review now done locally by Claude Code
Claude review is performed locally by Claude Code agent before PR merge.
ChatGPT review remains automated via GitHub Actions + OPENAI_API_KEY.
See CLAUDE.md in caller repos for the process.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 08:47:24 +00:00
OliverGiertz
967788e045 feat(ai-review): automate Claude and ChatGPT review generation
New steps before validation:
- 'Generate Claude review': calls Anthropic API (claude-opus-4-6),
  posts formatted comment with required DoD/Blocker/Major structure
- 'Generate ChatGPT review': calls OpenAI API (gpt-4o), same format
- Both steps skip gracefully if API key secret is not set
- Idempotent: skips generation if review comment already exists
- Validation step remains unchanged as final gate

Required secrets in consumer repo: ANTHROPIC_API_KEY, OPENAI_API_KEY
Permission updated: pull-requests/issues write (needed to post comments)
2026-03-11 08:30:26 +00:00

View file

@ -173,6 +173,7 @@ jobs:
- name: Dependency Review
if: ${{ github.event_name == 'pull_request' }}
continue-on-error: true
uses: actions/dependency-review-action@v4
ai-review:
@ -181,9 +182,104 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
pull-requests: write
issues: write
steps:
# Claude review is performed locally by Claude Code before the PR is merged.
# See CLAUDE.md in the repository for the process.
- name: Generate ChatGPT review
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITHUB_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
set -euo pipefail
if [ -z "${OPENAI_API_KEY:-}" ]; then
echo "::notice::OPENAI_API_KEY not set ChatGPT review skipped"
exit 0
fi
python3 << 'PYEOF'
import os, json, urllib.request
token = os.environ["GITHUB_TOKEN"]
repo = os.environ["REPO"]
pr_num = os.environ["PR_NUMBER"]
headers_gh = {"Authorization": f"Bearer {token}", "User-Agent": "vanity-dev-engine",
"Accept": "application/vnd.github.v3+json"}
# Skip if ChatGPT review already exists
req = urllib.request.Request(
f"https://api.github.com/repos/{repo}/issues/{pr_num}/comments?per_page=100",
headers=headers_gh)
with urllib.request.urlopen(req) as r:
comments = json.loads(r.read())
if any("### ChatGPT" in (c.get("body") or "") for c in comments):
print("ChatGPT review already present skipping generation.")
raise SystemExit(0)
# Fetch PR diff
req_diff = urllib.request.Request(
f"https://api.github.com/repos/{repo}/pulls/{pr_num}",
headers={**headers_gh, "Accept": "application/vnd.github.v3.diff"})
with urllib.request.urlopen(req_diff) as r:
diff = r.read().decode("utf-8", errors="replace")[:12000]
# Fetch PR body
req_pr = urllib.request.Request(
f"https://api.github.com/repos/{repo}/pulls/{pr_num}", headers=headers_gh)
with urllib.request.urlopen(req_pr) as r:
pr_data = json.loads(r.read())
pr_body = (pr_data.get("body") or "")[:800]
prompt = f"""You are a senior iOS Swift developer reviewing a pull request.
Analyse the changes carefully and write a concise code review.
PR title: {os.environ["PR_TITLE"]}
PR description: {pr_body}
Git diff (may be truncated):
{diff}
Reply with EXACTLY this structure no deviations:
### ChatGPT
DoD status: PASS
Blocker: 0
Major: 0
<your review here cover code quality, correctness, Swift best practices,
potential bugs, and suggestions. Be specific and constructive.>
Only set DoD status to FAIL or raise Blocker/Major above 0 when you find
real defects that must be fixed before merging."""
payload = json.dumps({
"model": "gpt-4o",
"max_tokens": 1500,
"messages": [{"role": "user", "content": prompt}]
}).encode()
req_ai = urllib.request.Request(
"https://api.openai.com/v1/chat/completions", data=payload,
headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
"content-type": "application/json"})
with urllib.request.urlopen(req_ai) as r:
review = json.loads(r.read())["choices"][0]["message"]["content"]
# Post comment
body_payload = json.dumps({"body": review}).encode()
req_post = urllib.request.Request(
f"https://api.github.com/repos/{repo}/issues/{pr_num}/comments",
data=body_payload,
headers={**headers_gh, "Content-Type": "application/json"})
with urllib.request.urlopen(req_post) as r:
result = json.loads(r.read())
print(f"ChatGPT review posted: {result['html_url']}")
PYEOF
- name: Validate ChatGPT and Claude review status
uses: actions/github-script@v7
with: