Story #2608 :: Task: Fix the formal-review importer and derive the Reviewer achievement from it - #2612
Open
herzog0 wants to merge 4 commits into
Open
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
15 tasks
herzog0
force-pushed
the
teo/2541-source-library-review
branch
2 times, most recently
from
August 14, 2026 15:26
ea950dc to
f1c244d
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 14, 2026 19:57
f1c244d to
a567bc4
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 14, 2026 20:07
a567bc4 to
96a6ca4
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
2 times, most recently
from
August 17, 2026 17:22
0421fcb to
3dc8fc4
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
2 times, most recently
from
August 17, 2026 23:06
0f3bac8 to
e5f7d9b
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 18, 2026 14:28
e5f7d9b to
7addb0e
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 21, 2026 14:48
7addb0e to
634e7ee
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 24, 2026 13:40
634e7ee to
3794f9f
Compare
herzog0
force-pushed
the
teo/2541-source-library-review
branch
from
August 24, 2026 19:22
3794f9f to
514afc8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue: #2608
teo/2541-source-library-versioningSummary & Context
Everything about formal reviews, in one place: the boost.org results importer, the admin button
that runs it, and the Reviewer achievement derived from what it imports. They are one context -
versions.models.Reviewis written by exactly one thing, and that thing is this importer, so abadge counting reviews and the command that produces them are not really separable.
Changes
The importer, rewritten
import_reviewswas scraping a page boost.org no longer serves, and creating near-duplicate rowson every run. The URL changes:
https://www.boost.org/community/review_schedule.html(gone - no usable tables)https://www.boost.org/doc/formal-reviews/review-results.htmlThe new page is generated from
boostorg/website-v2-docs/formal-reviews/modules/ROOT/pages/review-results.adoc, so its shapefollows that document rather than the old hand-written HTML. Open it before reviewing - almost
every change below follows from something visible on it.
The release-blocking part: the section now opens with a year-navigation table, and the old code
took the first table after the heading. On the live page that means the import would write about
two junk rows instead of the 286 real reviews, and report success.
h2.Verified against the live page: 27 tables in the section, 26 match, 286 rows parse, 0 without a
result; the rejected one is the navigation table.
<iframe srcdoc="...">; thecontent iframe is the one with the longest
srcdoc.requestsfalls back toISO-8859-1 per the HTTP spec and mojibakes every accented name (
Joaquín M López Muñoz->JoaquÃn M López Muñoz).dates), so a re-import updates in place instead of adding a near-duplicate, and pre-existing
duplicates collapse.
CommandErrorrather than returning quietly, whichmatters now that this also runs from a task.
--cleanmoved inside the import transaction and afterthe parse, so a failed scrape can no longer leave the reviews deleted.
discard_source_achievementsfirst. Agrant reaches its source through a generic FK with no referential integrity, so a bare delete
would leave one still counting toward a threshold.
github_link, matched on hostname. The key is omittedotherwise, so a re-import can never erase a link entered by hand.
ReviewAdmin: id, review-manager and scraped-review-manager columns,-idordering, widersearch, and the
select_related/prefetch_relatedthe results column needs.The admin button
An Import Reviews from boost.org button on the review changelist, built on the task-button
mixin from PR 2. Gated on delete permission rather than change, because the command can merge
duplicate reviews and delete the losing rows along with the achievements sourced from them, and
with a confirmation page that says what may be deleted in the same words as the button's help
text.
The Reviewer achievement
_iter_library_reviewyields(member, review)for every submitter that has a linked user.Submitters are
CommitAuthorrows and only some are claimed; an unlinked one is skipped ratherthan guessed at.
--sourcechoices.import_reviews_taskrunsbackfill_achievements --source library-reviewafter the import,scoped to this one source so it does not walk the commit and library tables the task never
touches.
test_reconcile_preview_blocks_an_incomplete_catalogue, which needs a wired source to meananything - it deletes this achievement's catalogue row to prove the reconcile preview refuses to
offer Apply against an incomplete catalogue.
check the reported count before running it for real.
Release Dates") makes the command find zero tables and raise. That is deliberate: failing loudly
beats importing nothing and reporting success. Same for aborting the run on a row with fewer
than five cells - one malformed year costs the whole import rather than one table.
on the same dates by the same submitter would collapse. There are none today, and the dates
component is what keeps re-reviews separate.
grants through
discard_source_achievements; one that reassigns a submitter leaves a stalegrant until someone reconciles. That is the engine's deliberate split.
submission is far rarer than a commit. Worth sanity-checking against real data before the first
production backfill.
means the count moves for reasons unrelated to reviewing.
Screenshots
Peer-review testing steps
Everything runs from the admin button, which is the path production will use. Setup:
just load_production_data,just migrate,docker compose up. Openhttps://www.boost.org/doc/formal-reviews/review-results.html in a tab first - most of these checks
are "does the admin agree with that page".
The import
/admin/versions/review/, note the row count in the paginator before doing anything. On aproduction copy this is the pre-existing set, duplicates included.
duplicate reviews, their results, and achievements sourced from them may be deleted. Continue, and
watch the status line reach Finished in place.
dates - there should be none. Press the button a second time: the count does not move, which is the
fingerprint doing its job.
Joaqu. The row must readJoaquín M López Muñoz, notJoaquÃn.has text: the FK is only filled when the scraped name matches a
CommitAuthorexactly, and the rawtext is kept either way. Add a
CommitAuthorwith that exact name at/admin/libraries/commitauthor/add/and re-import: the resolved column fills in on the next run andthe raw column is untouched.
github_link, save,and re-import: the value is still there, because only GitHub hostnames are written.
urlinversions/management/commands/import_reviews.pyat a page with no result tables and press the button again. The status line must read Failed with
the
CommandErrormessage, and/admin/versions/review/must still have every row. Put the URLback.
Review, the button must notrender on the changelist, and POSTing its URL must be refused. A GET on that URL must enqueue
nothing.
The Reviewer badge
/admin/badges/badge/- the Reviewer row's Automatic column is now a tick, the ladder reads1 / 2 / 3 / 4 / 5, and Holders is non-zero after the import. The import ran the backfill itself;nothing else had to be pressed.
/admin/badges/achievementsyncrun/- alibrary-reviewrow with trigger admin and yourname under Triggered by, because the button hands the actor down to the backfill it runs. A
second import adds another row with Added 0.
/admin/badges/userachievement/filtered to Achievement: Library Review - each Source columnlinks to the review row that justified it. Click one and confirm the submitter is the member on the
grant.
Submitters, then find one of them at
/admin/libraries/commitauthor/whose User field isempty. That person holds no Reviewer grant, which is deliberate - an unclaimed
CommitAuthorisskipped rather than guessed at. Point the User field at a test member, save, then press Backfill
achievements with Source = Library Review on the grant changelist. That member now has a
Reviewer grant and Bronze, the per-member page states the count in words, and nothing else moves.
CommitAuthorat a different member andpress Backfill: the first member's grant stays, because backfill only adds. Then Reconcile
achievements with Source = Library Review: the preview reports one addition and one removal,
and applying it moves both the grant and the badge. That split between the two commands is the
behaviour called out under Risks, worth seeing once rather than taking on trust.
Backend