Skip to main content
Slash commands let people act on an issue or pull request by writing a comment. Type /label bug and smartcloud adds the label; type /rebase and it rebases the pull request. It saves a trip to the sidebar, works from the GitHub mobile app and email replies, and lets contributors do safe things themselves, such as marking their own pull request ready, without being given write access. Anyone can write a command. smartcloud runs it only when the commenter’s role in the repository allows it, and the role needed for each command is yours to change.

Turn it on

1

Run the workflow on new comments

Commands arrive as issue_comment events. Add closed to the pull request types too if you want backports on merge:
.github/workflows/smartcloud.yml
The job needs issues: write and pull-requests: write for labels, replies and reviews, and contents: write for /rebase, /update and /backport.
2

Optionally, start jobs only for people who can use commands

Every command checks the commenter’s role itself, but you can stop a job starting at all for a comment that has no command or comes from outside the repository:
Leave this out if you want outside contributors to use the commands their author rights allow, such as /ready on their own pull request.
3

Add a commands section

An empty section turns every command on with its default roles:
.github/smartcloud.yml
4

Try it

Comment /help on any issue. smartcloud replies with the commands you can use there.

Writing commands

A command is a line that starts with / and a command name. Put each command on its own line; one comment can hold up to ten, and any after the tenth are refused.
  • Arguments are separated by spaces. Quote an argument that has spaces in it.
  • Names are not case-sensitive.
  • Lines in fenced code blocks and quoted lines (> /close) are skipped, so quoting or showing a command does not run it.
  • Lines that start with / but are not a command, such as a path, are ignored.
  • Edited comments are not run again, and comments by bot accounts are ignored, so smartcloud never answers itself.

Commands

“Or the author” means the person who opened the issue or pull request may use the command on it whatever their role.

Options

The overrides keys are command names without the slash, such as stale-snooze.

Complete example

.github/smartcloud.yml

How it works

Who may use a command

Roles are GitHub’s repository roles, lowest first: read, triage, write, maintain and admin. Each includes the ones before it. smartcloud reads the commenter’s role from GitHub for every comment. A custom role counts as the role it is based on. Someone who is not a collaborator has no role, and if GitHub’s answer cannot be read, smartcloud assumes no role and records a warning (commands.role), so commands fail closed. A command is refused when:
  • it is turned off (/merge is turned off in this repository);
  • the commenter’s role is too low (needs the write role, or to be the author; @someone has the read role);
  • it only works on pull requests and was used on an issue (/rebase only works on pull requests);
  • it is the eleventh or later in the comment.

Tokens

Commands act with the action’s token, and some need more than the workflow token has:
  • Changes the workflow token makes do not start other workflows. A pull request that /rebase, /update or /backport changes gets no CI run from it. Give the action a token of your own, such as a GitHub App token, for those to run CI.
  • /approve with the workflow token needs Allow GitHub Actions to create and approve pull requests turned on in the repository’s Actions settings (settings.actions.createPullRequests). The approval is by the token’s account, and its text names who asked for it.
  • /rebase, /update and /backport cannot change a branch in a fork unless its author allows maintainers to edit it.
GitHub’s answer is reported when it refuses a command, for example “Pull Request is not mergeable” for /merge.

Stale snooze

/stale-snooze needs the stale feature to be configured. It writes one smartcloud comment on the item saying until when it is snoozed, updating it on a later snooze, and removes the stale label. The stale sweep does not mark a snoozed item stale, and unmarks one that is. Only a snooze comment written by a bot account or a roles.trustedBots login counts, so nobody can snooze an item by typing the marker.

Backports

On a merged pull request, /backport release/1.x backports at once. On an open one it adds the label backport release/1.x, and the pull request is backported when it is merged: add closed to the workflow’s pull request types for that. Labelling a pull request by hand works the same way. Labels need the triage role, so anyone who can add one can ask for a backport; the backport is a pull request, which still needs review and merging. A pull request closed without merging is refused. For each target branch, smartcloud:
  1. Creates a branch named backport/<number>-<target> from the target, with each / in the target written as --, so release/1.x and release-1.x get branches of their own. When GitHub refuses the branch and it does not already exist, as with a prefix that is not a valid branch name, the backport fails rather than reporting an existing branch.
  2. Applies the pull request’s changes to it. Squash, rebase and merge-commit merges all work, including a rebase merge of several commits.
  3. Commits them as one commit, authored as the merged commit was, carrying its Signed-off-by lines, with (cherry picked from commit <sha>) in the message.
  4. Opens a pull request titled [<target>] <original title> into the target.
If the changes do not apply cleanly, smartcloud deletes the branch and says so; backport by hand. If the branch already exists, it leaves it alone. Pull requests with more than 100 commits are not backported. When the backport was asked for by label, smartcloud comments on the merged pull request with how each went.
When the backport feature is configured (a backport section), it does every backport on merge and this command only adds the label, using that feature’s prefix. Without a backport section, the commands feature does the backport itself. Either way a label is backported once, and a label naming the branch the pull request merged into is ignored.

Running features again

/run runs smartcloud’s features again for the item the comment is on: every feature for it when none are named, or the ones named, such as /run conventions labels. Their results are published as the item’s own run would be: check runs and the report comment. This is how to recheck a pull request after fixing its title without pushing. Features that act on the whole repository, such as settings, sync and stale, run as a manual dispatch would, and need the maintain role whatever overrides.run says. A feature turned off by its feature flag stays off. A name that is not a feature is refused with the list of features there are.

Dry runs

In a dry run, commands record the writes they would make instead of making them. /backport reads what it needs and says which branch it would open a backport from.

What you will see on GitHub

  • A reaction on the comment: thumbs up (+1) when every command worked, confused (confused) otherwise (unless reactions: false).
  • A reply when a command was refused, written wrongly or failed, and when a command has output, such as /help.
  • The change itself: the label, assignee, review, merge or backport pull request.
  • The job summary, listing every command: a change when it worked, and a warning (commands.denied, commands.invalid or commands.failed) when it did not.
A comment run publishes no check run and no report comment, because a comment is not a commit. Backports asked for by label run on the merged pull request’s closed event, so they also show as a smartcloud / commands check run there.

Forks and restricted runs

issue_comment workflows always run the default branch’s workflow with the base repository’s token, including for comments on pull requests from forks. The comment never runs code from the pull request, and the run is not restricted. That is why every command checks the commenter’s role before it does anything, and why the job condition in Turn it on is worth adding when the job mints a stronger token. A fork’s branch can only be changed by /rebase, /update or /backport when its author allows maintainers to edit it.

Troubleshooting

Check the workflow runs on issue_comment with types: [created], the config has a commands section, and the command is on its own line starting with /. Edited comments, comments by bots, quoted lines and lines in code blocks are ignored. A job condition on author_association also stops comments from outside the repository.
Your repository role is below the command’s. Ask a maintainer, or lower the role with overrides.<command>.permission.
GitHub did not answer the permission lookup, so smartcloud refused rather than guessed. Try again; if it persists, check the token can read the repository’s collaborators.
Changes made with the workflow token do not start workflows. Pass a GitHub App token as GITHUB_TOKEN.
Turn on Allow GitHub Actions to create and approve pull requests (Settings > Actions > General), or set settings.actions.createPullRequests: true, or use an app token.
Add a stale section; snoozing only means something when items can go stale.
settings, sync, stale and other repository-wide features need the maintain role whatever overrides.run says. Name only the item’s own features, or ask a maintainer.
smartcloud deletes the branch and says so. Cherry-pick the change onto the target branch by hand and open the pull request yourself.
Last modified on September 28, 2026