Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added content/blog/2025/pr-triage-boards/featured.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions content/blog/2025/pr-triage-boards/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: "Yuvi on scaling maintainer intuition to facilitate PR review with PR triage boards"
date: "2025-11-19"
categories:
- upstream-impact
tags:
- open source
- community
- learning
featured: false
---

Yuvi has a recent post on the [Jupyter blog](https://jupyter.org) on how his "maintainer intuition" about reviewable pull requests grew into the open-source [`pr-triage-board-bot`](https://github.com/jupyter/pr-triage-board-bot), a reusable workflow that keeps GitHub Project boards curated for the JupyterHub, JupyterLab, and GeoJupyter communities. [Foundational contributions](../foundational-contributions/) are rellay important to 2i2c. This is a great example of building clever technical systems that help maintainers prioritize the social work of facilitating contributions to keep ecosystems healthy.

{{< figure src="featured.png" title="The [JupyterHub PR Triage board](https://github.com/orgs/jupyterhub/projects/4/views/9)." >}}

Yuvi frames the problem here:

> Reviewing PRs is a critical way that maintainers keep an open source project moving forward, but identifying PRs that can productively be merged is hard.
And notes that _human scalability_ is often a big bottleneck:

> One key bottleneck we identified in the process was Step 2. In particular, I was relying on my maintainer intuition to pick a single PR that I believe can be merged, so others in the team can do review work. I started exploring what this intuition is, and if it can be scaled.
Here's his list of "intuitions" that he uses to choose PRs to work on:

> 1. PRs that aren’t too big, and are a reasonable size that can be merged within a 2 week window
> 1. CI tests passing, so at least our automated checks haven’t caught any issues with it
Features or bug fixes that I believe add value to the project and move us in the right direction towards being able to support our users as they need (this is the hardest!)
> 1. If the author of the PR is a newish contributor, as I want to encourage them to stick around by being responsive to their gift. All PRs are gifts that we may or may not choose to accept, but should do so with grace.
> 1. How long ago the PR was opened. There is such a big difference between a response to your PR 2 days after you make it vs 2 months vs 2 years. I prioritized newer PRs.
> 1. What kind of contribution is it primarily? Different engineers on our team have different skillsets (JS, Python, etc) and I wanted to match the PR to what the engineer preferred code reviewing.
And the board essentially tries to capture many of these intuitions by signal-boosting them in one place:

> we can roughly say ‘Pick a PR that looks good to you from the top of the “First Time Contributor” or “Seasoned Contributor” list’, and that relieves me from being the bottleneck quite a bit.
Read more in the original article: [Scaling "Maintainer Intuition" with Pull Request Triage Boards](https://blog.jupyter.org/scaling-maintainer-intuition-with-pull-request-triage-boards-779f2387498b).

## Acknowledgements

- [Project Jupyter](../../../collaborators/jupyter/) for trusting us to incubate and now donate the bot code to the broader ecosystem.
- [JupyterHub](../../../collaborators/jupyterhub/) and [GeoJupyter](../../../collaborators/geojupyter/) contributors who tested the triage views and fed real maintainer workflows back into the design.
- [Jason Grout](https://github.com/jasongrout), [Raniere Silva](https://github.com/rgaiacs), and [Matt Fisher](https://github.com/mfisher87) for spotting the experiment early and helping it land across multiple orgs.
92 changes: 1 addition & 91 deletions content/blog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,94 +5,4 @@ _build:
render: 'never'
---

Our goal is to make blogging as short and quick as we can, so we can blog often.
See [the template blog post](./_template-post/index.md) for an example template to use.

## How to write blog posts

Follow these steps:

- Copy the `content/blog/_template-post` folder into the appopriate year folder, and modify the folder name.
- Modify `index.md` to fit your post. Do these things:
- Generate post content using the linked posts in `_template-post/index.md` as inspiration.
- The post should be short, to the point, and scannable. Use quick and accessible language, keep posts below 200 words.
- If there are links in the issue, scan their content to learn more before you write the post.
- Make sure to add an acknowledgements section at the bottom. Do these things:
- check the `/content/collaborators` folder to see if an entry exists for that collaborator, and link them if so.


### Example from Yuvi's doepy talk

Here's an example from a recent talk that Yuvi gave:

- Example GitHub issue: https://github.com/2i2c-org/2i2c-org.github.io/issues/470
- The blog post that followed: ../../content/blog/2025/doepy-yuvi/index.md

### Example incident report

Incident reports are a way to provide transparency about what happened and what we learned as we run infrastructure. We create incident reports at https://github.com/2i2c-org/incident-reports so blog post GitHub issues don't need to have any content other than a link to the report.

- Example incident report issue: https://github.com/2i2c-org/2i2c-org.github.io/issues/482
- The blog post that followed: ../../content/blog/2025/incident-ucmerced-throttling
## How to write our Hugo directives

Here are a few example Hugo directives for quick reference.

### Figures

An example figure directive:

{{< figure src="images/staging-hub-matrix.png" title="Our staging and support hub job matrix tells GitHub Actions to deploy staging and support upgrades that act as canaries and stop production deploys if they fail.">}}

### Videos

From YouTube:

{{< youtube YjonPLxDiwM >}}

Local Videos:

{{< video src="videos/jupyterhub-admin.mp4">}}

### Callouts and admonitions

An example admonition / callout:

{{% callout %}}

Here's some markdown in my callout!

{{% /callout %}}


## How to add a category and tags

Each post has one category and multiple tags. Categories describe the post's intent, and tags cover its main themes or topics. You add them to the frontmatter of posts like so:

```markdown
---
title: Post title
date: "2025-01-01"
categories:
- updates
tags:
- open source
- geoscience
---
```

## How to use categories and tags

We use **lowercase formatting** as well as **spaces instead of hyphens** for both tags and categories. For example, `open source`, not `open-source` and not `Open Source`.

### Common categories

We try to keep the number of categories small, and non-overlapping in their meaning. [Here's a list of all our categories](https://2i2c.org/categories/), but we try to keep it only to the ones below:

- `impact` - telling stories of impact that 2i2c has had, either via contributors to a domain / open source community, or via communities we've enabled with our service.
- `service` - updates about our service and work we've recently done for it.
- `organization` - updates about our organization that isn't directly related to our service

### Common tags

We have a lot of tags, so don't worry about creating a new one if you don't think your tag has been covered yet. [Here's a list of all our tags](https://2i2c.org/tags/).
For information about contributing to the blog, see the [blog contributing guide](../../contribute/blog.md).
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
# THIS IS A TEMPLATE FOR COPY-PASTING TO MAKE IT EASIER TO CREATE BLOG POSTS
title: "TIL: How to do XYZ thing for Y outcome"
date: "1000-01-01"
authors:
Expand Down
30 changes: 30 additions & 0 deletions content/blog/_templates/reference-post/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "[Person's name] on [Topic]"
date: "1000-01-01"
authors:
- Foo
categories:
- learning
tags:
- Foo
---

One or two sentences describing a piece of content that you'd like to reference, its main takeaway, its author, and why it's worth reading (add a link to it and the author's name).

Some things that stood out to us:

Quotes, images, etc from the post that you'd like to highlight. Just one or two is fine, but add as much as you like. Make sure you're using exact quotes!

They mention ____ about ____

> Pull quote

They also talk about ____

> Pull quote

Read more in the original article: [article title]([link]).

## Acknowledgements

- Bulleted list of people and organizations to thank, with links to their spaces.
63 changes: 61 additions & 2 deletions contribute/blog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ See the **Tags and categories** section below for inspiration about what to blog
Copy the blog post folder template at the path below:

```
content/blog/_template-post
content/blog/_templates/[post-type]/index.md
```

It contains an `index.md` file that you can modify. Put it in the folder for the year in which you're posting (e.g.: `content/blog/2025/mypostfolder`).
Expand Down Expand Up @@ -100,4 +100,63 @@ _Tags are more fluid, you can add as many to a post as you like._

#### Domains
- `earth-science` - (here are common ones, add new domain tags as you wish)
- `biology`
- `biology`

## How to write blog posts

Follow these steps:

- **Find a GitHub issue**. An issue should describe the most important points to convey in a post. Read it, and any linked material inside, to learn what it's about.
- **Choose a template**. Copy one of the `content/blog/_templates/[posttype]/` folders into the appopriate year folder, and modify the folder name.
- **Read the template guidance**. Each template file has suggestions for its structure, as well as links to example posts - reda those posts to understand what we're going for.
- **Generate a post draft**. The post should be short, to the point, and scannable. Use quick and accessible language, keep posts around 100-300 words.
- **Add collaborator links**. Scan the post for mention of collaborating people and organizations - check the `/content/collaborators` folder to see if an entry exists for any you notice. If so, add a link to that folder entry.


### How to add a category and tags

Each post has one category and multiple tags. Categories describe the post's intent, and tags cover its main themes or topics. You add them to the frontmatter of posts like so:

```markdown
---
title: Post title
date: "2025-01-01"
categories:
- updates
tags:
- open source
- geoscience
---
```

We use **lowercase formatting** as well as **spaces instead of hyphens** for both tags and categories. For example, `open source`, not `open-source` and not `Open Source`.

## Hugo directives you can use in our blog

Here are a few example Hugo directives for quick reference.

### Figures

An example figure directive:

{{< figure src="images/staging-hub-matrix.png" title="Our staging and support hub job matrix tells GitHub Actions to deploy staging and support upgrades that act as canaries and stop production deploys if they fail.">}}

### Videos

From YouTube:

{{< youtube YjonPLxDiwM >}}

Local Videos:

{{< video src="videos/jupyterhub-admin.mp4">}}

### Callouts and admonitions

An example admonition / callout:

{{% callout %}}

Here's some markdown in my callout!

{{% /callout %}}