fix(ci): make /pi invocable on org-owned repos via API permission check #14

Merged
alex merged 1 commit from pi/issue13-1786732047274 into master 2026-08-15 20:58:04 +00:00
Contributor

Fixes #13

Problem

The job-level guard in pi.yml:

if: |
  (startsWith(forgejo.event.comment.body, '/pi ') && forgejo.event.sender.login == forgejo.repository_owner)

compares the commenting user against forgejo.repository_owner. On org-owned repos (org/repo) the repository owner is the organization, so sender.login == repository_owner can never be true — the job is always skipped and /pi never runs.

Fix

Authorization is now enforced per-event by an Authorize invoker step that queries the Forgejo API for the sender's effective permission on the repository (GET /repos/{owner}/{repo}/collaborators/{user}/permission, authenticated as secrets.PI_TOKEN):

  • owner or admin permission → the agent runs
  • anything else (write/read/none) → the job fails with a clear ::error:: message

This covers both user/repo and org/repo layouts uniformly, since org owners/admins get owner/admin on their org's repos.

The job-level if: now only gates on the /pi command prefix (issue comment, review comment or review body), which also restores triggering from PR review bodies (review.content) that was dropped in 6fb8f3b.

Notes

  • Verified live against forge.l3x.in: repo owner → owner (allowed), non-collaborator → none (denied). The permission query requires the pi user behind PI_TOKEN to be site admin or repo/org admin (it is a site admin here).
  • For org repos, PI_TOKEN and the PROVIDER/MODEL/THINKING_LEVEL/MY_FORGEJO_PUBLIC_URL vars must exist at org level — documented in docs/setup-pi-bot.md.
  • Unauthorized invocations fail the run (red + error annotation) rather than being silently skipped, so abuse attempts are visible.
Fixes #13 ## Problem The job-level guard in `pi.yml`: ```yaml if: | (startsWith(forgejo.event.comment.body, '/pi ') && forgejo.event.sender.login == forgejo.repository_owner) ``` compares the **commenting user** against `forgejo.repository_owner`. On org-owned repos (`org/repo`) the repository owner is the *organization*, so `sender.login == repository_owner` can never be true — the job is always skipped and `/pi` never runs. ## Fix Authorization is now enforced per-event by an **Authorize invoker** step that queries the Forgejo API for the sender's effective permission on the repository (`GET /repos/{owner}/{repo}/collaborators/{user}/permission`, authenticated as `secrets.PI_TOKEN`): - `owner` or `admin` permission → the agent runs - anything else (`write`/`read`/`none`) → the job fails with a clear `::error::` message This covers both `user/repo` and `org/repo` layouts uniformly, since org owners/admins get `owner`/`admin` on their org's repos. The job-level `if:` now only gates on the `/pi ` command prefix (issue comment, review comment or review body), which also restores triggering from PR review bodies (`review.content`) that was dropped in 6fb8f3b. ## Notes - Verified live against `forge.l3x.in`: repo owner → `owner` (allowed), non-collaborator → `none` (denied). The permission query requires the `pi` user behind `PI_TOKEN` to be site admin or repo/org admin (it is a site admin here). - For org repos, `PI_TOKEN` and the `PROVIDER`/`MODEL`/`THINKING_LEVEL`/`MY_FORGEJO_PUBLIC_URL` vars must exist at **org level** — documented in `docs/setup-pi-bot.md`. - Unauthorized invocations fail the run (red ❌ + error annotation) rather than being silently skipped, so abuse attempts are visible.
alex merged commit f1818577da into master 2026-08-15 20:58:04 +00:00
alex deleted branch pi/issue13-1786732047274 2026-08-15 20:58:04 +00:00
Sign in to join this conversation.
No reviewers
No labels
dependencies
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
alex/.profile!14
No description provided.