Add dispatch-type and support for workflow dispatch
This commit is contained in:
+2
-1
@@ -14,6 +14,7 @@
|
||||
],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"rules": {
|
||||
"@typescript-eslint/camelcase": "off"
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"@typescript-eslint/ban-types": "warn"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
"foo=bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"command": "update",
|
||||
"permission": "write",
|
||||
"issue_type": "issue",
|
||||
"dispatch_type": "workflow"
|
||||
},
|
||||
{
|
||||
"command": "do-something-remotely",
|
||||
"permission": "write",
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
[](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.
|
||||
A GitHub action that facilitates ["ChatOps"](https://www.pagerduty.com/blog/what-is-chatops/) by creating 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.
|
||||
When a valid command is found it creates a [repository dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch) event that includes a payload containing full details of the command and its context.
|
||||
It also supports creating [workflow dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) events with defined input parameters.
|
||||
|
||||
### Why repository dispatch?
|
||||
### Why create dispatch events?
|
||||
|
||||
"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.
|
||||
@@ -32,6 +33,7 @@ See it in action with the following live demos.
|
||||
- [Examples](docs/examples.md)
|
||||
- [Standard configuration](#standard-configuration)
|
||||
- [Advanced configuration](docs/advanced-configuration.md)
|
||||
- [Workflow dispatch](docs/workflow-dispatch.md)
|
||||
- [Updating to v2](docs/updating.md)
|
||||
|
||||
## Dispatching commands
|
||||
@@ -59,7 +61,7 @@ jobs:
|
||||
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.
|
||||
Note that not specifying the `repository` input will mean that 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.
|
||||
|
||||
@@ -77,13 +79,14 @@ This action also features [advanced configuration](docs/advanced-configuration.m
|
||||
| `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` |
|
||||
| `static-args` | A comma or newline separated list of arguments that will be dispatched with every command. | |
|
||||
| `dispatch-type` | The dispatch type; `repository` or `workflow`. See [dispatch-type](#dispatch-type) for further details. | `repository` |
|
||||
| `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.
|
||||
This action creates [`repository_dispatch`](https://developer.github.com/v3/repos/#create-a-repository-dispatch-event) and [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) events.
|
||||
The default `GITHUB_TOKEN` does not have scopes to create these events, 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`
|
||||
@@ -104,6 +107,13 @@ You can use a [PAT](https://help.github.com/en/github/authenticating-to-github/c
|
||||
build-docs
|
||||
```
|
||||
|
||||
#### `dispatch-type`
|
||||
|
||||
By default, the action creates [`repository_dispatch`](https://developer.github.com/v3/repos/#create-a-repository-dispatch-event) events.
|
||||
Setting `dispatch-type` to `workflow` will instead create [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) events.
|
||||
|
||||
There are significant differences in the action's behaviour when using `workflow` dispatch. See [workflow dispatch](docs/workflow-dispatch.md) for usage details.
|
||||
|
||||
### 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.
|
||||
@@ -116,6 +126,9 @@ Slash commands must be placed in the first line of the comment to be interpreted
|
||||
|
||||
## Handling dispatched commands
|
||||
|
||||
The following documentation applies to the `dispatch-type` default, `repository`, which creates [`repository_dispatch`](https://developer.github.com/v3/repos/#create-a-repository-dispatch-event) events.
|
||||
For `workflow` dispatch documentation, see [workflow dispatch](docs/workflow-dispatch.md).
|
||||
|
||||
### 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`.
|
||||
|
||||
@@ -25,6 +25,7 @@ describe('command-helper tests', () => {
|
||||
repository: '',
|
||||
eventTypeSuffix: '-command',
|
||||
staticArgs: [],
|
||||
dispatchType: 'repository',
|
||||
config: '',
|
||||
configFromFile: ''
|
||||
}
|
||||
@@ -40,6 +41,7 @@ describe('command-helper tests', () => {
|
||||
commandDefaults.event_type_suffix
|
||||
)
|
||||
expect(config[i].static_args).toEqual(commandDefaults.static_args)
|
||||
expect(config[i].dispatch_type).toEqual(commandDefaults.dispatch_type)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -56,6 +58,7 @@ describe('command-helper tests', () => {
|
||||
repository: 'owner/repo',
|
||||
eventTypeSuffix: '-cmd',
|
||||
staticArgs: ['production', 'region=us-east-1'],
|
||||
dispatchType: 'workflow',
|
||||
config: '',
|
||||
configFromFile: ''
|
||||
}
|
||||
@@ -69,6 +72,7 @@ describe('command-helper tests', () => {
|
||||
expect(config[i].repository).toEqual(inputs.repository)
|
||||
expect(config[i].event_type_suffix).toEqual(inputs.eventTypeSuffix)
|
||||
expect(config[i].static_args).toEqual(inputs.staticArgs)
|
||||
expect(config[i].dispatch_type).toEqual(inputs.dispatchType)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -93,7 +97,8 @@ describe('command-helper tests', () => {
|
||||
expect(config[i].event_type_suffix).toEqual(
|
||||
commandDefaults.event_type_suffix
|
||||
)
|
||||
expect(config[i].static_args).toEqual(commandDefaults.static_args)
|
||||
expect(config[i].static_args).toEqual(commandDefaults.static_args),
|
||||
expect(config[i].dispatch_type).toEqual(commandDefaults.dispatch_type)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -113,7 +118,8 @@ describe('command-helper tests', () => {
|
||||
"static_args": [
|
||||
"production",
|
||||
"region=us-east-1"
|
||||
]
|
||||
],
|
||||
"dispatch_type": "workflow"
|
||||
}
|
||||
]`
|
||||
const commands = ['do-stuff', 'test-all-the-things']
|
||||
@@ -125,10 +131,13 @@ describe('command-helper tests', () => {
|
||||
expect(config[0].allow_edits).toBeTruthy()
|
||||
expect(config[0].repository).toEqual('owner/repo')
|
||||
expect(config[0].event_type_suffix).toEqual('-cmd')
|
||||
expect(config[0].static_args).toEqual([])
|
||||
expect(config[0].dispatch_type).toEqual('repository')
|
||||
expect(config[1].command).toEqual(commands[1])
|
||||
expect(config[1].permission).toEqual('read')
|
||||
expect(config[1].issue_type).toEqual(commandDefaults.issue_type)
|
||||
expect(config[1].static_args).toEqual(['production', 'region=us-east-1'])
|
||||
expect(config[1].dispatch_type).toEqual('workflow')
|
||||
})
|
||||
|
||||
test('valid config', async () => {
|
||||
@@ -140,7 +149,8 @@ describe('command-helper tests', () => {
|
||||
allow_edits: false,
|
||||
repository: 'peter-evans/slash-command-dispatch',
|
||||
event_type_suffix: '-command',
|
||||
static_args: []
|
||||
static_args: [],
|
||||
dispatch_type: 'repository'
|
||||
}
|
||||
]
|
||||
expect(configIsValid(config)).toBeTruthy()
|
||||
@@ -155,7 +165,8 @@ describe('command-helper tests', () => {
|
||||
allow_edits: false,
|
||||
repository: 'peter-evans/slash-command-dispatch',
|
||||
event_type_suffix: '-command',
|
||||
static_args: []
|
||||
static_args: [],
|
||||
dispatch_type: 'repository'
|
||||
}
|
||||
]
|
||||
expect(configIsValid(config)).toBeFalsy()
|
||||
@@ -170,7 +181,24 @@ describe('command-helper tests', () => {
|
||||
allow_edits: false,
|
||||
repository: 'peter-evans/slash-command-dispatch',
|
||||
event_type_suffix: '-command',
|
||||
static_args: []
|
||||
static_args: [],
|
||||
dispatch_type: 'repository'
|
||||
}
|
||||
]
|
||||
expect(configIsValid(config)).toBeFalsy()
|
||||
})
|
||||
|
||||
test('invalid dispatch type in config', async () => {
|
||||
const config: Command[] = [
|
||||
{
|
||||
command: 'test',
|
||||
permission: 'write',
|
||||
issue_type: 'test-case-invalid-issue-type',
|
||||
allow_edits: false,
|
||||
repository: 'peter-evans/slash-command-dispatch',
|
||||
event_type_suffix: '-command',
|
||||
static_args: [],
|
||||
dispatch_type: 'test-case-invalid-dispatch-type'
|
||||
}
|
||||
]
|
||||
expect(configIsValid(config)).toBeFalsy()
|
||||
|
||||
+4
-1
@@ -1,5 +1,5 @@
|
||||
name: 'Slash Command Dispatch'
|
||||
description: 'Facilitates "ChatOps" by creating repository dispatch events for slash commands'
|
||||
description: 'Facilitates "ChatOps" by creating dispatch events for slash commands'
|
||||
inputs:
|
||||
token:
|
||||
description: 'A repo scoped GitHub Personal Access Token.'
|
||||
@@ -30,6 +30,9 @@ inputs:
|
||||
default: -command
|
||||
static-args:
|
||||
description: 'A comma or newline separated list of arguments that will be dispatched with every command.'
|
||||
dispatch-type:
|
||||
description: 'The dispatch type; `repository` or `workflow`.'
|
||||
default: repository
|
||||
config:
|
||||
description: 'JSON configuration for commands.'
|
||||
config-from-file:
|
||||
|
||||
Vendored
+152
-51
@@ -520,7 +520,7 @@ const core = __importStar(__webpack_require__(470));
|
||||
const github = __importStar(__webpack_require__(469));
|
||||
const util_1 = __webpack_require__(669);
|
||||
const command_helper_1 = __webpack_require__(372);
|
||||
const octokit_client_1 = __webpack_require__(921);
|
||||
const github_helper_1 = __webpack_require__(718);
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
@@ -595,15 +595,15 @@ function run() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Set octokit clients
|
||||
const octokit = new octokit_client_1.Octokit({ auth: `${inputs.token}` });
|
||||
const reactionOctokit = new octokit_client_1.Octokit({ auth: `${inputs.reactionToken}` });
|
||||
// Create github clients
|
||||
const githubHelper = new github_helper_1.GitHubHelper(inputs.token);
|
||||
const githubHelperReaction = new github_helper_1.GitHubHelper(inputs.reactionToken);
|
||||
// At this point we know the command is registered
|
||||
// Add the "eyes" reaction to the comment
|
||||
if (inputs.reactions)
|
||||
yield command_helper_1.addReaction(reactionOctokit, github.context.repo, commentId, 'eyes');
|
||||
yield githubHelperReaction.tryAddReaction(github.context.repo, commentId, 'eyes');
|
||||
// Get the actor permission
|
||||
const actorPermission = yield command_helper_1.getActorPermission(octokit, github.context.repo, github.context.actor);
|
||||
const actorPermission = yield githubHelper.getActorPermission(github.context.repo, github.context.actor);
|
||||
core.debug(`Actor permission: ${actorPermission}`);
|
||||
// Filter matching commands by the user's permission level
|
||||
configMatches = configMatches.filter(function (cmd) {
|
||||
@@ -618,7 +618,6 @@ function run() {
|
||||
core.info(`Command '${commandWords[0]}' to be dispatched.`);
|
||||
// Define payload
|
||||
const clientPayload = {
|
||||
slash_command: {},
|
||||
github: github.context
|
||||
};
|
||||
// Truncate the body to keep the size of the payload under the max
|
||||
@@ -628,7 +627,7 @@ function run() {
|
||||
}
|
||||
// Get the pull request context for the dispatch payload
|
||||
if (isPullRequest) {
|
||||
const { data: pullRequest } = yield octokit.pulls.get(Object.assign(Object.assign({}, github.context.repo), { pull_number: github.context.payload.issue.number }));
|
||||
const pullRequest = yield githubHelper.getPull(github.context.repo, github.context.payload.issue.number);
|
||||
// Truncate the body to keep the size of the payload under the max
|
||||
pullRequest.body = pullRequest.body.slice(0, 1000);
|
||||
clientPayload['pull_request'] = pullRequest;
|
||||
@@ -639,20 +638,11 @@ function run() {
|
||||
clientPayload.slash_command = command_helper_1.getSlashCommandPayload(commandWords, cmd.static_args);
|
||||
core.debug(`Slash command payload: ${util_1.inspect(clientPayload.slash_command)}`);
|
||||
// Dispatch the command
|
||||
const dispatchRepo = cmd.repository.split('/');
|
||||
const eventType = cmd.command + cmd.event_type_suffix;
|
||||
yield octokit.repos.createDispatchEvent({
|
||||
owner: dispatchRepo[0],
|
||||
repo: dispatchRepo[1],
|
||||
event_type: eventType,
|
||||
client_payload: clientPayload
|
||||
});
|
||||
core.info(`Command '${cmd.command}' dispatched to '${cmd.repository}' ` +
|
||||
`with event type '${eventType}'.`);
|
||||
yield githubHelper.createDispatch(cmd, clientPayload);
|
||||
}
|
||||
// Add the "rocket" reaction to the comment
|
||||
if (inputs.reactions)
|
||||
yield command_helper_1.addReaction(reactionOctokit, github.context.repo, commentId, 'rocket');
|
||||
yield githubHelperReaction.tryAddReaction(github.context.repo, commentId, 'rocket');
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(util_1.inspect(error));
|
||||
@@ -933,17 +923,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getSlashCommandPayload = exports.addReaction = exports.getActorPermission = exports.actorHasPermission = exports.configIsValid = exports.getCommandsConfigFromJson = exports.getCommandsConfigFromInputs = exports.getCommandsConfig = exports.getInputs = exports.toBool = exports.commandDefaults = exports.MAX_ARGS = void 0;
|
||||
exports.getSlashCommandPayload = exports.actorHasPermission = exports.configIsValid = exports.getCommandsConfigFromJson = exports.getCommandsConfigFromInputs = exports.getCommandsConfig = exports.getInputs = exports.toBool = exports.commandDefaults = exports.MAX_ARGS = void 0;
|
||||
const core = __importStar(__webpack_require__(470));
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const util_1 = __webpack_require__(669);
|
||||
@@ -956,7 +937,8 @@ exports.commandDefaults = Object.freeze({
|
||||
allow_edits: false,
|
||||
repository: process.env.GITHUB_REPOSITORY || '',
|
||||
event_type_suffix: '-command',
|
||||
static_args: []
|
||||
static_args: [],
|
||||
dispatch_type: 'repository'
|
||||
});
|
||||
function toBool(input, defaultVal) {
|
||||
if (typeof input === 'boolean') {
|
||||
@@ -983,6 +965,7 @@ function getInputs() {
|
||||
repository: core.getInput('repository'),
|
||||
eventTypeSuffix: core.getInput('event-type-suffix'),
|
||||
staticArgs: utils.getInputAsArray('static-args'),
|
||||
dispatchType: core.getInput('dispatch-type'),
|
||||
config: core.getInput('config'),
|
||||
configFromFile: core.getInput('config-from-file')
|
||||
};
|
||||
@@ -1018,7 +1001,8 @@ function getCommandsConfigFromInputs(inputs) {
|
||||
allow_edits: inputs.allowEdits,
|
||||
repository: inputs.repository,
|
||||
event_type_suffix: inputs.eventTypeSuffix,
|
||||
static_args: inputs.staticArgs
|
||||
static_args: inputs.staticArgs,
|
||||
dispatch_type: inputs.dispatchType
|
||||
};
|
||||
config.push(cmd);
|
||||
}
|
||||
@@ -1039,7 +1023,12 @@ function getCommandsConfigFromJson(json) {
|
||||
event_type_suffix: jc.event_type_suffix
|
||||
? jc.event_type_suffix
|
||||
: exports.commandDefaults.event_type_suffix,
|
||||
static_args: jc.static_args ? jc.static_args : exports.commandDefaults.static_args
|
||||
static_args: jc.static_args
|
||||
? jc.static_args
|
||||
: exports.commandDefaults.static_args,
|
||||
dispatch_type: jc.dispatch_type
|
||||
? jc.dispatch_type
|
||||
: exports.commandDefaults.dispatch_type
|
||||
};
|
||||
config.push(cmd);
|
||||
}
|
||||
@@ -1056,6 +1045,10 @@ function configIsValid(config) {
|
||||
core.setFailed(`'${command.issue_type}' is not a valid 'issue-type'.`);
|
||||
return false;
|
||||
}
|
||||
if (!['repository', 'workflow'].includes(command.dispatch_type)) {
|
||||
core.setFailed(`'${command.dispatch_type}' is not a valid 'dispatch-type'.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1072,25 +1065,6 @@ function actorHasPermission(actorPermission, commandPermission) {
|
||||
return (permissionLevels[actorPermission] >= permissionLevels[commandPermission]);
|
||||
}
|
||||
exports.actorHasPermission = actorHasPermission;
|
||||
function getActorPermission(octokit, repo, actor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { data: { permission } } = yield octokit.repos.getCollaboratorPermissionLevel(Object.assign(Object.assign({}, repo), { username: actor }));
|
||||
return permission;
|
||||
});
|
||||
}
|
||||
exports.getActorPermission = getActorPermission;
|
||||
function addReaction(octokit, repo, commentId, reaction) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield octokit.reactions.createForIssueComment(Object.assign(Object.assign({}, repo), { comment_id: commentId, content: reaction }));
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(util_1.inspect(error));
|
||||
core.warning(`Failed to set reaction on comment ID ${commentId}.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.addReaction = addReaction;
|
||||
function getSlashCommandPayload(commandWords, staticArgs) {
|
||||
const payload = {
|
||||
command: commandWords[0],
|
||||
@@ -4676,6 +4650,133 @@ function isPlainObject(o) {
|
||||
module.exports = isPlainObject;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 718:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GitHubHelper = void 0;
|
||||
const core = __importStar(__webpack_require__(470));
|
||||
const octokit_client_1 = __webpack_require__(921);
|
||||
class GitHubHelper {
|
||||
constructor(token) {
|
||||
const options = {};
|
||||
if (token) {
|
||||
options.auth = `${token}`;
|
||||
}
|
||||
this.octokit = new octokit_client_1.Octokit(options);
|
||||
}
|
||||
parseRepository(repository) {
|
||||
const [owner, repo] = repository.split('/');
|
||||
return {
|
||||
owner: owner,
|
||||
repo: repo
|
||||
};
|
||||
}
|
||||
getActorPermission(repo, actor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { data: { permission } } = yield this.octokit.repos.getCollaboratorPermissionLevel(Object.assign(Object.assign({}, repo), { username: actor }));
|
||||
return permission;
|
||||
});
|
||||
}
|
||||
tryAddReaction(repo, commentId, reaction) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield this.octokit.reactions.createForIssueComment(Object.assign(Object.assign({}, repo), { comment_id: commentId, content: reaction }));
|
||||
}
|
||||
catch (error) {
|
||||
core.debug(error);
|
||||
core.warning(`Failed to set reaction on comment ID ${commentId}.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
getPull(repo, pullNumber) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { data: pullRequest } = yield this.octokit.pulls.get(Object.assign(Object.assign({}, repo), { pull_number: pullNumber }));
|
||||
return pullRequest;
|
||||
});
|
||||
}
|
||||
createDispatch(cmd, clientPayload) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (cmd.dispatch_type == 'repository') {
|
||||
yield this.createRepositoryDispatch(cmd, clientPayload);
|
||||
}
|
||||
else {
|
||||
yield this.createWorkflowDispatch(cmd, clientPayload);
|
||||
}
|
||||
});
|
||||
}
|
||||
createRepositoryDispatch(cmd, clientPayload) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const eventType = `${cmd.command}${cmd.event_type_suffix}`;
|
||||
yield this.octokit.repos.createDispatchEvent(Object.assign(Object.assign({}, this.parseRepository(cmd.repository)), { event_type: `${cmd.command}${cmd.event_type_suffix}`, client_payload: clientPayload }));
|
||||
core.info(`Command '${cmd.command}' dispatched to '${cmd.repository}' ` +
|
||||
`with event type '${eventType}'.`);
|
||||
});
|
||||
}
|
||||
createWorkflowDispatch(cmd, clientPayload) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const workflow = `${cmd.command}${cmd.event_type_suffix}.yml`;
|
||||
const slashCommand = clientPayload.slash_command;
|
||||
const ref = slashCommand.args.named.ref
|
||||
? slashCommand.args.named.ref
|
||||
: yield this.getDefaultBranch(cmd.repository);
|
||||
// Take max 10 named arguments, excluding 'ref'.
|
||||
const inputs = {};
|
||||
let count = 0;
|
||||
for (const key in slashCommand.args.named) {
|
||||
if (key != 'ref') {
|
||||
inputs[key] = slashCommand.args.named[key];
|
||||
count++;
|
||||
}
|
||||
if (count == 10)
|
||||
break;
|
||||
}
|
||||
yield this.octokit.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', Object.assign(Object.assign({}, this.parseRepository(cmd.repository)), { workflow_id: workflow, ref: ref, inputs: inputs }));
|
||||
core.info(`Command '${cmd.command}' dispatched to workflow '${workflow}' in '${cmd.repository}'`);
|
||||
});
|
||||
}
|
||||
getDefaultBranch(repository) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { data: repo } = yield this.octokit.repos.get(Object.assign({}, this.parseRepository(repository)));
|
||||
return repo.default_branch;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.GitHubHelper = GitHubHelper;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 747:
|
||||
|
||||
@@ -64,7 +64,8 @@ jobs:
|
||||
"permission": "write",
|
||||
"issue_type": "issue",
|
||||
"allow_edits": true,
|
||||
"event_type_suffix": "-cmd"
|
||||
"event_type_suffix": "-cmd",
|
||||
"dispatch_type": "workflow"
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -105,5 +106,6 @@ Advanced configuration requires a combination of yaml based inputs and JSON conf
|
||||
| | `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 command. | `-command` |
|
||||
| | `static_args` | A string array of arguments that will be dispatched with the command. | `[]` |
|
||||
| | `dispatch_type` | The dispatch type; `repository` or `workflow`. | `repository` |
|
||||
| `config` | | JSON configuration for commands. | |
|
||||
| `config-from-file` | | JSON configuration from a file for commands. | |
|
||||
|
||||
+4
-1
@@ -50,9 +50,12 @@
|
||||
region=us-east-1
|
||||
```
|
||||
Advanced configuration:
|
||||
```yml
|
||||
```json
|
||||
"static_args": [
|
||||
"production",
|
||||
"region=us-east-1"
|
||||
]
|
||||
```
|
||||
|
||||
- Commands can now be dispatched via the new [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) event. For standard configuration, set the new `dispatch-type` input to `workflow`. For advanced configuration, set the `dispatch_type` JSON property of a command to `workflow`.
|
||||
There are significant differences in the action's behaviour when using `workflow` dispatch. See [workflow dispatch](workflow-dispatch.md) for usage details.
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Workflow dispatch
|
||||
|
||||
This documentation applies when the `dispatch-type` input is set to `workflow`, which instructs the action to create [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) events.
|
||||
|
||||
To learn about the `workflow_dispatch` event, see GitHub's documentation on [manually running a workflow](https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#manually-running-a-workflow).
|
||||
|
||||
## Action behaviour
|
||||
|
||||
There are significant differences in the action's behaviour when using `workflow` dispatch.
|
||||
|
||||
- When issuing a slash command with arguments, *only named arguments are accepted*. Unnamed arguments will be ignored.
|
||||
- A maximum of 10 named arguments are accepted. Additional named arguments after the first 10 will be ignored.
|
||||
- `ref` is a reserved named argument that does not count towards the maximum of 10. This is used to specify the target reference of the command. The reference can be a branch, tag, or a commit SHA. If you omit the `ref` argument, the target repository's default branch will be used.
|
||||
- A `client_payload` context cannot be sent with [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) events. The target workflow can only make use of up to 10 pre-defined inputs, the names of which must match the named arguments supplied with the slash command.
|
||||
|
||||
## Handling dispatched commands
|
||||
|
||||
### Workflow name
|
||||
|
||||
It is important to name the `workflow_dispatch` event workflow correctly since the action targets the workflow based on its filename. The target filename is a combination of the command name and the `event-type-suffix`.
|
||||
|
||||
For the following example configuration, the target workflows are:
|
||||
- `deploy-command.yml`
|
||||
- `integration-test-command.yml`
|
||||
- `build-docs-command.yml`
|
||||
|
||||
```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@v2
|
||||
with:
|
||||
token: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||
commands: |
|
||||
deploy
|
||||
integration-test
|
||||
build-docs
|
||||
dispatch-type: workflow
|
||||
```
|
||||
|
||||
### Responding to the comment on command completion
|
||||
|
||||
In order to respond to the comment where the slash command was made we need to pass the `comment-id` and `repository` (if the target workflow is not in the current repository). Set static arguments as follows. Note that these static arguments will count towards the maximum of 10 named arguments.
|
||||
|
||||
Using basic configuration:
|
||||
```yml
|
||||
static-args: |
|
||||
repository=${{ github.repository }}
|
||||
comment-id=${{ github.event.issue.comment-id }}
|
||||
```
|
||||
|
||||
Using advanced configuration:
|
||||
```json
|
||||
"static_args": [
|
||||
"repository=${{ github.repository }}",
|
||||
"comment-id=${{ github.event.issue.comment-id }}"
|
||||
]
|
||||
```
|
||||
|
||||
The target workflow must define these arguments as inputs.
|
||||
|
||||
```yml
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
repository:
|
||||
description: 'The repository from which the slash command was dispatched'
|
||||
required: true
|
||||
comment-id:
|
||||
description: 'The comment-id of the slash command'
|
||||
required: true
|
||||
```
|
||||
|
||||
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.inputs.repository }}
|
||||
comment-id: ${{ github.event.inputs.comment-id }}
|
||||
reaction-type: hooray
|
||||
```
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "slash-command-dispatch",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+3
-2
@@ -2,7 +2,7 @@
|
||||
"name": "slash-command-dispatch",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"description": "Create repository dispatch events for slash commands",
|
||||
"description": "Facilitates 'ChatOps' by creating dispatch events for slash commands",
|
||||
"main": "lib/main.js",
|
||||
"scripts": {
|
||||
"build": "tsc && ncc build",
|
||||
@@ -31,7 +31,8 @@
|
||||
"@actions/github": "4.0.0",
|
||||
"@octokit/core": "3.1.1",
|
||||
"@octokit/plugin-paginate-rest": "2.2.3",
|
||||
"@octokit/plugin-rest-endpoint-methods": "4.1.0"
|
||||
"@octokit/plugin-rest-endpoint-methods": "4.1.0",
|
||||
"@octokit/types": "5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "26.0.5",
|
||||
|
||||
+19
-49
@@ -1,7 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as fs from 'fs'
|
||||
import {inspect} from 'util'
|
||||
import {Octokit} from './octokit-client'
|
||||
import * as utils from './utils'
|
||||
|
||||
const NAMED_ARG_PATTERN = /^(?<name>[a-zA-Z0-9_]+)=(?<value>[^\s]+)$/
|
||||
@@ -19,6 +18,7 @@ export interface Inputs {
|
||||
repository: string
|
||||
eventTypeSuffix: string
|
||||
staticArgs: string[]
|
||||
dispatchType: string
|
||||
config: string
|
||||
configFromFile: string
|
||||
}
|
||||
@@ -31,11 +31,7 @@ export interface Command {
|
||||
repository: string
|
||||
event_type_suffix: string
|
||||
static_args: string[]
|
||||
}
|
||||
|
||||
interface Repo {
|
||||
owner: string
|
||||
repo: string
|
||||
dispatch_type: string
|
||||
}
|
||||
|
||||
export interface SlashCommandPayload {
|
||||
@@ -58,7 +54,8 @@ export const commandDefaults = Object.freeze({
|
||||
allow_edits: false,
|
||||
repository: process.env.GITHUB_REPOSITORY || '',
|
||||
event_type_suffix: '-command',
|
||||
static_args: []
|
||||
static_args: [],
|
||||
dispatch_type: 'repository'
|
||||
})
|
||||
|
||||
export function toBool(input: string, defaultVal: boolean): boolean {
|
||||
@@ -84,6 +81,7 @@ export function getInputs(): Inputs {
|
||||
repository: core.getInput('repository'),
|
||||
eventTypeSuffix: core.getInput('event-type-suffix'),
|
||||
staticArgs: utils.getInputAsArray('static-args'),
|
||||
dispatchType: core.getInput('dispatch-type'),
|
||||
config: core.getInput('config'),
|
||||
configFromFile: core.getInput('config-from-file')
|
||||
}
|
||||
@@ -118,7 +116,8 @@ export function getCommandsConfigFromInputs(inputs: Inputs): Command[] {
|
||||
allow_edits: inputs.allowEdits,
|
||||
repository: inputs.repository,
|
||||
event_type_suffix: inputs.eventTypeSuffix,
|
||||
static_args: inputs.staticArgs
|
||||
static_args: inputs.staticArgs,
|
||||
dispatch_type: inputs.dispatchType
|
||||
}
|
||||
config.push(cmd)
|
||||
}
|
||||
@@ -140,7 +139,12 @@ export function getCommandsConfigFromJson(json: string): Command[] {
|
||||
event_type_suffix: jc.event_type_suffix
|
||||
? jc.event_type_suffix
|
||||
: commandDefaults.event_type_suffix,
|
||||
static_args: jc.static_args ? jc.static_args : commandDefaults.static_args
|
||||
static_args: jc.static_args
|
||||
? jc.static_args
|
||||
: commandDefaults.static_args,
|
||||
dispatch_type: jc.dispatch_type
|
||||
? jc.dispatch_type
|
||||
: commandDefaults.dispatch_type
|
||||
}
|
||||
config.push(cmd)
|
||||
}
|
||||
@@ -157,6 +161,12 @@ export function configIsValid(config: Command[]): boolean {
|
||||
core.setFailed(`'${command.issue_type}' is not a valid 'issue-type'.`)
|
||||
return false
|
||||
}
|
||||
if (!['repository', 'workflow'].includes(command.dispatch_type)) {
|
||||
core.setFailed(
|
||||
`'${command.dispatch_type}' is not a valid 'dispatch-type'.`
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -178,46 +188,6 @@ export function actorHasPermission(
|
||||
)
|
||||
}
|
||||
|
||||
export async function getActorPermission(
|
||||
octokit: InstanceType<typeof Octokit>,
|
||||
repo: Repo,
|
||||
actor: string
|
||||
): Promise<string> {
|
||||
const {
|
||||
data: {permission}
|
||||
} = await octokit.repos.getCollaboratorPermissionLevel({
|
||||
...repo,
|
||||
username: actor
|
||||
})
|
||||
return permission
|
||||
}
|
||||
|
||||
export async function addReaction(
|
||||
octokit: InstanceType<typeof Octokit>,
|
||||
repo: Repo,
|
||||
commentId: number,
|
||||
reaction:
|
||||
| '+1'
|
||||
| '-1'
|
||||
| 'laugh'
|
||||
| 'confused'
|
||||
| 'heart'
|
||||
| 'hooray'
|
||||
| 'rocket'
|
||||
| 'eyes'
|
||||
): Promise<void> {
|
||||
try {
|
||||
await octokit.reactions.createForIssueComment({
|
||||
...repo,
|
||||
comment_id: commentId,
|
||||
content: reaction
|
||||
})
|
||||
} catch (error) {
|
||||
core.debug(inspect(error))
|
||||
core.warning(`Failed to set reaction on comment ID ${commentId}.`)
|
||||
}
|
||||
}
|
||||
|
||||
export function getSlashCommandPayload(
|
||||
commandWords: string[],
|
||||
staticArgs: string[]
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
import * as core from '@actions/core'
|
||||
import {Octokit, OctokitOptions, PullsGetResponseData} from './octokit-client'
|
||||
import {Command, SlashCommandPayload} from './command-helper'
|
||||
|
||||
type ReposCreateDispatchEventParamsClientPayload = {
|
||||
[key: string]: ReposCreateDispatchEventParamsClientPayloadKeyString
|
||||
}
|
||||
type ReposCreateDispatchEventParamsClientPayloadKeyString = {}
|
||||
|
||||
export interface ClientPayload
|
||||
extends ReposCreateDispatchEventParamsClientPayload {
|
||||
github: any
|
||||
pull_request?: any
|
||||
slash_command?: SlashCommandPayload | any
|
||||
}
|
||||
|
||||
interface Repository {
|
||||
owner: string
|
||||
repo: string
|
||||
}
|
||||
|
||||
export class GitHubHelper {
|
||||
private octokit: InstanceType<typeof Octokit>
|
||||
|
||||
constructor(token: string) {
|
||||
const options: OctokitOptions = {}
|
||||
if (token) {
|
||||
options.auth = `${token}`
|
||||
}
|
||||
this.octokit = new Octokit(options)
|
||||
}
|
||||
|
||||
private parseRepository(repository: string): Repository {
|
||||
const [owner, repo] = repository.split('/')
|
||||
return {
|
||||
owner: owner,
|
||||
repo: repo
|
||||
}
|
||||
}
|
||||
|
||||
async getActorPermission(repo: Repository, actor: string): Promise<string> {
|
||||
const {
|
||||
data: {permission}
|
||||
} = await this.octokit.repos.getCollaboratorPermissionLevel({
|
||||
...repo,
|
||||
username: actor
|
||||
})
|
||||
return permission
|
||||
}
|
||||
|
||||
async tryAddReaction(
|
||||
repo: Repository,
|
||||
commentId: number,
|
||||
reaction:
|
||||
| '+1'
|
||||
| '-1'
|
||||
| 'laugh'
|
||||
| 'confused'
|
||||
| 'heart'
|
||||
| 'hooray'
|
||||
| 'rocket'
|
||||
| 'eyes'
|
||||
): Promise<void> {
|
||||
try {
|
||||
await this.octokit.reactions.createForIssueComment({
|
||||
...repo,
|
||||
comment_id: commentId,
|
||||
content: reaction
|
||||
})
|
||||
} catch (error) {
|
||||
core.debug(error)
|
||||
core.warning(`Failed to set reaction on comment ID ${commentId}.`)
|
||||
}
|
||||
}
|
||||
|
||||
async getPull(
|
||||
repo: Repository,
|
||||
pullNumber: number
|
||||
): Promise<PullsGetResponseData> {
|
||||
const {data: pullRequest} = await this.octokit.pulls.get({
|
||||
...repo,
|
||||
pull_number: pullNumber
|
||||
})
|
||||
return pullRequest
|
||||
}
|
||||
|
||||
async createDispatch(
|
||||
cmd: Command,
|
||||
clientPayload: ClientPayload
|
||||
): Promise<void> {
|
||||
if (cmd.dispatch_type == 'repository') {
|
||||
await this.createRepositoryDispatch(cmd, clientPayload)
|
||||
} else {
|
||||
await this.createWorkflowDispatch(cmd, clientPayload)
|
||||
}
|
||||
}
|
||||
|
||||
private async createRepositoryDispatch(
|
||||
cmd: Command,
|
||||
clientPayload: ClientPayload
|
||||
): Promise<void> {
|
||||
const eventType = `${cmd.command}${cmd.event_type_suffix}`
|
||||
await this.octokit.repos.createDispatchEvent({
|
||||
...this.parseRepository(cmd.repository),
|
||||
event_type: `${cmd.command}${cmd.event_type_suffix}`,
|
||||
client_payload: clientPayload
|
||||
})
|
||||
core.info(
|
||||
`Command '${cmd.command}' dispatched to '${cmd.repository}' ` +
|
||||
`with event type '${eventType}'.`
|
||||
)
|
||||
}
|
||||
|
||||
async createWorkflowDispatch(
|
||||
cmd: Command,
|
||||
clientPayload: ClientPayload
|
||||
): Promise<void> {
|
||||
const workflow = `${cmd.command}${cmd.event_type_suffix}.yml`
|
||||
const slashCommand: SlashCommandPayload = clientPayload.slash_command
|
||||
const ref = slashCommand.args.named.ref
|
||||
? slashCommand.args.named.ref
|
||||
: await this.getDefaultBranch(cmd.repository)
|
||||
|
||||
// Take max 10 named arguments, excluding 'ref'.
|
||||
const inputs = {}
|
||||
let count = 0
|
||||
for (const key in slashCommand.args.named) {
|
||||
if (key != 'ref') {
|
||||
inputs[key] = slashCommand.args.named[key]
|
||||
count++
|
||||
}
|
||||
if (count == 10) break
|
||||
}
|
||||
|
||||
await this.octokit.request(
|
||||
'POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches',
|
||||
{
|
||||
...this.parseRepository(cmd.repository),
|
||||
workflow_id: workflow,
|
||||
ref: ref,
|
||||
inputs: inputs
|
||||
}
|
||||
)
|
||||
core.info(
|
||||
`Command '${cmd.command}' dispatched to workflow '${workflow}' in '${cmd.repository}'`
|
||||
)
|
||||
}
|
||||
|
||||
private async getDefaultBranch(repository: string): Promise<string> {
|
||||
const {data: repo} = await this.octokit.repos.get({
|
||||
...this.parseRepository(repository)
|
||||
})
|
||||
return repo.default_branch
|
||||
}
|
||||
|
||||
// private async createOrUpdate(
|
||||
// inputs: Inputs,
|
||||
// baseRepository: string,
|
||||
// headBranch: string
|
||||
// ): Promise<number> {
|
||||
// // Try to create the pull request
|
||||
// try {
|
||||
// const {data: pull} = await this.octokit.pulls.create({
|
||||
// ...this.parseRepository(baseRepository),
|
||||
// title: inputs.title,
|
||||
// head: headBranch,
|
||||
// base: inputs.base,
|
||||
// body: inputs.body,
|
||||
// draft: inputs.draft
|
||||
// })
|
||||
// core.info(
|
||||
// `Created pull request #${pull.number} (${headBranch} => ${inputs.base})`
|
||||
// )
|
||||
// return pull.number
|
||||
// } catch (e) {
|
||||
// if (
|
||||
// !e.message ||
|
||||
// !e.message.includes(`A pull request already exists for ${headBranch}`)
|
||||
// ) {
|
||||
// throw e
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Update the pull request that exists for this branch and base
|
||||
// const {data: pulls} = await this.octokit.pulls.list({
|
||||
// ...this.parseRepository(baseRepository),
|
||||
// state: 'open',
|
||||
// head: headBranch,
|
||||
// base: inputs.base
|
||||
// })
|
||||
// const {data: pull} = await this.octokit.pulls.update({
|
||||
// ...this.parseRepository(baseRepository),
|
||||
// pull_number: pulls[0].number,
|
||||
// title: inputs.title,
|
||||
// body: inputs.body,
|
||||
// draft: inputs.draft
|
||||
// })
|
||||
// core.info(
|
||||
// `Updated pull request #${pull.number} (${headBranch} => ${inputs.base})`
|
||||
// )
|
||||
// return pull.number
|
||||
// }
|
||||
|
||||
// async getRepositoryParent(headRepository: string): Promise<string> {
|
||||
// const {data: headRepo} = await this.octokit.repos.get({
|
||||
// ...this.parseRepository(headRepository)
|
||||
// })
|
||||
// if (!headRepo.parent) {
|
||||
// throw new Error(
|
||||
// `Repository '${headRepository}' is not a fork. Unable to continue.`
|
||||
// )
|
||||
// }
|
||||
// return headRepo.parent.full_name
|
||||
// }
|
||||
|
||||
// async createOrUpdatePullRequest(
|
||||
// inputs: Inputs,
|
||||
// baseRepository: string,
|
||||
// headRepository: string
|
||||
// ): Promise<void> {
|
||||
// const [headOwner] = headRepository.split('/')
|
||||
// const headBranch = `${headOwner}:${inputs.branch}`
|
||||
|
||||
// // Create or update the pull request
|
||||
// const pullNumber = await this.createOrUpdate(
|
||||
// inputs,
|
||||
// baseRepository,
|
||||
// headBranch
|
||||
// )
|
||||
|
||||
// // Set outputs
|
||||
// core.startGroup('Setting outputs')
|
||||
// core.setOutput('pull-request-number', pullNumber)
|
||||
// core.exportVariable('PULL_REQUEST_NUMBER', pullNumber)
|
||||
// core.endGroup()
|
||||
|
||||
// // Set milestone, labels and assignees
|
||||
// const updateIssueParams = {}
|
||||
// if (inputs.milestone) {
|
||||
// updateIssueParams['milestone'] = inputs.milestone
|
||||
// core.info(`Applying milestone '${inputs.milestone}'`)
|
||||
// }
|
||||
// if (inputs.labels.length > 0) {
|
||||
// updateIssueParams['labels'] = inputs.labels
|
||||
// core.info(`Applying labels '${inputs.labels}'`)
|
||||
// }
|
||||
// if (inputs.assignees.length > 0) {
|
||||
// updateIssueParams['assignees'] = inputs.assignees
|
||||
// core.info(`Applying assignees '${inputs.assignees}'`)
|
||||
// }
|
||||
// if (Object.keys(updateIssueParams).length > 0) {
|
||||
// await this.octokit.issues.update({
|
||||
// ...this.parseRepository(baseRepository),
|
||||
// issue_number: pullNumber,
|
||||
// ...updateIssueParams
|
||||
// })
|
||||
// }
|
||||
|
||||
// // Request reviewers and team reviewers
|
||||
// const requestReviewersParams = {}
|
||||
// if (inputs.reviewers.length > 0) {
|
||||
// requestReviewersParams['reviewers'] = inputs.reviewers
|
||||
// core.info(`Requesting reviewers '${inputs.reviewers}'`)
|
||||
// }
|
||||
// if (inputs.teamReviewers.length > 0) {
|
||||
// requestReviewersParams['team_reviewers'] = inputs.teamReviewers
|
||||
// core.info(`Requesting team reviewers '${inputs.teamReviewers}'`)
|
||||
// }
|
||||
// if (Object.keys(requestReviewersParams).length > 0) {
|
||||
// try {
|
||||
// await this.octokit.pulls.requestReviewers({
|
||||
// ...this.parseRepository(baseRepository),
|
||||
// pull_number: pullNumber,
|
||||
// ...requestReviewersParams
|
||||
// })
|
||||
// } catch (e) {
|
||||
// if (e.message && e.message.includes(ERROR_PR_REVIEW_FROM_AUTHOR)) {
|
||||
// core.warning(ERROR_PR_REVIEW_FROM_AUTHOR)
|
||||
// } else {
|
||||
// throw e
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
+17
-29
@@ -6,11 +6,9 @@ import {
|
||||
getCommandsConfig,
|
||||
configIsValid,
|
||||
actorHasPermission,
|
||||
getActorPermission,
|
||||
addReaction,
|
||||
getSlashCommandPayload
|
||||
} from './command-helper'
|
||||
import {Octokit} from './octokit-client'
|
||||
import {GitHubHelper, ClientPayload} from './github-helper'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
@@ -108,18 +106,21 @@ async function run(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// Set octokit clients
|
||||
const octokit = new Octokit({auth: `${inputs.token}`})
|
||||
const reactionOctokit = new Octokit({auth: `${inputs.reactionToken}`})
|
||||
// Create github clients
|
||||
const githubHelper = new GitHubHelper(inputs.token)
|
||||
const githubHelperReaction = new GitHubHelper(inputs.reactionToken)
|
||||
|
||||
// At this point we know the command is registered
|
||||
// Add the "eyes" reaction to the comment
|
||||
if (inputs.reactions)
|
||||
await addReaction(reactionOctokit, github.context.repo, commentId, 'eyes')
|
||||
await githubHelperReaction.tryAddReaction(
|
||||
github.context.repo,
|
||||
commentId,
|
||||
'eyes'
|
||||
)
|
||||
|
||||
// Get the actor permission
|
||||
const actorPermission = await getActorPermission(
|
||||
octokit,
|
||||
const actorPermission = await githubHelper.getActorPermission(
|
||||
github.context.repo,
|
||||
github.context.actor
|
||||
)
|
||||
@@ -141,8 +142,7 @@ async function run(): Promise<void> {
|
||||
core.info(`Command '${commandWords[0]}' to be dispatched.`)
|
||||
|
||||
// Define payload
|
||||
const clientPayload = {
|
||||
slash_command: {},
|
||||
const clientPayload: ClientPayload = {
|
||||
github: github.context
|
||||
}
|
||||
// Truncate the body to keep the size of the payload under the max
|
||||
@@ -158,10 +158,10 @@ async function run(): Promise<void> {
|
||||
|
||||
// Get the pull request context for the dispatch payload
|
||||
if (isPullRequest) {
|
||||
const {data: pullRequest} = await octokit.pulls.get({
|
||||
...github.context.repo,
|
||||
pull_number: github.context.payload.issue.number
|
||||
})
|
||||
const pullRequest = await githubHelper.getPull(
|
||||
github.context.repo,
|
||||
github.context.payload.issue.number
|
||||
)
|
||||
// Truncate the body to keep the size of the payload under the max
|
||||
pullRequest.body = pullRequest.body.slice(0, 1000)
|
||||
clientPayload['pull_request'] = pullRequest
|
||||
@@ -178,24 +178,12 @@ async function run(): Promise<void> {
|
||||
`Slash command payload: ${inspect(clientPayload.slash_command)}`
|
||||
)
|
||||
// Dispatch the command
|
||||
const dispatchRepo = cmd.repository.split('/')
|
||||
const eventType = cmd.command + cmd.event_type_suffix
|
||||
await octokit.repos.createDispatchEvent({
|
||||
owner: dispatchRepo[0],
|
||||
repo: dispatchRepo[1],
|
||||
event_type: eventType,
|
||||
client_payload: clientPayload
|
||||
})
|
||||
core.info(
|
||||
`Command '${cmd.command}' dispatched to '${cmd.repository}' ` +
|
||||
`with event type '${eventType}'.`
|
||||
)
|
||||
await githubHelper.createDispatch(cmd, clientPayload)
|
||||
}
|
||||
|
||||
// Add the "rocket" reaction to the comment
|
||||
if (inputs.reactions)
|
||||
await addReaction(
|
||||
reactionOctokit,
|
||||
await githubHelperReaction.tryAddReaction(
|
||||
github.context.repo,
|
||||
commentId,
|
||||
'rocket'
|
||||
|
||||
@@ -5,3 +5,5 @@ export {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods'
|
||||
export {OctokitOptions} from '@octokit/core/dist-types/types'
|
||||
|
||||
export const Octokit = Core.plugin(paginateRest, restEndpointMethods)
|
||||
|
||||
export {PullsGetResponseData} from '@octokit/types'
|
||||
|
||||
Reference in New Issue
Block a user