Discussion: Best Approach for Managing Blocker/Dependent Issues?
Topic
Hello, community family,
While working on PR #848 (p5.js-website) I realized that it will be fully resolved the moment issue #7722 (p5.js) is closed. I applied a small workaround for now, but this highlighted a broader question: What is the best, most maintainable way for us to handle blocker / dependent relationships across our issues? Below are four possible approaches drawn from recent discussions. I would appreciate everyone’s thoughts, additional ideas, on which direction we should adopt. Thanks to @ksen0 and @GregStanton for their inputs for the ideas.
1. Manual “Blockers” list in our planning documents
If the number of dependencies remains small, we can simply add the blocking issue numbers (for example, #7722) to the Blockers section of the p5.js development-planning document. If it's a handful of things, manual is the best option.
2. Lightweight GitHub Action that watches for “waiting for #” comments
A GitHub Action can watch for any issue being closed and then look for open issues or PRs that contain “waiting for #7722” (or whatever issue number). As soon as #7722 is closed, the Action automatically closes (or locks) all items that have that exact comment. In other words, you add a small script or YAML workflow that listens to the issues.closed event, searches for “waiting for #
3. Feature-dependency blockers surfaced from inline TODOs
Some dependencies live inside the codebase rather than in the issue tracker. A good example is the planned 2D-only build of p5.js, which cannot be shipped until the GPU-accelerated filter() renderer (PR #7409) is finished.
For this scenario, Our code should contain inline TODOs such as // TODO: implement 2D build once filter() runs on GPU We could run a periodic Action that scans for such annotated TODOs, detects when their prerequisites have landed, and then opens a fresh issue (“Implement 2D build”), this will let us know that we can work on this part now. This approach is more complex but helps surface hidden technical debt.
4. GitHub’s new Parent / Sub-Issue hierarchy
GitHub now lets us attach sub-issues to a parent and shows live progress bars. This is excellent for large, multi-step tasks where everything lives in the same repository or where cross-repo links can be attached manually.
What it does not provide is automatic closing of a dependent issue, I also think this probably only applies to new issues and hierarchical tasks, and the hardest dependencies are historical and may have more complex interconnections. However, it is a good idea imo to use existing features / supported process where it is possible
So, I would like to invite everyone here to share their preferences or suggest alternative strategies. Maybe someone has ideas to improve / knows tools that can be used for this. Thanks a lot :)
Wow, thanks for the great ideas and write-up @perminder-17! There's a lot to process here, and I haven't looked into it carefully, but I had a few ideas that may be helpful.
1. Manual “Blockers” list in our planning documents
I like that this is simple, and a manual approach offers some flexibility for unplanned scenarios. On the other hand, I suppose it adds some maintenance overhead, and outdated lists might cause a bit of trouble.
2. Lightweight GitHub Action that watches for “waiting for #” comments
This seems like a great idea, and I'd add that we might want to consider more than one type of comment, to account for common scenarios, like the following:
- "blocked by #"
- Trigger: Blocking issue is closed, enabling work on current issue
- Action: Add comment to current issue indicating it's unblocked
- Example:
arcVertex()can be worked on if a linear-system solver is provided by a newp5.Matrixclass
- "fixable by #":
Optionally, we might create a "waiting" label covering both of the scenarios above. It could be added automatically when a comment with a "blocked by #" type of tag is included, and the actions above could remove it. If contributors want to work on something immediately, they can skip over waiting issues when visually scanning the full issue list; alternatively, if they want to help resolve bottlenecks, they can specifically look for waiting issues (or filter for them).
Note: For sensitive actions triggered by a comment, a security measure might be worth considering, since anyone on GitHub can make a comment. Closing someone else's issue might be a sensitive action in this sense, although I'm not sure how much of a concern it is.
3. Feature-dependency blockers surfaced from inline TODOs
Interesting!
Proposed idea: "Writability" advantage This could be very ergonomic for contributors who are working inside the codebase. Basically, it improves writability. I think there are some tools related to this type of thing, although I haven't done a serious search. One very new tool I saw is jsdoc-todo, which might provide some inspiration, although its features are different than what's been proposed.
If we go this route, maybe we could use the JSDoc @todo tag to standardize the format? Otherwise, it might be easy to write a variation such as TODO, todo, to-do, or TO-DO without realizing it's not covered by this functionality. Maybe a JSDoc tag would also signal that something special could be happening, compared to a plain text reminder, for those who aren't familiar with the policy? We'd also need to consider existing to-do comments that are scattered throughout the codebase and might not all have the same meaning.
Alternative: "Readability" advantage Just to have all options explicitly on the table, another approach could be to open issues and label them as blocked (instead of adding a to-do). This would leverage option 2. I suppose it'd eliminate the need for contributors to learn a hybrid issue/inline system, in addition to eliminating the need to develop and maintain two systems.
Another possible advantage is that it'd give more visibility to blocked issues. Then, if an issue is blocked but no one can currently work on it, or a contributor needs to stop working for some reason, others can more easily discover the issue and its dependencies, so they can help out. They may also be able to understand the nature of the dependency more easily, if an explanation is described in Markdown in a GitHub issue, rather than in a code comment.
4. Sub-issues
I also think this probably only applies to new issues and hierarchical tasks, and the hardest dependencies are historical and may have more complex interconnections.
Great point. After considering this a bit more, the main use case for sub-issues appears to be planning out large chunks of work. Although it is possible to add existing issues as sub-issues of other issues, it won't be possible in general to model unplanned dependencies with GitHub sub-issues, due to the single-parent requirement.
Summary
My initial thinking is that we could use GitHub Actions for managing unplanned dependencies in a couple common scenarios, and we could use sub-issues to plan out and manage large issues.
Caveats: I haven't done any significant research on standard practices. There might be relevant design criteria I'm overlooking. Etc. I'm curious to hear what others think!
Using something like jsdoc-todo seems very useful.
I was wondering if a combined approach would be feasible by creating issues which are labeled as umbrella issue which are only editable by maintainers or github actions (in regard of the security concerns). For example: if a contributor adds a comment such as 'waiting for' a github action checks or updates existing umbrella issues and the github actions mentioned in 2. are triggered only when such an umbrella issue is closed.
I am not familiar with github's sub-issue feature and can't tell if it accomplishes the same
Really exciting discussion, thanks for your thoughts everyone! A couple comments based on a few of the topics above.
Using jsdoc-todo for inline TODOs
Thanks for bringing up jsdoc-todo @GregStanton @error-four-o-four ! I looked into it a little more, and I like the tooling that people have built around it. Seems worth exploring for @perminder-17 's point 3.
A couple of things I found as I was looking into it - not directly related but maybe something nice to try out on a one-time basis to tidy up all the inline TODOs.
- VSCode extension to surface
@todoannotations: todo-tree - Turns
@todointo a checklist in the repo: jsdoc-todo
For context, the "todos" are pretty varied in style in the 1.x branch, including but not limited to @todo syntax. In 1.x, there are 136 matches across 37 files. In the 2.x branch, there are 220 matches over 70 files. Though there's a lot of variety now, maybe working toward standardized use of @todo, perhaps even with linting / CI checks, as a potential longer-term practice.
There is a marketplace action for TODO to issue, so maybe worth checking if this can be customized to meet the needs of original point 3 ("Feature-dependency blockers surfaced from inline TODOs") without triggering too many false positives.
@GregStanton :
Just to have all options explicitly on the table, another approach could be to open issues and label them as blocked (instead of adding a to-do).
I think this could be considered, especially as a longer-term goal/practice, though I'm keeping in mind that currently there are >300 issues (core and website), and >300 inline TODOs. So either manually or automatically (as with above tools) opening issues for inline TODOs would be an undertaking.
Label-gated automation
@GregStanton and @error-four-o-four 's point about permissions is also valuable. Right now, maintainer and triage role can add/remove labels; though some contributors do have this role granted on a case-by-case basis, it's not widely used. Even if it's more systematically given, this permission would still be given mindfully, so I think "locking" the logic with a label would meet the security concern.
I.e., The automation only triggers when the appropriate label is present on the issue, which mitigates abuse. Possible labels: "umbrella" (above comment), "dependency" (confusing), "waiting" (per @GregStanton's suggestion) or "blocking" on the issue that is being waited for, which is where gating matters most. I don't have a very precise idea right now, but using labels as a control mechanism seems like a way to keep the system flexible and easy (comments) but a bit more secure.
EDITED TO ADD: example user flow:
- Issue A is waiting for issue B, and a contributor (without triage role) adds comment "Waiting for [issue-number] fix which will .....". This has no effect until:
- Someone with a triage role applies "Waiting" label to Issue A
- This triggers an action that applies the matching label and comment to Issue B ("Blocking" for example). This label could be added manually, too: the symmetric operation is a comment on Issue B like "Blocking [issue-number] because ..." and could potentially trigger an automated label+comment on Issue A.
- When Issue B is closed, if it has the Blocking label, then any other issues that are "waiting for" it are notified with a comment that they're not blocked (and "waiting" label removed). Maybe if there are multiple blockers in an issue then it's still silently waiting until all blocking issues are resolved. But this is adding more logic.
@ksen0 Oh, wow. Looks like you've made a lot of progress.
To-do comments
The "todo-tree and "TODO to issue" tools look like they could be really useful. Great find.
I initially thought that providing two options (inline to-do comments and direct issue creation) might introduce too much complexity. However, based on your investigation, I now see that it might make a lot of sense.
It's clear from the data you've uncovered that inline to-do comments are attractive to many contributors. This looks like a desire path (you may see me citing this concept a lot as it's a new one for me 😄). Paving this desire path would make existing work patterns more robust, rather than working against contributors' instincts.
Security
Using symmetric labels as an approval mechanism seems like an elegant solution to the security problem. It allows general users to easily initiate a dependency relationship, while also providing a measure of security through a simple approval process.
Perhaps if we also have an action that notifies those with triage permissions of unapproved "waiting" comments, we can close the loop and prevent proposed dependency relationships from languishing without approval.
Label names
Possible labels: "umbrella" (above comment), "dependency" (confusing), "waiting" (per @GregStanton's suggestion) or "blocking" on the issue that is being waited for, which is where gating matters most.
We may want the language to clearly reflect a couple of things: (a) "umbrella"/"waiting"/"blocked" and "blocking" are two related categories, and (b) these categories are not the same. Unfortunately, I see pros and cons to each naming scheme, so it's not obvious to me which one is best.
Maybe the first step is to figure out what features we want. Do we want to support both "blocked by" and "fixable by" comments? If "fixable by" would be sufficiently rare, then maybe we only need an automation for "blocked by"?
Maybe if there are multiple blockers in an issue then it's still silently waiting until all blocking issues are resolved. But this is adding more logic.
Do you think that additional logic would incur a significant cost? It seems like it'd be important.
Caveats
I hope you don't mind me sharing a somewhat half-baked analysis. I thought it might be helpful to offer at least some high-level thoughts about the new options that you've discovered.