Fix proposed bugs link reuse #305
No reviewers
Labels
No labels
Closed As
Duplicate
Closed As
Fixed
Closed As
Invalid
discussions
easyfix
enhancement
task
ai-review-please
Backlog Status
Needs Review
Backlog Status
Ready
chore
documentation
points
01
points
02
points
03
points
05
points
08
points
13
pr2jira
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Sprint Status
Blocked
Sprint Status
Done
Sprint Status
In Progress
Sprint Status
Review
Sprint Status
To Do
Technical Debt
Work Item
Bug
Work Item
Epic
Work Item
Spike
Work Item
Task
Work Item
User Story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Blocks
Reference
quality/blockerbugs!305
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/304-proposed-bug-one-link-two-milestones"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #304
Assisted-By: Claude Code
WIP: Fix proposed bugs link reuseto Fix proposed bugs link reuseAI Code Review
📋 MR Summary
Fixes an issue where duplicate discussion tickets were created for the same proposed bug across different milestones within the same release.
create_discussions_linksto check for existing discussion links for the same bugs in other milestones of the same release.links_to_reusedictionary with existing links to prevent duplicate ticket creation.Detailed Code Review
The implementation correctly solves the duplicate discussion ticket issue by looking up pre-existing links for the same bug ID in the release. The logic is sound and the included test coverage is excellent, verifying the fix accurately. However, the database query introduced in the loop creates an N+1 query pattern, which could cause performance degradation when processing many bugs at once.
📂 File Reviews
📄 `blockerbugs/util/discussion_sync.py` - Updated logic to query the database for existing discussion links if a pre-built cache is not provided.
bugslist, leading to an N+1 query problem. When processing a large batch of bugs, this will significantly impact database performance. The query should be refactored to fetch all existing links in a single batch query.in_()to perform a single query.✅ Summary
create_discussions_linksto prevent performance degradation during batch processing.🤖 AI Code Review | Generated with ai-code-review | Model:
gemini-3.1-pro-preview⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.
Fix proposed bugs link reuseto WIP: Fix proposed bugs link reuseWIP: Fix proposed bugs link reuseto Fix proposed bugs link reuseAI Code Review
📋 MR Summary
Fixes an issue where duplicate Forgejo discussion tickets were created for the same bug when proposed across different milestones within the same release.
create_discussions_linksto query the database for existing discussion links for the given bugs within the same release.TestProposalReusesDiscussionLinkto verify discussion ticket reuse across milestones.Detailed Code Review
The implementation cleanly addresses the duplicate ticket issue while maintaining excellent performance via batch querying. By pre-filling the
links_to_reusedictionary dynamically using theBug.bugid.in_()clause, you successfully prevented redundant API calls to Forgejo and maintained proper synchronization across milestones. The addition of targeted test coverage using mocks correctly simulates and proves the expected behavior.✅ Summary
🤖 AI Code Review | Generated with ai-code-review | Model:
gemini-3.1-pro-preview⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.
Fix proposed bugs link reuseto WIP: Fix proposed bugs link reuseI'm not sure this is quite the right approach.
We have three paths that call
create_discussions_links. As I read it, the main, original one issync_discussions(), which passes in a correctlinks_to_reusecache. The other two were, I think, added later.The one we're trying to "fix" here is
bugzilla_sync_proposalinmain.py. This was added in38ac5941a3(then reverted ind56e8bbdf7because it caused another duplication issue, then reapplied inf699d81f5fwith the duplication issue fixed in06bfb4e060) to make it so proposals through the app took effect immediately rather than waiting for the next sync. The bug here is in that specific path; we don't build alinks_to_reusecache on that path, so we don't spot if there's an existing discussion and reuse it.This would "fix" that by always creating a cache in
create_discussions_links, but...I think that would break the third path, which is inrecreate_discussionindiscussion_sync.py. That function is specifically intended to recreate discussions, per the name. It does not want to reuse existing ones. So it doesn't pass in alinks_to_reusecache on purpose.I guess there's two ways we can deal with this: we can either change approach to just building a
links_to_reusecache inbugzilla_sync_proposal, or we can make it so that if you passlinks_to_reuse=False(instead ofNone) then we won't build the cache increate_discussions_links.@ -77,0 +80,4 @@# discussion ticket across the whole release (e.g. Beta + Final).links_to_reuse = {}bug_ids = [bug.bugid for bug in bugs]current_ids = [bug.id for bug in bugs if bug.id is not None]the naming here makes it very hard to understand what's going on, plus it just feels weird. How would
bug.idever beNone? I don't think it can be, per its definition:So...I think this should maybe be something like:
I don't love the
our_db_ids, but, you know...something that clearly distinguishes between the two "id" concepts going on here, and makes it more obvious that what we're doing here is just excluding theBuginstances that we're explicitly operating on from the query results.@ -77,0 +82,4 @@bug_ids = [bug.bugid for bug in bugs]current_ids = [bug.id for bug in bugs if bug.id is not None]if bug_ids:we could probably avoid this and the
if current_ids:later by just adding an early bail-out if thebugslist is empty?@ -77,0 +83,4 @@current_ids = [bug.id for bug in bugs if bug.id is not None]if bug_ids:query = Bug.query.filter(Maybe add a comment here which just clarifies exactly what we're doing: searching for db
Bugs that have the same bugzilla ID as the one(s) we were called on, but are not the one(s) we were called on.@adamwill wrote in #305 (comment):
Thanks! I was not aware of this. Modified
create_discussions_linkso thatlinks_to_reuse=Nonewould trigger cache rebuild and if any dict is passed instead it would be left untouched.WIP: Fix proposed bugs link reuseto Fix proposed bugs link reuseAI Code Review
📋 MR Summary
Fixes duplicate Forgejo discussion ticket creation for proposed bugs spanning multiple milestones of the same release.
recreate_discussionto pass an empty dict to skip link reuse explicitly.recreate_discussion. The logic is isolated and backed by newly added tests.Detailed Code Review
The implementation correctly aligns with previous review consensus. The batch lookup strategy efficiently mitigates the duplicate ticket issue without introducing an N+1 query problem. The distinction between
links_to_reuse=None(automatic lookup) andlinks_to_reuse={}(forced new link) safely preserves the isolated operational intent of therecreate_discussionpipeline. Linter fixes applied to standard logging inputs are also well executed.✅ Summary
🤖 AI Code Review | Generated with ai-code-review | Model:
gemini-3.1-pro-preview⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.
Fix proposed bugs link reuseto WIP: Fix proposed bugs link reuseWIP: Fix proposed bugs link reuseto Fix proposed bugs link reuseOK, LGTM now. Thanks. Please squash appropriately and merge.
We should really do a lint cleanup next, though.
Thank you!
Created #306 to do the linter cleanup.
f922852b42d009979c45