Repository navigation
feat(ci): sync open issues to a contributor Project with suggested areas and owners - #6995
Conversation
…eas and owners Adds a GitHub Actions workflow and Python helpers that keep a private GitHub Project of open issues for core contributors. Each issue gets a Suggested area (28 areas, mapped from file paths) and a Suggested owner (ranked from merged-PR history and git blame per area). The sync only adds open issues and fills blank suggestion fields. It never sets assignees, labels or human-edited values, defaults to a dry run, and is skipped until AO_CONTRIBUTOR_PROJECT_URL is configured.
🏆 Review leaderboardOct 14–21, 2026 · UTC
Ranked by distinct external PRs reviewed, then review rounds, then PR comments. Self-activity and bot activity are excluded. Show 7 more reviewers
|
The --repo default was computed from ROOT on every run, so tests that patch ROOT to a shallow temp dir (e.g. /tmp on Linux runners) raised IndexError. Resolve it once from the script's location, matching ownership_extract.py.
…oject sync Adding an issue that is already on the Project returns the existing item, so when the Project item list lags, an issue that looked new could already hold a human value. Recheck every item before filling, not only pre-existing ones. One timeout, dropped connection, HTTP 5xx or GraphQL internal error aborted a run of ~1,500 calls. Retry those once after 5 seconds, with a budget separate from the rate-limit retry, and log each retry.
- Route issues without a hand-reviewed area by a single area:<id> label, then a confident text match, else Needs area review. - Rebuild owners daily in CI from merged PRs and reviews plus a committed blame snapshot, instead of committing the owner map. - Record bot-written values in a Sync record field so they refresh while human edits stay untouched. - Archive closed issues and bring back reopened ones the bot archived. - Sort and dedupe issue pages, limit the App token to what the sync needs, warn when the owner build fails or goes stale, and compact the data maps.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
ronishrohan
left a comment
There was a problem hiding this comment.
Live verification found two issues to fix before merge: the P1 reopen failure and the P2 area/owner mismatch below.
Nine of eleven live scenarios passed. All 114 existing Python tests and a fresh owner-data build passed. Live testing used a private scratch Project and disposable issues in a private test repository. Production Project settings, existing issues and PR code were untouched; the QA Project is now closed and the test repository archived.
The narrower App installation token and the GitHub Actions cache lifecycle were not exercised. Live sync used an authorized CLI OAuth token.
… area The unarchive mutation was built by chained replaces on the archive one, which produced UnunarchiveProjectV2ItemInput and stopped every later sync. Write it out and test both mutation names. When a human sets Suggested area, suggest owners for that area. Unowned areas clear only a bot-written owner; unknown options leave it alone.
ronishrohan
left a comment
There was a problem hiding this comment.
Approved after retesting fc43317.
All 116 Python tests, 10 local CLI scenarios, and 14 live GitHub scenarios passed. Area-map validation passed too.
Manually verified dry-run safety, initial population, unchanged reruns, human area and owner edits, owned/unowned/custom area routing, manual archives, close/reopen recovery, draft preservation, and invalid-owner fallback. Both reported bugs are fixed: reopened issues return correctly and the next sync makes zero writes; owner suggestions follow the preserved human-selected area.
Live checks used a private QA Project and disposable test issues. The Project is closed and the fixture repository archived after testing. Production settings and existing issues were untouched.
No remaining blockers from this retest. The full repository CI job is still running, so wait for that to pass before merging. The narrower App installation token and the Actions cache lifecycle were not exercised live.
Withdrawing approval while I address bulk-sync rate limits, interrupted-write recovery, archive growth, incremental owner extraction, and owner-build scheduling.
- Exit 4 and fail the job when a deferred sync wrote nothing, so a stuck backlog is visible instead of staying green. - At capacity, skip only new adds; existing items still update and the job fails with an error until the board is rotated. - Defer rate-limit waits that would run past 30 minutes, before the 45-minute job timeout. - Save PR evidence only when a failed extraction made progress, owners built, or nothing was cached yet. - Key the owner cache on owner scripts and data, not sync_project.py.
|
@ronishrohan thanks for the scaling work. I pushed
All 137 tests pass. The README and the PR description are updated. I have not linted this commit or run it live. I'm least sure about two things: the |
ronishrohan
left a comment
There was a problem hiding this comment.
Approved after checking 8d1e69b.
All 137 Python tests pass. The stateful 512-issue backfill completes across 26 runs within the 100-write limit. All GitHub CI checks pass, including the full frontend suite, Linux browser integration, renderer smoke, Mac helpers and Gitleaks. The privileged owners/sync jobs correctly skip PR runs.
Manual GitHub testing passed 19 scenarios before the final commit and six further checks on this head. Verified bounded writes, stop/resume, interrupted-update recovery, preservation of human edits, close/reopen handling and unchanged reruns. The final capacity check used the real API with only the in-process capacity threshold lowered; existing items updated while new additions were skipped with a nonzero exit.
Proof: private QA Project, final backfill fixtures, and CI run. The QA Project is closed and the fixture repository archived. Production settings and existing issues were untouched.
The narrowed App installation token and hosted Actions cache lifecycle still need their post-merge check; live tests used the authorized CLI OAuth token. Board rotation remains an explicit administrator operation, with no automatic deletion of archive history.
Code changes: +1902 -0
Tests: +2004 -0
Others: +1477 -0
What
Adds a workflow that keeps a private org GitHub Project of every open issue. Each issue gets a suggested product area and up to three suggested owners. Core contributors filter the board by area, or by their own name, to find work.
Why
About 500 issues are open and nothing says who should look at which one. This gives every issue a starting owner, based on who actually works in that part of the code.
How
The sync runs every 15 minutes and manually. Issue events are reconciled on the next scheduled run.
data/issue-areas.json(about 490 issues)area:<id>label on the issueNeeds area reviewSuggested owner.Owners rebuild once a day in a separate job with its own concurrency group, and the result is cached by source/data hash and UTC date. Per area, each person scores:
data/blame-lines.json)Core means 10+ merged PRs in 90 days.
data/core-overrides.jsonadds or drops people.Human edits win. A
Sync recordfield stores what the bot last wrote, and the bot only changes a field that is blank or still holds its own value.It never assigns, adds labels, comments, or touches items from other repos. The App token is limited to this repo, org Projects write and Issues read.
Review focus:
apply_planinsync_project.py(the write path) and the cache steps in the workflow.Left out on purpose:
area:*labels exist yet. A labelling rule for the repo bot is drafted but not enabled, so most new issues land inNeeds area reviewuntil it is.scripts/blame_snapshot.py, see README). Live blame took over 15 minutes per run.main.Scaling and recovery
complete: false, a reason and remaining-item count, and exit 3. The workflow shows the JSON summary and a warning. A deferred run that wrote nothing exits 4 and fails the job, so a stalled backlog is visible; other errors also fail the job. A rate-limit wait that would run past 30 minutes defers instead of sleeping into the 45-minute job timeout.sync_project.py, so sync-only edits keep today's owners and generated bytecode cannot change the key between restore and save. PR evidence is saved only when a failed extraction made progress, owners built, or nothing was cached yet, so a failing build does not save a new cache every 15 minutes.Setup after merge (admin)
Nothing runs until step 1 is done.
AO_CONTRIBUTOR_PROJECT_URL.AO_CONTRIBUTOR_APP_CLIENT_IDand the secretAO_CONTRIBUTOR_APP_PRIVATE_KEY.If the owner build fails or the owners are more than 7 days old, the run shows a warning annotation.
Testing
8d1e69ba7f, all 137 Python tests, area-map validation and workflow lint pass. Six further live checks pass: dry-run, the 10-write limit, resume, existing-item updates while a lowered test capacity blocks additions, a later addition after that threshold clears, and a zero-write rerun. The real API was used for reads and writes; the capacity threshold alone was lowered in process. The private QA Project is closed and the fixture repository archived again.fc43317; the corresponding Linux integration passed in GitHub CI.The narrowed App installation token and hosted Actions cache restore/save path have not been exercised live. The live sync checks used the authorized CLI OAuth token. Production Project settings and existing issues were untouched.
Checklist
main