May 06, 2018 • ☕️☕️ 9 min read
Here’s a short story about discovering the Lock Threads Probot!
So you find yourself looking at GitHub notifications (yet again 🙂).
Whether you’re doing it out of obligation, or because you’re doing it full-time, you may find it overwhelming to look through it all (every few months you do a “Mark all as read” but you just did it last week).
You start looking through some of these again, one by one.
You already realize that it’s for a closed issue, but you click it anyway.
You notice that someone has commented on an issue that was closed over a year ago.
Enter the maintainer’s dilemma: Do you start helping them right then and there, by triaging it or trying to figure out the solution? Do you just say: “Please make a new issue, because this might be unrelated or out of date”? Do you shy away because you don’t want to offend? Do you just ignore it and realize you probably shouldn’t be looking at notifications anymore?
It’s these kinds of notifications that make you question whether it matters if an issue is closed at all?
I think Dan puts it well here:
Tip: commenting on closed issues or upvoting comments on them is usually futile. You’re lucky it somebody even sees them. Instead, file a new issue (and then you can link to it from the old one).— Dan Abramov (@dan_abramov) May 5, 2018
Maintainers are unlikely to want to look at closed issues (both in terms of time and how they try to help via the interfaces they use), and it can seem lazy on the part of the commentor if they think they can just add a “it still doesn’t work” at the end. We need more context not less.
It’s understandable; as a user, you find a bug or issue with how you use an open source project and you think, “hey instead of making a new issue, I can search through the repo and find something similar and figure it out from there!” However it doesn’t match exactly what you want (since you might be looking for more of a Stack Overflow type thing) so you leave a comment saying “+1”.
But as a maintainer, you might end up finding yourself wanting to click that “lock” button.
In my experience, locking issues is something that isn’t done very often, but it’s really useful when needed. When a conversation is just getting out of hand or not constructive, you might temporarily/permanently lock an issue.
I just realized that in the process of writing this and checking the GitHub help articles that you can lock PRs and even commits?
I’d probably argue we should probably lock/remove comments on commits by default? Or make it easier to link/comment on associated PRs? I guess this related how we do changelogs as well, and maybe a way to response to a specific release about questions/bugs.
Actually, this makes what I’ll be talking about next more relevant!
If you are using GitHub and checking notifications, you might notice a pattern: you may randomly get comments on items that were closed over two years ago. Maybe the codebase has long been rewritten, maybe the issue was fixed in a later version, maybe the issue is actually unrelated.
This is another case when a maintainer may want to prevent any additional comments on a particular issue: not to prevent discussion in general, but to have a clear distinction between issues. Unfortunately, the maintainer has to lock each issue manually. And even then you might feel bad, because “locking” to some users is perceived as “hostile” because it prevents further discussion (but only in that thread). And you’re already overwhelmed by newly create issues let alone old ones.
To be clear, this is different from closing/locking an open issue or PR since that might just be a valid bug/request but low priority or just that no one is able to get to. Determining what to do with “stale” (or even what defines “stale”) has pretty varying opinions (never close vs close after x days).
Your next thought might be: shouldn’t we automate this?
I wish I could automatically limit further conversation on a GitHub issue to collaborators and/or people who have already commented so that random people don't come along and make comments on super old issues. It just clogs up my notifications 🤨— MICHAEL JACKSON (@mjackson) April 29, 2018
I decided to look into this after seeing @mjackson’s Tweet since I remember wanting a similar behavior and didn’t recall an API being available for locking at the time.
So has anyone done this already?
Personal plug: if someone wants to do a contribution to Babel, I made an issue for converting our own custom bot to Probot 😁.
Installation is as easy as going to the install page and adding it to your organization or repo.
Currently, there is no real easy way to make this apply across all your repos, though you can use Probot’s extends feature. I think for this bot-powered action it makes sense to just have the same config/behavior across all repos instead of needing repo-specific configs.
Now all that’s left is to create and configure a
lock.yml file inside the
Some options (at the time of this article) are as follows:
# Configuration for lock-threads - https://github.com/dessant/lock-threads # Number of days of inactivity before a closed issue or pull request is locked daysUntilLock: 365 # Issues and pull requests with these labels will not be locked. Set to `` to disable exemptLabels:  # Label to add before locking, such as `outdated`. Set to `false` to disable lockLabel: false # Comment to post before locking. Set to `false` to disable lockComment: This thread has been automatically locked. # Limit to only `issues` or `pulls` # only: issues # Optionally, specify configuration settings just for `issues` or `pulls` # issues: # exemptLabels: # - help-wanted # lockLabel: outdated # pulls: # daysUntilLock: 30
I was able to make two contributions! (Shoutout to Armin for being so responsive! 😁)
In dessant/lock-threads#3, I added a new feature so that when locking, the bot will automatically add
resolved as the
lock reason. This should give more context to anyone that stumbles upon the locked issue and might be confused why they can’t comment anymore. I also pinged a friend at GitHub about adding
outdated as a
lock reason in the future.
In the meantime, I got a suggestion to use a label which in hindsight, is such an awesome and obvious idea! So dessant/lock-threads#4 implements just that: the ability to an
outdated label after locking before the new
lock reason is implemented.
For Babel, I didn’t want to use the
lockComment option because sending a comment would send an email/notification to anyone watch the repo or subscribed to the closed issue. As we enable this on the repo, the thought of sending 5k emails to my own “inbox” (or anyone still watching) seems totally unnecessary.
While it makes sense to do this silently for all the old issues, it may, howver, be a good idea for new closed/stale issues?
# 3 months is a pretty long time daysUntilLock: 91 # Don't want to notify/email lockComment: false # Only issue with PRs are fixed only: issues # Give context into what is being locked lockLabel: 'outdated'
There is currently an issue regarding locking PRs, so I’ve only enabled it on issues in Babel for now: https://github.com/dessant/lock-threads/issues/5.
At the time of this article, we have ~4.5k closed issues with about ~1.5k of them marked as
outdated/locked, since the bot only does ~30/hour due to rate limiting! There’s probably some improvements to the way it tries to filter out issues so please try it out and contribute back!
Auto-lock “heated” discussions: You could probably also make a bot that auto locks a thread (with a
lock reason of
too heated) if there are too many comments from different people in a short amount of time (say 24 hrs). It shouldn’t be too difficult to differentiate between a regression where people complain vs. something like a name change given the nature of the issue (created by a collaborator, can filter by labels, etc).
GitHub has recently added a few tools to help maintainers that you may or may not have used yet!
Hiding Comments: While editing and deleting comments has been around for some time, it can sometimes be perceived as antagonistic. Hiding Comments was just added as a new feature to help make looking at issues/PRs easier by keeping the discussions relevant.
Temporary Interaction Limits: Instead of locking an issue temporarly, you can now do this across the whole repo. So even if a single issue is blowing up and you want to prevent spam/new issues until it dies down you now have a few options. You can it to only existing users, only prior contributors, or only collaborators.
Archiving a Repo: There comes a time when you may want to deprecate a repo, move a repo into a monorepo, or just not want any further activity. Previously, you had to decide whether to just unwatch the repo or just delete it entirely. Archiving a repo now allows you to make it read-only so that links to previous issues/PRs still work and people can still view the readme/docs/etc but it’s clear that it’s frozen.
If you like this kind or writing and want to support that or my open source work, check if you’d want to donate to my Patreon. I’m trying to to this full time now!
Blog of Henry Zhu