diff --git a/action.yml b/action.yml index 7c4ced52d..a522be118 100644 --- a/action.yml +++ b/action.yml @@ -19,9 +19,12 @@ inputs: issue-type: description: 'The issue type required for commands.' default: both + allow-bots: + description: 'a comma or newline separated list of bots that are allowed to trigger command dispatches.' + default: '' allow-edits: description: 'Allow edited comments to trigger command dispatches.' - default: false + default: 'false' repository: description: 'The full name of the repository to send the dispatch events.' default: ${{ github.repository }} diff --git a/dist/index.js b/dist/index.js index 058bbb06d..a4a9bcfe7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -43,6 +43,7 @@ exports.MAX_ARGS = 50; exports.commandDefaults = Object.freeze({ permission: 'write', issue_type: 'both', + allow_bots: [], allow_edits: false, repository: process.env.GITHUB_REPOSITORY || '', event_type_suffix: '-command', @@ -70,6 +71,7 @@ function getInputs() { commands: utils.getInputAsArray('commands'), permission: core.getInput('permission'), issueType: core.getInput('issue-type'), + allowBots: utils.getInputAsArray('allow-bots'), allowEdits: core.getInput('allow-edits') === 'true', repository: core.getInput('repository'), eventTypeSuffix: core.getInput('event-type-suffix'), @@ -107,6 +109,7 @@ function getCommandsConfigFromInputs(inputs) { command: c, permission: inputs.permission, issue_type: inputs.issueType, + allow_bots: inputs.allowBots, allow_edits: inputs.allowEdits, repository: inputs.repository, event_type_suffix: inputs.eventTypeSuffix, @@ -127,6 +130,7 @@ function getCommandsConfigFromJson(json) { command: jc.command, permission: jc.permission ? jc.permission : exports.commandDefaults.permission, issue_type: jc.issue_type ? jc.issue_type : exports.commandDefaults.issue_type, + allow_bots: jc.allow_bots ? jc.allow_bots : exports.commandDefaults.allow_bots, allow_edits: toBool(jc.allow_edits, exports.commandDefaults.allow_edits), repository: jc.repository ? jc.repository : exports.commandDefaults.repository, event_type_suffix: jc.event_type_suffix @@ -158,6 +162,17 @@ function configIsValid(config) { core.setFailed(`'${command.dispatch_type}' is not a valid 'dispatch-type'.`); return false; } + if (command.allow_bots !== undefined) { + if (!Array.isArray(command.allow_bots)) { + core.setFailed(`'allow_bots' must be an array`); + return false; + } + const invalidBotNames = command.allow_bots.filter((name) => !name.endsWith('[bot]')); + if (invalidBotNames.length > 0) { + core.setFailed(`${invalidBotNames.map((name) => `'${name}'`).join(', ')} are not the valid bot names.`); + return false; + } + } } return true; } @@ -430,6 +445,7 @@ const command_helper_1 = __nccwpck_require__(9622); const github_helper_1 = __nccwpck_require__(446); const utils = __importStar(__nccwpck_require__(918)); function run() { + var _a; return __awaiter(this, void 0, void 0, function* () { try { // Check required context properties exist (satisfy type checking) @@ -510,17 +526,30 @@ function run() { // Add the "eyes" reaction to the comment if (inputs.reactions) yield githubHelperReaction.tryAddReaction(github.context.repo, commentId, 'eyes'); - // Get the actor permission - 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) { - return (0, command_helper_1.actorHasPermission)(actorPermission, cmd.permission); - }); - core.debug(`Config matches on 'permission': ${(0, util_1.inspect)(configMatches)}`); - if (configMatches.length == 0) { - core.info(`Command '${commandTokens[0]}' is not configured for the user's permission level '${actorPermission}'.`); - return; + const isBot = ((_a = github.context.payload.sender) === null || _a === void 0 ? void 0 : _a.type) === 'Bot'; + if (!isBot) { + // Get the actor permission + 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) { + return (0, command_helper_1.actorHasPermission)(actorPermission, cmd.permission); + }); + core.debug(`Config matches on 'permission': ${(0, util_1.inspect)(configMatches)}`); + if (configMatches.length == 0) { + core.info(`Command '${commandTokens[0]}' is not configured for the user's permission level '${actorPermission}'.`); + return; + } + } + else { + core.debug(`Bot actor: ${github.context.actor}`); + configMatches = configMatches.filter(function (cmd) { + return cmd.allow_bots.includes(github.context.actor); + }); + if (configMatches.length == 0) { + core.info(`Command '${commandTokens[0]}' is not configured to allow bot '${github.context.actor}'.`); + return; + } } // Determined that the command should be dispatched core.info(`Command '${commandTokens[0]}' to be dispatched.`); diff --git a/src/command-helper.ts b/src/command-helper.ts index 42e7b3db3..030f24337 100644 --- a/src/command-helper.ts +++ b/src/command-helper.ts @@ -18,6 +18,7 @@ export interface Inputs { commands: string[] permission: string issueType: string + allowBots: string[] allowEdits: boolean repository: string eventTypeSuffix: string @@ -31,6 +32,7 @@ export interface Command { command: string permission: string issue_type: string + allow_bots: string[] allow_edits: boolean repository: string event_type_suffix: string @@ -55,6 +57,7 @@ export interface SlashCommandPayload { export const commandDefaults = Object.freeze({ permission: 'write', issue_type: 'both', + allow_bots: [], allow_edits: false, repository: process.env.GITHUB_REPOSITORY || '', event_type_suffix: '-command', @@ -81,6 +84,7 @@ export function getInputs(): Inputs { commands: utils.getInputAsArray('commands'), permission: core.getInput('permission'), issueType: core.getInput('issue-type'), + allowBots: utils.getInputAsArray('allow-bots'), allowEdits: core.getInput('allow-edits') === 'true', repository: core.getInput('repository'), eventTypeSuffix: core.getInput('event-type-suffix'), @@ -117,6 +121,7 @@ export function getCommandsConfigFromInputs(inputs: Inputs): Command[] { command: c, permission: inputs.permission, issue_type: inputs.issueType, + allow_bots: inputs.allowBots, allow_edits: inputs.allowEdits, repository: inputs.repository, event_type_suffix: inputs.eventTypeSuffix, @@ -138,6 +143,7 @@ export function getCommandsConfigFromJson(json: string): Command[] { command: jc.command, permission: jc.permission ? jc.permission : commandDefaults.permission, issue_type: jc.issue_type ? jc.issue_type : commandDefaults.issue_type, + allow_bots: jc.allow_bots ? jc.allow_bots : commandDefaults.allow_bots, allow_edits: toBool(jc.allow_edits, commandDefaults.allow_edits), repository: jc.repository ? jc.repository : commandDefaults.repository, event_type_suffix: jc.event_type_suffix @@ -175,6 +181,19 @@ export function configIsValid(config: Command[]): boolean { ) return false } + if (command.allow_bots !== undefined ) { + if (!Array.isArray(command.allow_bots)) { + core.setFailed(`'allow_bots' must be an array`) + return false + } + + const invalidBotNames = command.allow_bots.filter((name) => !name.endsWith('[bot]')) + if (invalidBotNames.length > 0) { + core.setFailed(`${invalidBotNames.map((name) => `'${name}'`).join(', ')} are not the valid bot names.` ) + return false + } + } + } return true } diff --git a/src/main.ts b/src/main.ts index 889ac831d..4b5082c27 100644 --- a/src/main.ts +++ b/src/main.ts @@ -121,23 +121,39 @@ async function run(): Promise { 'eyes' ) - // Get the actor permission - const actorPermission = await 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) { - return actorHasPermission(actorPermission, cmd.permission) - }) - core.debug(`Config matches on 'permission': ${inspect(configMatches)}`) - if (configMatches.length == 0) { - core.info( - `Command '${commandTokens[0]}' is not configured for the user's permission level '${actorPermission}'.` + const isBot = github.context.payload.sender?.type === 'Bot' + + if (!isBot) { + // Get the actor permission + const actorPermission = await githubHelper.getActorPermission( + github.context.repo, + github.context.actor ) - return + core.debug(`Actor permission: ${actorPermission}`) + + // Filter matching commands by the user's permission level + configMatches = configMatches.filter(function (cmd) { + return actorHasPermission(actorPermission, cmd.permission) + }) + core.debug(`Config matches on 'permission': ${inspect(configMatches)}`) + if (configMatches.length == 0) { + core.info( + `Command '${commandTokens[0]}' is not configured for the user's permission level '${actorPermission}'.` + ) + return + } + } else { + core.debug(`Bot actor: ${github.context.actor}`) + configMatches = configMatches.filter(function (cmd) { + return cmd.allow_bots.includes(github.context.actor) + }) + + if (configMatches.length == 0) { + core.info( + `Command '${commandTokens[0]}' is not configured to allow bot '${github.context.actor}'.` + ) + return + } } // Determined that the command should be dispatched