Skip to main content
When an issue or pull request has been closed for a long time, new comments on it are usually in the wrong place: a new bug report hiding in an old thread, or a “me too” nobody will read. The lock feature locks the conversation of every item that has been closed for a number of days. Once locked, only people with write access can comment, and GitHub tells everyone else to open a new issue. You would use it to keep old threads tidy and make sure new problems are reported where maintainers will see them. The feature runs as a sweep: once per scheduled or manual run, it finds every closed, unlocked item old enough to lock.

Turn it on

1

Run smartcloud on a schedule

The sweep runs only on schedule and workflow_dispatch events. Make sure your workflow has both:
.github/workflows/smartcloud.yml
2

Give the job write access to issues and pull requests

Locking needs issues: write for issues and pull-requests: write for pull requests. The workflow token has both with the permissions in Getting started.
3

Add a lock section

.github/smartcloud.yml
4

Run it once by hand

Run the workflow from the Actions tab and read the job summary. With the action’s dryRun: true input, it lists what it would lock without locking anything.

Options

A pull request counts as closed whether it was merged or not.

Complete example

.github/smartcloud.yml

How it works

  1. smartcloud searches the repository for closed, unlocked issues and pull requests closed more than afterDays ago, one search for each kind in on.
  2. Items with an exempt.labels label are skipped.
  3. For each other item, smartcloud posts comment, adds label, and then locks the conversation with reason. The comment and label come first, while the thread is still open to them.
smartcloud keeps at most one lock comment per item, and edits an existing one rather than posting again, so an item that failed part way, or that GitHub’s search still lists as unlocked for a moment after locking, is not commented on twice. Only a lock comment written by a bot account or by a login in roles.trustedBots counts. GitHub’s search returns at most 1,000 items for each kind. A repository with a larger backlog of closed, unlocked threads is worked through over several sweeps. Each item is locked on its own. When GitHub fails on one, the sweep records an error naming it and carries on with the rest.

What you will see on GitHub

  • On the item: your comment, your label, and the conversation locked, with GitHub’s “locked as resolved” (or your reason) note.
  • Check run: smartcloud / lock, concluding success when every item was locked and failure when any could not be. See check runs.
  • Job summary: each comment, label and lock, as a list of changes.

Forks and restricted runs

Scheduled and manually dispatched runs never come from a fork, so the feature never runs with a fork’s read-only token. It works with the plain workflow token. In a restricted run, a write GitHub refuses is skipped and listed under Restricted access in the job summary.

Troubleshooting

The sweep runs only on schedule and workflow_dispatch. Add a schedule, or run the workflow by hand.
GitHub refused or failed that item. Usually the job is missing issues: write (for issues) or pull-requests: write (for pull requests). The rest of the sweep carried on, and the next sweep tries again.
GitHub’s search returns at most 1,000 items of each kind per sweep, so a large backlog takes several sweeps. Search results can also lag a few minutes behind recent closes.
reason accepts only resolved, off-topic, too heated (with the space) or spam.
Last modified on September 27, 2026