docs: update Docker Compose instructions and add development configuration
This commit is contained in:
245
Idea.md
245
Idea.md
@@ -1,245 +0,0 @@
|
|||||||
Architecture:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Gitea
|
|
||||||
└─ webhook: pull_request_comment / issue_comment
|
|
||||||
└─ gitea-codex-bot API
|
|
||||||
├─ verifies X-Gitea-Signature
|
|
||||||
├─ checks body starts with @codex review
|
|
||||||
├─ queues review job
|
|
||||||
└─ worker:
|
|
||||||
├─ clones repo / fetches PR branches
|
|
||||||
├─ builds git diff + context
|
|
||||||
├─ runs codex headless
|
|
||||||
├─ parses JSON findings
|
|
||||||
└─ posts review comment as codex-bot
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a real Gitea user, e.g. `codex-bot`. Give it a token with minimum access: read repo, read PRs/issues, write comments. Do not use your personal admin token. Gitea exposes Swagger/OpenAPI per instance at `/api/swagger` and `/swagger.v1.json`, so you can wire against your actual server version instead of guessing endpoints. ([Gitea Documentation][3])
|
|
||||||
|
|
||||||
MVP behavior:
|
|
||||||
|
|
||||||
```text
|
|
||||||
User comments:
|
|
||||||
@codex review
|
|
||||||
|
|
||||||
Bot replies:
|
|
||||||
👀 Codex review queued for commit abc123...
|
|
||||||
|
|
||||||
Later edits/posts:
|
|
||||||
## Codex Review
|
|
||||||
|
|
||||||
Verdict: patch mostly correct
|
|
||||||
Confidence: 0.78
|
|
||||||
|
|
||||||
Findings:
|
|
||||||
1. src/auth.ts:42-55
|
|
||||||
Token validation accepts expired tokens in one path.
|
|
||||||
|
|
||||||
2. api/users.ts:88
|
|
||||||
Missing permission check before update.
|
|
||||||
|
|
||||||
No blocking issues found in tests.
|
|
||||||
```
|
|
||||||
|
|
||||||
For v1, post one normal PR timeline comment. Do not fight inline comments yet. Gitea has PR review webhook concepts, but line-level diff review API support can be version-sensitive/awkward; there are still recent reports about API-token support for diff-level review comments being unclear. ([Gitea Documentation][1]) Summary comments are reliable and still useful.
|
|
||||||
|
|
||||||
Core trigger logic:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
if (event !== "pull_request_comment" && event !== "issue_comment") return;
|
|
||||||
if (!payload.is_pull && !payload.pull_request) return;
|
|
||||||
if (payload.sender.username === "codex-bot") return;
|
|
||||||
if (!payload.comment.body.trim().startsWith("@codex review")) return;
|
|
||||||
enqueueReview(payload.repository.full_name, payload.pull_request.number);
|
|
||||||
```
|
|
||||||
|
|
||||||
Job flow:
|
|
||||||
|
|
||||||
```text
|
|
||||||
1. Verify webhook HMAC.
|
|
||||||
2. Dedupe by delivery ID/comment ID.
|
|
||||||
3. Parse command:
|
|
||||||
@codex review
|
|
||||||
@codex review security
|
|
||||||
@codex review tests
|
|
||||||
@codex review --full
|
|
||||||
4. Create “queued” comment.
|
|
||||||
5. Clone/fetch repo into isolated temp dir.
|
|
||||||
6. Checkout PR head.
|
|
||||||
7. Generate:
|
|
||||||
git diff base...head
|
|
||||||
changed file list
|
|
||||||
optional full changed-file content
|
|
||||||
optional test output
|
|
||||||
8. Run Codex headless with JSON schema.
|
|
||||||
9. Validate JSON.
|
|
||||||
10. Post/update review comment.
|
|
||||||
```
|
|
||||||
|
|
||||||
Use SQLite first:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
reviews(
|
|
||||||
id,
|
|
||||||
repo,
|
|
||||||
pr_number,
|
|
||||||
head_sha,
|
|
||||||
trigger_comment_id,
|
|
||||||
status,
|
|
||||||
requested_by,
|
|
||||||
created_at,
|
|
||||||
updated_at,
|
|
||||||
result_json
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Suggested service stack:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Backend: Python FastAPI or Node/TS Fastify
|
|
||||||
Queue: SQLite jobs first, Redis later
|
|
||||||
Runner: Docker worker container
|
|
||||||
Storage: /var/lib/gitea-codex-bot
|
|
||||||
Auth: bot PAT + webhook secret
|
|
||||||
Deployment: docker compose
|
|
||||||
```
|
|
||||||
|
|
||||||
Config:
|
|
||||||
|
|
||||||
```env
|
|
||||||
GITEA_BASE_URL=https://git.example.com
|
|
||||||
GITEA_TOKEN=...
|
|
||||||
GITEA_BOT_USERNAME=codex-bot
|
|
||||||
GITEA_WEBHOOK_SECRET=...
|
|
||||||
OPENAI_API_KEY=...
|
|
||||||
WORKDIR=/var/lib/gitea-codex/worktrees
|
|
||||||
MAX_DIFF_BYTES=200000
|
|
||||||
MAX_REVIEW_MINUTES=10
|
|
||||||
CONCURRENCY=1
|
|
||||||
```
|
|
||||||
|
|
||||||
Good commands to support later:
|
|
||||||
|
|
||||||
```text
|
|
||||||
@codex review
|
|
||||||
@codex review security
|
|
||||||
@codex review performance
|
|
||||||
@codex review tests
|
|
||||||
@codex review --full
|
|
||||||
@codex explain
|
|
||||||
@codex fix
|
|
||||||
@codex fix --branch
|
|
||||||
@codex ignore
|
|
||||||
@codex rerun
|
|
||||||
```
|
|
||||||
|
|
||||||
Best v2 feature: persistent review comment. Instead of spamming new comments, the bot finds its previous comment on that PR and edits it:
|
|
||||||
|
|
||||||
```text
|
|
||||||
<!-- codex-review:head_sha=abc123 -->
|
|
||||||
## Codex Review
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Then reruns replace the same block.
|
|
||||||
|
|
||||||
Best v3 feature: fixes. User comments:
|
|
||||||
|
|
||||||
```text
|
|
||||||
@codex fix finding 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Bot creates a branch:
|
|
||||||
|
|
||||||
```text
|
|
||||||
codex/pr-42-fix-permission-check
|
|
||||||
```
|
|
||||||
|
|
||||||
Then opens a PR or pushes to the existing PR branch only if allowed. Keep this disabled by default. Review-only is safer.
|
|
||||||
|
|
||||||
Security rules that matter:
|
|
||||||
|
|
||||||
```text
|
|
||||||
- Verify X-Gitea-Signature.
|
|
||||||
- Ignore bot’s own comments.
|
|
||||||
- Allowlist repos/orgs.
|
|
||||||
- Never run on untrusted fork PRs unless sandboxed hard.
|
|
||||||
- No Docker socket mount.
|
|
||||||
- No host filesystem mount except temp workdir.
|
|
||||||
- Timeout every job.
|
|
||||||
- Limit diff size.
|
|
||||||
- Redact .env, secrets, keys.
|
|
||||||
- Use bot token, not admin token.
|
|
||||||
- Log prompt + result, but not secrets.
|
|
||||||
```
|
|
||||||
|
|
||||||
Prompt shape for Codex:
|
|
||||||
|
|
||||||
```text
|
|
||||||
You are reviewing a Gitea pull request.
|
|
||||||
|
|
||||||
Focus only on issues introduced by this PR.
|
|
||||||
Prioritize correctness, security, data loss, broken behavior, bad migrations, and missing tests.
|
|
||||||
Avoid style nitpicks.
|
|
||||||
|
|
||||||
Return JSON:
|
|
||||||
{
|
|
||||||
"verdict": "correct" | "has_issues",
|
|
||||||
"confidence": 0.0-1.0,
|
|
||||||
"summary": "...",
|
|
||||||
"findings": [
|
|
||||||
{
|
|
||||||
"severity": "low|medium|high|critical",
|
|
||||||
"file": "...",
|
|
||||||
"line_start": 1,
|
|
||||||
"line_end": 1,
|
|
||||||
"title": "...",
|
|
||||||
"body": "...",
|
|
||||||
"suggestion": "..."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Practical build order:
|
|
||||||
|
|
||||||
```text
|
|
||||||
1. Make bot account + token.
|
|
||||||
2. Add webhook receiver.
|
|
||||||
3. Verify signature + parse @codex review.
|
|
||||||
4. Post “queued” comment.
|
|
||||||
5. Clone repo and generate diff.
|
|
||||||
6. Run Codex headless.
|
|
||||||
7. Post one summary comment.
|
|
||||||
8. Add dedupe + SQLite.
|
|
||||||
9. Add per-repo config file.
|
|
||||||
10. Add optional inline comments/fix branches later.
|
|
||||||
```
|
|
||||||
|
|
||||||
Per-repo config idea:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# .codex-review.yml
|
|
||||||
enabled: true
|
|
||||||
review:
|
|
||||||
default_mode: summary
|
|
||||||
max_diff_bytes: 200000
|
|
||||||
include_tests: true
|
|
||||||
focus:
|
|
||||||
- correctness
|
|
||||||
- security
|
|
||||||
- maintainability
|
|
||||||
ignore:
|
|
||||||
- "dist/**"
|
|
||||||
- "pnpm-lock.yaml"
|
|
||||||
- "*.min.js"
|
|
||||||
commands:
|
|
||||||
allow_fix: false
|
|
||||||
```
|
|
||||||
|
|
||||||
Final recommendation: external webhook bot, summary comments first, bot account + token, Codex headless JSON, SQLite queue. Inline review comments and auto-fix branches are v2/v3. Trying to make the first version “full GitHub Copilot Reviews clone” is how this becomes annoying trash.
|
|
||||||
|
|
||||||
[1]: https://docs.gitea.com/usage/repository/webhooks "Webhooks | Gitea Documentation"
|
|
||||||
[2]: https://developers.openai.com/cookbook/examples/codex/build_code_review_with_codex_sdk "Build Code Review with the Codex SDK"
|
|
||||||
[3]: https://docs.gitea.com/development/api-usage?utm_source=chatgpt.com "API Usage"
|
|
||||||
@@ -69,7 +69,11 @@ uvicorn gitea_codex_bot.main:app --host 0.0.0.0 --port 8000
|
|||||||
## Docker Compose
|
## Docker Compose
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up --build
|
# Local dev image build
|
||||||
|
docker compose -f docker-compose.dev.yml up --build
|
||||||
|
|
||||||
|
# Published image
|
||||||
|
docker compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
## CI
|
## CI
|
||||||
|
|||||||
34
docker-compose.dev.yml
Normal file
34
docker-compose.dev.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
services:
|
||||||
|
# mariadb: # Uncomment this block to run a local MariaDB instance.
|
||||||
|
# image: mariadb:11
|
||||||
|
# restart: unless-stopped
|
||||||
|
# environment:
|
||||||
|
# MARIADB_DATABASE: gitea_codex
|
||||||
|
# MARIADB_USER: gitea_codex
|
||||||
|
# MARIADB_PASSWORD: gitea_codex
|
||||||
|
# MARIADB_ROOT_PASSWORD: rootpass
|
||||||
|
# ports:
|
||||||
|
# - "3306:3306"
|
||||||
|
# volumes:
|
||||||
|
# - ./db:/var/lib/mysql
|
||||||
|
# healthcheck:
|
||||||
|
# test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpass"]
|
||||||
|
# interval: 5s
|
||||||
|
# timeout: 3s
|
||||||
|
# retries: 20
|
||||||
|
|
||||||
|
bot:
|
||||||
|
build: .
|
||||||
|
depends_on:
|
||||||
|
mariadb:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
CODEX_AUTH_JSON_PATH: /root/.codex/auth.json
|
||||||
|
volumes:
|
||||||
|
- ./worktrees:/var/lib/gitea-codex/worktrees
|
||||||
|
- ~/.codex/auth.json:/root/.codex/auth.json:ro # Comment this out if you are not using ChatGPT Auth
|
||||||
|
- //var/run/docker.sock:/var/run/docker.sock
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
services:
|
services:
|
||||||
# mariadb: # Uncomment this block to run a local MariaDB instance.
|
mariadb: # Uncomment this block to run a local MariaDB instance.
|
||||||
# image: mariadb:11
|
image: mariadb:11
|
||||||
# restart: unless-stopped
|
restart: unless-stopped
|
||||||
# environment:
|
environment:
|
||||||
# MARIADB_DATABASE: gitea_codex
|
MARIADB_DATABASE: gitea_codex
|
||||||
# MARIADB_USER: gitea_codex
|
MARIADB_USER: gitea_codex
|
||||||
# MARIADB_PASSWORD: gitea_codex
|
MARIADB_PASSWORD: gitea_codex
|
||||||
# MARIADB_ROOT_PASSWORD: rootpass
|
MARIADB_ROOT_PASSWORD: rootpass
|
||||||
# ports:
|
ports:
|
||||||
# - "3306:3306"
|
- "3306:3306"
|
||||||
# volumes:
|
volumes:
|
||||||
# - ./db:/var/lib/mysql
|
- ./db:/var/lib/mysql
|
||||||
# healthcheck:
|
healthcheck:
|
||||||
# test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpass"]
|
test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "-uroot", "-prootpass"]
|
||||||
# interval: 5s
|
interval: 5s
|
||||||
# timeout: 3s
|
timeout: 3s
|
||||||
# retries: 20
|
retries: 20
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
build: .
|
image: gitea.reversed.dev/space/gitea-codex:latest
|
||||||
depends_on:
|
depends_on:
|
||||||
mariadb:
|
mariadb:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|||||||
Reference in New Issue
Block a user