224 lines
11 KiB
Markdown
224 lines
11 KiB
Markdown
# Slash Command Dispatch
|
|
[](https://github.com/peter-evans/slash-command-dispatch/actions?query=workflow%3ACI)
|
|
[](https://github.com/marketplace/actions/slash-command-dispatch)
|
|
|
|
A GitHub action that facilitates ["ChatOps"](https://www.pagerduty.com/blog/what-is-chatops/) by creating repository dispatch events for slash commands.
|
|
|
|
### How does it work?
|
|
|
|
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.
|
|
|
|
### Why repository dispatch?
|
|
|
|
"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.
|
|
|
|
<div align="center"><img src="docs/assets/slash-command-dispatch.png" width="550"></div>
|
|
|
|
## Demos
|
|
|
|
See it in action with the following live demos.
|
|
|
|
- [ChatOps Demo in Issues](https://github.com/peter-evans/slash-command-dispatch/issues/3)
|
|
- [ChatOps Demo in Pull Requests](https://github.com/peter-evans/slash-command-dispatch/pull/8)
|
|
- [Slash command code formatting - Python](https://github.com/peter-evans/slash-command-dispatch/pull/11)
|
|
|
|
## Documentation
|
|
|
|
- [Getting started](docs/getting-started.md)
|
|
- [Examples](docs/examples.md)
|
|
- [Standard configuration](#standard-configuration)
|
|
- [Advanced configuration](docs/advanced-configuration.md)
|
|
|
|
## Dispatching commands
|
|
|
|
### Standard configuration
|
|
|
|
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`.
|
|
|
|
```yml
|
|
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-docs
|
|
```
|
|
|
|
Note 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](docs/advanced-configuration.md) that allows each command to be configured individually if necessary. Use the standard configuration shown above unless you require advanced features.
|
|
|
|
### Action inputs
|
|
|
|
| Input | Description | Default |
|
|
| --- | --- | --- |
|
|
| `token` | (**required**) A `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line). Note: `GITHUB_TOKEN` *does not* work here. See [token](#token) for further details. | |
|
|
| `reaction-token` | `GITHUB_TOKEN` or a `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line). See [reaction-token](#reaction-token) for further details. | `GITHUB_TOKEN` |
|
|
| `reactions` | Add reactions. :eyes: = seen, :rocket: = 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](docs/advanced-configuration.md) | |
|
|
| `config-from-file` | | JSON configuration from a file for commands. See [Advanced configuration](docs/advanced-configuration.md) | |
|
|
|
|
#### `token`
|
|
|
|
This action creates [`repository_dispatch`](https://developer.github.com/v3/repos/#create-a-repository-dispatch-event) events.
|
|
The default `GITHUB_TOKEN` does not have scopes to do this so a `repo` scoped [PAT](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) is required.
|
|
If you will be dispatching commands to public repositories *only* then you can use the more limited `public_repo` scope.
|
|
|
|
#### `reaction-token`
|
|
|
|
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](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) if you would prefer reactions to be made by the user account associated with the PAT.
|
|
|
|
```yml
|
|
- 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-docs
|
|
```
|
|
|
|
### How comments are parsed for slash commands
|
|
|
|
Slash 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
|
|
|
|

|
|
|
|
## Handling dispatched commands
|
|
|
|
### Event types
|
|
|
|
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`.
|
|
|
|
```yml
|
|
on:
|
|
repository_dispatch:
|
|
types: [integration-test-command]
|
|
```
|
|
|
|
### Accessing contexts
|
|
|
|
Commands are dispatched with a payload containing a number of contexts.
|
|
|
|
#### `slash_command` context
|
|
|
|
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.
|
|
|
|
```yml
|
|
- 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.
|
|
|
|
```json
|
|
"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.
|
|
|
|
```yml
|
|
- 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 }}
|
|
```
|
|
|
|
#### `github` and `pull_request` contexts
|
|
|
|
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](https://developer.github.com/v3/pulls/#get-a-single-pull-request) and attach it to the payload at path `github.event.client_payload.pull_request`.
|
|
|
|
You can inspect the payload with the following step.
|
|
```yml
|
|
- name: Dump the client payload context
|
|
env:
|
|
PAYLOAD_CONTEXT: ${{ toJson(github.event.client_payload) }}
|
|
run: echo "$PAYLOAD_CONTEXT"
|
|
```
|
|
|
|
### Responding to the comment on command completion
|
|
|
|
Using [create-or-update-comment](https://github.com/peter-evans/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 :tada: reaction to the comment.
|
|
|
|
```yml
|
|
- 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: hooray
|
|
```
|
|
|
|
Another option is to reply with a new comment containing a link to the run output.
|
|
|
|
```yml
|
|
- 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 }}
|
|
```
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|