A GitHub action that facilitates "ChatOps" by creating repository dispatch events for slash commands.
The action runs in issue_comment event workflows and checks the first line of comments for slash commands.
When a valid command is found it creates a repository dispatch event that includes a payload containing full details of the command and its context.
"ChatOps" with slash commands can work in a basic way by parsing the commands during issue_comment events and immediately processing the command.
In repositories with a lot of activity, the workflow queue will get backed up very quickly trying to handle new issue_comment events and process the commands themselves.
Dispatching commands to be processed elsewhere keeps the workflow queue moving quickly. It essentially enables parallel processing of workflows.
See it in action with the following live demos.
The following workflow should be configured in the repository where commands will be dispatched from. This example will respond to comments containing the slash commands /deploy, /integration-test and /build-docs.
name: Slash Command Dispatch
on:
  issue_comment:
    types: [created]
jobs:
  slashCommandDispatch:
    runs-on: ubuntu-latest
    steps:
      - name: Slash Command Dispatch
        uses: peter-evans/slash-command-dispatch@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          commands: deploy, integration-test, build-docsNote that not specifying the repository input will mean that repository_dispatch events are created in the current repository by default. It's perfectly fine to use the current repository and not dispatch events to a seperate "processor" repository.
This action also features advanced configuration that allows each command to be configured individually if necessary. Use the standard configuration shown above unless you require advanced features.
| Input | Description | Default | 
|---|---|---|
| token | (required) A reposcoped PAT. Note:GITHUB_TOKENdoes not work here. See token for further details. | |
| reaction-token | GITHUB_TOKENor areposcoped PAT. See reaction-token for further details. | GITHUB_TOKEN | 
| reactions | Add reactions. π = seen, π = dispatched | true | 
| commands | (required) A comma separated list of commands. | |
| permission | The repository permission level required by the user to dispatch commands. ( none,read,write,admin) | write | 
| issue-type | The issue type required for commands. ( issue,pull-request,both) | both | 
| allow-edits | Allow edited comments to trigger command dispatches. | false | 
| repository | The full name of the repository to send the dispatch events. | Current repository | 
| event-type-suffix | The repository dispatch event type suffix for the commands. | -command | 
| named-args | Parse named arguments and add them to the command payload. | false | 
| config | JSON configuration for commands. See Advanced configuration | |
| config-from-file | JSON configuration from a file for commands. See Advanced configuration | 
This action creates repository_dispatch events.
The default GITHUB_TOKEN does not have scopes to do this so a repo scoped PAT is required.
If you will be dispatching commands to public repositories only then you can use the more limited public_repo scope.
If you don't specify a token for reaction-token it will use the default GITHUB_TOKEN.
Reactions to comments will then be made by the @github-actions bot user.
You can use a PAT if you would prefer reactions to be made by the user account associated with the PAT.
      - name: Slash Command Dispatch
        uses: peter-evans/slash-command-dispatch@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          reaction-token: ${{ secrets.REPO_ACCESS_TOKEN }}
          commands: deploy, integration-test, build-docsSlash commands must be placed in the first line of the comment to be interpreted as a command.
- The command must start with a /
- The slash command extends to the last non-whitespace character on the first line
- Anything after the first line is ignored and can be freely used for comments
Repository dispatch events have a type to distinguish between events. The type set by the action is a combination of the slash command and event-type-suffix. The event-type-suffix input defaults to -command.
For example, if your slash command is integration-test, the event type will be integration-test-command.
on:
  repository_dispatch:
    types: [integration-test-command]Commands are dispatched with a payload containing a number of contexts.
The slash command context can be accessed as follows.
args is a space separated string of all the supplied arguments.
Each argument is also supplied in a numbered property, i.e. arg1, arg2, arg3, etc.
      - name: Output command and arguments
        run: |
          echo ${{ github.event.client_payload.slash_command.command }}
          echo ${{ github.event.client_payload.slash_command.args }}
          echo ${{ github.event.client_payload.slash_command.arg1 }}
          echo ${{ github.event.client_payload.slash_command.arg2 }}
          echo ${{ github.event.client_payload.slash_command.arg3 }}
          # etc.If the named-args input is set to true, any arguments that are prefixed in the format name=argument will be parsed and added to the payload.
For example, the slash command /deploy branch=master env=prod some other args will be set in the JSON payload as follows.
    "slash_command": {
        "command": "deploy",
        "args": "branch=master env=prod some other args",
        "unnamed_args": "some other args",
        "branch": "master",
        "env": "prod",
        "arg1": "some",
        "arg2": "other",
        "arg3": "args"
    }These named arguments can be accessed in a workflow as follows.
      - name: Output command and named arguments
        run: |
          echo ${{ github.event.client_payload.slash_command.command }}
          echo ${{ github.event.client_payload.slash_command.branch }}
          echo ${{ github.event.client_payload.slash_command.env }}
          echo ${{ github.event.client_payload.slash_command.unnamed_args }}The payload contains the complete github context of the issue_comment event at path github.event.client_payload.github.
Additionally, if the comment was made in a pull request, the action calls the GitHub API to fetch the pull request detail and attach it to the payload at path github.event.client_payload.pull_request.
You can inspect the payload with the following step.
      - name: Dump the client payload context
        env:
          PAYLOAD_CONTEXT: ${{ toJson(github.event.client_payload) }}
        run: echo "$PAYLOAD_CONTEXT"Using create-or-update-comment action there are a number of ways you can respond to the comment once the command has completed.
The simplest response is to add a π reaction to the comment.
      - name: Add reaction
        uses: peter-evans/create-or-update-comment@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          repository: ${{ github.event.client_payload.github.payload.repository.full_name }}
          comment-id: ${{ github.event.client_payload.github.payload.comment.id }}
          reaction-type: hoorayAnother option is to reply with a new comment containing a link to the run output.
      - name: Create URL to the run output
        id: vars
        run: echo ::set-output name=run-url::https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
      - name: Create comment
        uses: peter-evans/create-or-update-comment@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          repository: ${{ github.event.client_payload.github.payload.repository.full_name }}
          issue-number: ${{ github.event.client_payload.github.payload.issue.number }}
          body: |
            [Command run output][1]
            [1]: ${{ steps.vars.outputs.run-url }}
