Skip to content

Conversation

@Carbonhell
Copy link

@Carbonhell Carbonhell commented Dec 22, 2025

Closes #494.

I wasn't sure whether to use IDs from the pull_request table to represent PRs in the mapping, or just the GitHub PR number - I went with the latter as there would be no record for the rollup at the time of its creation, as that gets populated via GitHub events, if I understood correctly.

I haven't experienced rollups at all as I haven't (yet?) contributed to a project with bors, but I noticed there's no safety check for multiple rollups containing the same PR(s) being opened. I found a related comment here, but I kept it out of this PR to reduce its scope and simplify review. I think such a safety check could be added easily by checking for rollups associated to each candidate PR, and verifying the status of the rollup PR to ignore closed ones. That would still allow one to recreate the same scenario by reopening a previously closed rollup, though.

One thing I'm unsure about is how to handle the error when writing the rollup_contents records in the DB. I think that should only happen either in case of DB connection errors, or if the list of PRs contains duplicates. I assume the former can be propagated to the caller, whereas I'm not sure if the latter is realistic and should be accounted for. I'm thinking we can just ignore the conflicting records in such case - let me know if I should proceed with that.

Edit: sorry, I forgot the migration test files. Will push them tomorrow as soon as possible

@Kobzol
Copy link
Member

Kobzol commented Dec 22, 2025

Hi, thanks for the PR! I'll take a look, but I don't know when I'll be able to get to it, since it's Holiday season :)

I wasn't sure whether to use IDs from the pull_request table to represent PRs in the mapping, or just the GitHub PR number - I went with the latter as there would be no record for the rollup at the time of its creation, as that gets populated via GitHub events, if I understood correctly.

Yeah, that makes sense.

but I noticed there's no safety check for multiple rollups containing the same PR(s) being opened.

This is not a problem on its own, there are often multiple rollups that contain a single PR, because if a rollup fails, you create a new one, often before the old one is closed. I don't think that we need to think about that right now.

if the list of PRs contains duplicates. I assume the former can be propagated to the caller, whereas I'm not sure if the latter is realistic and should be accounted for.

Also a good point! I'll ignore duplicate PR numbers in rollups.

Copy link
Member

@Kobzol Kobzol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the main query that we will want to execute on the queue page would look something like this:

SELECT
    rollup_pr_number, member_pr_number
FROM rollup_member
WHERE repository = $1 AND
      rollup_pr_number IN (SELECT number
                           FROM pull_request AS pr
                           WHERE pr.repository = $1
                             AND pr.status IN ('open', 'draft'))
ORDER BY rollup_pr_number;

And we get back something like HashMap<PrNum, HashSet<PrNum>>, which maps rollups to their member PRs. Because we assume that there will be only a couple of open rollups, so it seems easier and faster to do it this way, rather than try to find a corresponding rollup for each PR in the queue.

@Carbonhell Carbonhell force-pushed the feat/rollup-contents branch 3 times, most recently from 948ac1d to c1d42a4 Compare January 6, 2026 21:52
@Carbonhell Carbonhell requested a review from Kobzol January 6, 2026 23:33
@Carbonhell
Copy link
Author

Sorry for the long delay (and the force-pushes 👀), the PR should be ready for another review now. Thank you in advance :)

Copy link
Member

@Kobzol Kobzol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, it looks good!

@Kobzol
Copy link
Member

Kobzol commented Jan 7, 2026

I wouldn't actually mind having some basic usage of the new queries in the same PR - it often turns out that a new API will need to be changed once it's actually used 😆 Would you like to take a stab at that?

Some ideas:

  1. If a rollup is currently being tested (it has state pending), it should not be possible to add its members to a new rollup (the rollup checkboxes should be disabled for the members)
  2. Each rollup in the queue could have some color associated to it, and we could show some small rectangle or circle before/after the rollup PR number or title, in the queue table. And then we could also add this rectangle/circle at the same spot for the rollup members, to make it visually obvious which members belong to which rollups.
  3. When you hover on a rollup, its members could be highlighted.

I think that 3. might be the simplest to implement, and it would be enough to test that the queries that we have here make sense. The rest could be done in follow-up PRs.

@Carbonhell
Copy link
Author

I wouldn't actually mind having some basic usage of the new queries in the same PR - it often turns out that a new API will need to be changed once it's actually used 😆 Would you like to take a stab at that?

Some ideas:

  1. If a rollup is currently being tested (it has state pending), it should not be possible to add its members to a new rollup (the rollup checkboxes should be disabled for the members)
  2. Each rollup in the queue could have some color associated to it, and we could show some small rectangle or circle before/after the rollup PR number or title, in the queue table. And then we could also add this rectangle/circle at the same spot for the rollup members, to make it visually obvious which members belong to which rollups.
  3. When you hover on a rollup, its members could be highlighted.

I think that 3. might be the simplest to implement, and it would be enough to test that the queries that we have here make sense. The rest could be done in follow-up PRs.

Honestly I agree on implementing the usage of the new queries in this PR. I've been sticking to small PRs mainly to facilitate the reviews and to avoid making it too time consuming for maintainers, as I'll probably do a few mistakes since I just started contributing :) I'd be more than happy to handle it! I'll look into it in this weekend

@Kobzol
Copy link
Member

Kobzol commented Jan 8, 2026

Yeah ofc small PRs are good in general. On the other hand, I tend to be a bit wary of PRs that just add new functionality without using it, because very often when we start using it we realize that we need to make changes to it anyway 😆

…nsert/get logic

chore(git): add relevant gitattributes to ensure correct line endings for sqlx files
…ove unnecessary index

tweak(rollups): replace access patterns to rollup_member with a single get_nonclosed_rollups operation, to be used within the queue page endpoint logic in the future
fix(rollups): add missing test sql file
chore(rollups): update migration timestamp
@Carbonhell Carbonhell force-pushed the feat/rollup-contents branch from 41253eb to 4298378 Compare January 11, 2026 22:45
…en hovering the row representing a rollup PR
… is to verify the acceptable case of multiple rollups may point to the same member PR
@Carbonhell Carbonhell force-pushed the feat/rollup-contents branch from 4298378 to 0c5aeee Compare January 11, 2026 22:58
@Carbonhell
Copy link
Author

Carbonhell commented Jan 11, 2026

As agreed on Zulip, for now I've only implemented the hover functionality, as seen in the following screenshot (mouse hovering on a rollup not shown):
image

I've also fixed the issue with the multiple_rollups_same_pr test from the last review.
The PR should be ready for review. Thanks in advance :)

@Carbonhell Carbonhell requested a review from Kobzol January 11, 2026 23:01
Copy link
Member

@Kobzol Kobzol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple of small nits, but otherwise this looks really awesome! The hover also looks and works great ❤️ Thank you!

Comment on lines +6 to +8
rollup_pr_number BIGINT NOT NULL,
member_pr_number BIGINT NOT NULL,
repository TEXT NOT NULL,
Copy link
Member

@Kobzol Kobzol Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rollup_pr_number BIGINT NOT NULL,
member_pr_number BIGINT NOT NULL,
repository TEXT NOT NULL,
repository TEXT NOT NULL,
rollup_pr_number BIGINT NOT NULL,
member_pr_number BIGINT NOT NULL,

Just a nit, it's easier to read like this when inspecting the DB state manually :) The migration data SQL file will also need to be updated after this change.

Ok(())
}

/// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup.
/// Returns a map of rollup PR numbers to the set of member PR numbers that are part of that rollup.
/// Only returns non-closed rollup PRs.

AND pr.number = rm.rollup_pr_number
WHERE rm.repository = $1
AND pr.status IN ('open', 'draft')
ORDER BY rm.rollup_pr_number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ORDER BY rm.rollup_pr_number;

Doesn't seem to be required, since we store the numbers in a hashmap/hashset anyway? Might help with cache locality for the hashmap, but that's not really needed here, and the DB won't have to sort the rollups.

tbody.addEventListener("mouseover", handler);
tbody.addEventListener("mouseleave", clear);

return () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice that you implemented the event removal, but we don't call it anywhere anyway, so 🤷 I'd just remove it to shorten the code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do. One related note: do you think it might be worth to support hovering on mobile devices too? I was thinking of hooking the hover handle to the touchstart event (and clear on touchend).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure, because on click we select the PR - how do you actually distinguish hover and click on mobile? 🤔 If it can be done reliably, then might be useful, but I'd leave it for a future PR :)

};
const handler = (event) => {
// Reset highlight
clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clear()
clear();

}
let rollupPrMembers = rowElement.dataset.rollupPrMembers;
if (!rollupPrMembers) {
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return
return;

.await
.context("Cannot create PR")?;

db.register_rollup_members(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about (many!) follow-up features that we could implement once this PR lands, and I realized that the problem with the missing PR id can be solved very easily. We can simply pre-insert the PR into the DB immediately here:

let pr_db = db.upsert_pull_request(..., pr.into());

and then use pr_db.id to record the rollup mapping in the DB.

Since we anyway have to do a JOIN with the PR table when selecting the rollup mapping due to filtering out open PRs, I think that storing the IDs in the mapping would be simpler, after all, would waste less DB space, and would provide proper FK mapping in the DB.

Could you please change it to store (FK to PR table, rollup PR number) in the rollup_member table? Sorry for the late notice 😅

Copy link
Author

@Carbonhell Carbonhell Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense! Some questions:

  1. I assume the fact we perform another upsert from the webhook event received by GitHub for the same PR doesn't matter, as it'd just write the same data. Adding a check to prevent writing PRs that are already in the table in the webhook logic seems pointless - is my assumption correct?
  2. Wouldn't it make sense to change the member PR number in the same way? I assume we're guaranteed to have an entry in the PR table, as from what I know, rollups can only be created from the queue page, which implies PRs shown there have an entry in the table. Therefore we could use a FK for member PRs too for the same reasons. I think the only tradeoff is that writes would be slightly more expensive, but it shoudn't be a concern with the low amount of writes, and it might help future with future query patterns, if any.

I'm always looking for issues to contribute to (mostly during weekends, when i'm not too tired from working in a startup haha). If you want, write down the ideas in GitHub issues and I'll take care of them!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yeah, the open PR webhook is not load-bearing. It can in theory race with the rollup handler, but that shouldn't matter much, Postgres will ensure atomicity of the PR creation.
  2. A very good point! Yeah, I agree. In all cases where we will query this table, the corresponding PRs should already be in the DB. Including when we record the member entries.

Btw, after this change you can remove refresh_prs from rollup tests.

Okay, I will create issues for the features, once this PR lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Store mapping of PRs to rollups

2 participants