Add the bug tracker Web API resources and fields.
Review Request #15318 — Created Sept. 17, 2026 and updated
This change adds API resources for the new bug tracker features:
/api/bug-trackers/and/api/bug-trackers/<id>/:Read-only listings of the bug trackers usable by the requesting user.
Disabled trackers, the sentinel, and trackers whose user conditions the
requester fails are never listed. Configuration management stays in the
administration UI for this phase.
/api/bug-trackers/<id>/bugs/?q=&review-request=:Typeahead search, implemented with
BaseBugTracker.search_bugs(). This
will the per-integration ajax views that were implemented for Trello and
Asana. The endpoint requires a review request and verifies, server-side,
that the tracker applies to it and that the requester passes the
tracker's user conditions.
conditions.A bugs field on the review request and draft resources:
Entries of
{id, tracker, url?, summary?}, with url/summary omitted
when the requester fails the tracker's conditions. Draft writes take
comma-separated[<tracker-id>:]<bug-id>tokens (bare IDs go to the
default tracker, or stay unattributed). A write replaces the links on
every tracker the writer passes conditions for; links on trackers the
writer fails are preserved untouched, and naming such a tracker is an
error.
/api/review-requests/?bug=<id>and/api/review-requests/?bug-tracker=<id>:Filters on the review request list resource, joining against the bug
relations.
Ran unit tests.
| Summary | ID |
|---|---|
| onokvwrqnmxszlwktrmzsotyoxsotrux |
| Description | From | Last Updated |
|---|---|---|
|
I don't know what it is, but this description feels a bit opaque, kind of like a technical piece of … |
|
|
|
'typing.ClassVar' imported but unused Column: 5 Error code: F401 |
|
|
|
'typing.Any' imported but unused Column: 5 Error code: F401 |
|
|
|
continuation line under-indented for visual indent Column: 44 Error code: E128 |
|
|
|
continuation line under-indented for visual indent Column: 44 Error code: E128 |
|
|
|
continuation line under-indented for visual indent Column: 44 Error code: E128 |
|
|
|
line too long (82 > 79 characters) Column: 80 Error code: E501 |
|
|
|
This function feels pretty complex, given the two large conditionals. The biggest piece is the entry-building code, which is subtly … |
|
|
|
JSONDict? |
|
|
|
We should probably log here? |
|
|
|
JSONDict |
|
|
|
I get what this is doing but it feels very unclear that this is going to be None or a … |
|
|
|
We should log here. |
|
|
|
What are we ignoring here and in all the other spots below? |
|
|
|
Can you sort the keys in here? |
|
|
|
Here and below, what are user conditions? I feel like we should be clear in the docs. |
|
|
|
Why the type()? We can get it via the instance. (If it's because we use ClassVar, that only impacts setting.) |
|
|
|
We should log an exception here. |
|
|
|
We should log an exception here. |
|
|
|
It feels like this is a purpose for this resource, but not the only purpose. This is for querying of … |
|
|
|
I really don't like using this form. It hurts readability and other variations on this form easily lead to bugs. … |
|
|
|
This is a pk, but for Local Sites we need to use a display ID. Otherwise we'd grab the wrong … |
|
|
|
We don't use this form and it's doing too much. Can you pull this set-building out and then check against … |
|
|
|
It doesn't look like we need to pull out service_cls, since we're just using it immediately below. I also don't … |
|
|
|
Can we set these somewhere so they're not magic numbers in here? |
|
|
|
The wording could be a bit less terse on the legacy bit. Can we flesh out the guidance a bit? … |
|
|
|
All the same notes as above. |
|
|
|
And here. |
|
|
|
This form makes sense to us but I think it's error-prone for someone working with this. I think it'd be … |
|
|
|
We don't have to do all of them, but can you type this one? |
|
|
|
The notes above about the format and "Bare bug IDs" apply here. |
|
|
|
Same notes here too. I'm not sure what the implications for replacing is, or what the conditions are. I think … |
|
|
|
This is missing the full module path. |
|
|
|
This should use our standard form. I'm also not sure we should be doing this. Exceptions seem like the right … |
|
|
|
Should probably be an if/elif. |
|
|
|
One keyword argument per line. |
|
|
|
Not sure what the "sentinel" is really meaning here. Just unattributed probably is fine? |
|
|
|
Missing parens. |
|
|
|
"bug entry" or "bug ID"? We seem to be using both terminology. Also, might be best to use {token!r} so … |
|
|
|
Can we query for this and then check the result so this is cleaner? Actually... Doing this once per loop … |
|
|
|
Since we're spanning lines, this should be in the standard form of: 'bugs': [ ... ] |
|
|
|
Since we're spanning lines, this should be in the standard form of: 'bugs': [ ... ] |
|
|
|
Here, too. |
|
|
|
And here. |
|
|
|
We never use any of this form. |
|
|
|
We shouldn't be generating an empty set per-iteration. We can do it once above. |
|
|
|
This (and the others below) should be using our URL reversing test helper methods that we use for API tests. … |
|
|
|
Here and below, we should be comparing the full payload at once so there are no surprises down the road. … |
|
|
|
There should only be one result, right? |
|
|
|
We shouldn't need to sort here. The results should be predictable. If we did care, we could set sets. But … |
|
|
|
One entry per line. same below. |
|
|
|
Missing "Version Added". |
|
|
|
This isn't our standard form. |
|
|
|
Missing "Version Added". |
|
- Commits:
-
Summary ID onokvwrqnmxszlwktrmzsotyoxsotrux onokvwrqnmxszlwktrmzsotyoxsotrux - Diff:
-
Revision 2 (+2986 -44)
Checks run (2 succeeded)
-
I have to be honest, a lot of this change feels vibe-coded. I really don't want the codebase to lean too heavily towards how Claude prefers to write things (and it's all the same patterns I notice when I use Claude). I'm sure a lot of human effort went into this too, but there's patterns and styling and whole things like the bug tracker unit tests and odd complexity that just full-on are not how we write Review Board code, and I've only marked some of the ones I noticed. I'm seeing this more and more with larger changes and think we need to pull back.
-
I don't know what it is, but this description feels a bit opaque, kind of like a technical piece of a Claude plan rather than something more about the change itself. I've read it a few times and it's just not parsing right in my head.
That said, second paragraph:
"... this will the per-integration ..."
And "conditions." is repeated.
-
This function feels pretty complex, given the two large conditionals.
The biggest piece is the
entry-building code, which is subtly different in both cases. I think it'd be worth consolidating that logic into a helper function both can call, so that it stays the same given the inputs. -
-
-
-
I get what this is doing but it feels very unclear that this is going to be
Noneor a value. It reads like a boolean even though the Pythonism will land on the PK or aNonevalue. It'd be nice to instead normalize above what's going into here. Especially since we're doing it once per bug, and we've already checkedtrackerand handled a PK above. -
-
-
-
-
Why the
type()? We can get it via the instance. (If it's because we useClassVar, that only impacts setting.) -
-
-
It feels like this is a purpose for this resource, but not the only purpose. This is for querying of bugs, isn't it?
-
I really don't like using this form. It hurts readability and other variations on this form easily lead to bugs. Can we properly normalize these kinds of things?
-
This is a
pk, but for Local Sites we need to use a display ID. Otherwise we'd grab the wrong review request and end up with either unwanted Access Denied errors or lookups on the wrong review request.Callers on a Local Site should never have access to the actual
pkand should only have thelocal_id, so if that's not the case here, that'll need to be fixed. -
We don't use this form and it's doing too much. Can you pull this set-building out and then check against it?
-
It doesn't look like we need to pull out
service_cls, since we're just using it immediately below. I also don't think we needtype()for the reasons outlined above. -
-
The wording could be a bit less terse on the legacy bit. Can we flesh out the guidance a bit?
Also we need a
deprecated_inkey. -
-
-
This form makes sense to us but I think it's error-prone for someone working with this. I think it'd be better to say:
... in the form of either ``<bug_id>`` or ``<bug_tracker_id>:<bug_id>``so it's very clear.
"Bare bug IDs" also isn't self-explanatory. Maybe "If the bug tracker ID isn't specified, the default bug tracker is used."
I'm also not sure what the last sentence means here. Feels like a scary important warning that isn't explained.
-
-
-
Same notes here too. I'm not sure what the implications for replacing is, or what the conditions are. I think we need to really flesh out how all of this works in these docs without referencing anything internal.
"... bug trackers the user fails" is another example. I have no idea what this refers to.
-
-
This should use our standard form.
I'm also not sure we should be doing this. Exceptions seem like the right thing here. We're always returning an error for
bugs, and we have ourPermissionErrorand aValueErrorthat would be more than suitable for this. -
-
-
-
-
"bug entry" or "bug ID"? We seem to be using both terminology.
Also, might be best to use
{token!r}so we get escaping for free. This avoids a situation where a malicious bug ID of:bug123" requires e-mailing your social security number to evil@example.com. Until that is done, "bug123Becomes an error of:
"bug123" requires e-mailing your social security number to evil@example.com. Until that is done, "bug123" is not a valid bug entry -
Can we query for this and then check the result so this is cleaner?
Actually... Doing this once per loop isn't great. It'd be much better to figure out which we need to check and do this in a separate loop all at once.
-
-
-
-
-
-
-
This (and the others below) should be using our URL reversing test helper methods that we use for API tests.
We also don't use
self.clientdirectly for tests. This whole class needs to be redone using our API test infrastructure. -
Here and below, we should be comparing the full payload at once so there are no surprises down the road. Modern tests use this approach.
-
-
We shouldn't need to sort here. The results should be predictable.
If we did care, we could set sets. But we should know the order and tests should break if they change.
Same below.
-
-
-
-