knowledge-work/command-action is an Action inspired by github/command.
It provides primitive features to assist in implementing IssueOps commands. It parses key-value strings using a dedicated syntax and converts them into a format that can be used in subsequent workflows. These will help in implementing high-level IssueOps commands.
Note
Currently, a syntax that supports receiving multiple parameters is provided.
This section introduces a quick start guide for knowledge-work/command-action.
Specify the command name to be executed as IssueOps in the command option.
- id: command
uses: knowledge-work/command-action@v1
with:
command: 'preview'This sets up your custom IssueOps command to interpret comments on Issues and Pull Requests.
Refer to Inputs for other options.
Hereβs a simple workflow example to execute the .greet command in IssueOps.
name: 'Greet DEMO'
on:
issue_comment:
types: [created]
jobs:
demo:
runs-on: ubuntu-latest
steps:
# Set up the ".greet" command.
- id: command
uses: knowledge-work/command-action@v1
with:
command: 'greet'
# Only run if `steps.<id>.outputs.continue` is "true".
# This indicates that `knowledge-work` successfully parsed the command and the subsequent steps should continue.
# IssueOps params are passed through `env:` and referenced as shell variables to avoid
# GitHub Actions expression injection from attacker-controlled comment content.
- name: Greet
if: ${{ steps.command.outputs.continue == 'true' }}
env:
NAME: ${{ fromJSON(steps.command.outputs.params).name }}
run: echo "Hi $NAME !"
# Add other steps necessary for IssueOps...You can invoke the .greet command as follows:
.greet name="Alice"
Refer to IssueOps Command Syntax for more detailed syntax.
When executing an IssueOps command, it often needs to accept some parameters. This Action parses the parameters using a simple key-value syntax, allowing you to quickly build the scaffolding required for more complex IssueOps commands.
An IssueOps command is called in the following format:
.<command> <key>=<value>, <key>=<value>, ...
<key> should consist of the following:
- A string starting with alphanumeric characters or an underscore.
- A string followed by alphanumeric characters, underscores, or hyphens.
The key-value parameters provided are converted into JSON format and made available as outputs.params. For example, if the following command is executed:
.greet name="Alice", age=20
You will get the following outputs.params:
{
"name": "Alice",
"age": 20
}Values that can be specified for parameters include numbers, strings, booleans, and null. Below are examples of each. Refer to parse.test.ts for more detailed specifications.
Supports common signed and unsigned integers as well as decimals.
.command key=123
.command key=+456
.command key=-789
.command key=0.5
Strings can use single or double quotes. Escaping is also supported.
.command key='value'
.command key="value"
.command key='value \' with escape'
.command key="value \" with escape"
Quotes can also be omitted if the string does not contain spaces or commas.
.command key=/path/to/file.txt
Supports booleans in JSON format.
.command key=true
.command key=false
Supports null in JSON format.
.command key=null
| ID | Required | Default | Description |
|---|---|---|---|
command |
β | n/a | The name of the command to be used in IssueOps, which can be specified as a comma-separated list. |
allowed_contexts |
issue,pull_request,discussion |
The comment contexts that trigger the IssueOps command, specified as a comma-separated list. Allowed values: "issue", "pull_request", "discussion". |
| ID | Description |
|---|---|
continue |
Indicates whether the IssueOps command was triggered and the workflow should continue with the string "true". If the action did not complete successfully, "false" will be used. |
params |
The parameters of the triggered IssueOps command, provided as a JSON string. |
comment_id |
The ID of the comment that triggered this action. |
actor |
The GitHub handle of the actor who executed the IssueOps command. |
issue_number |
[Deprecated] The issue number of the comment that triggered this action. Use number instead. This output will be removed in the next major release. |
number |
The number of the issue, pull request, or discussion that triggered this action. |
context |
The context that triggered this action. One of "issue", "pull_request", or "discussion". |
command |
The command of the triggered IssueOps command. |
A section introducing tips for implementing IssueOps commands.
command-action also handles GitHub Discussions when the workflow is triggered by the discussion_comment event. The same parsing logic applies β the only differences are that outputs.context becomes "discussion" and outputs.issue_number is not emitted (use outputs.number instead).
name: 'Greet DEMO (Discussions)'
on:
discussion_comment:
types: [created]
permissions:
contents: read
discussions: write # only required if your follow-up step writes back to the discussion (e.g. reactions via GraphQL)
jobs:
demo:
runs-on: ubuntu-latest
steps:
- id: command
uses: knowledge-work/command-action@v1
with:
command: 'greet'
- if: ${{ steps.command.outputs.continue == 'true' }}
env:
NAME: ${{ fromJSON(steps.command.outputs.params).name }}
run: echo "Hi $NAME !"Warning
Discussion / Issue / PR comments are attacker-controlled. Pass IssueOps params via env: and reference them as shell variables ("$NAME") instead of interpolating ${{ ... }} directly into a run: script. See GitHub Actions security hardening for details.
To restrict the action to discussions only (or to issues / pull requests only), use the allowed_contexts input β for example allowed_contexts: 'discussion'.
You can use actions/github-script to add a reaction to the comment that triggered the IssueOps command.
jobs:
demo:
runs-on: ubuntu-latest
steps:
- id: command
uses: knowledge-work/command-action@v1
with:
command: 'greet'
# A snippet to add a reaction to the comment that triggered the command.
- if: ${{ steps.command.outputs.continue == 'true' }}
name: Reactions
uses: actions/github-script@v7
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes',
});
# Add other steps necessary for IssueOps...Please note that this action does not provide a reaction feature. However, by leveraging GitHub Action's awesome ecosystem, you can implement highly flexible IssueOps commands.
Introducing the steps for developing command-action.
Using mise, activate the versions of Node.js and pnpm written in .mise.toml.
$ mise install
$ pnpm iSee LICENSE.
Copyright 2024 Knowledge Work Inc.