Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Bot as an actor #297

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
51 changes: 40 additions & 11 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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'),
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.`);
Expand Down
19 changes: 19 additions & 0 deletions src/command-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface Inputs {
commands: string[]
permission: string
issueType: string
allowBots: string[]
allowEdits: boolean
repository: string
eventTypeSuffix: string
Expand All @@ -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
Expand All @@ -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',
Expand All @@ -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'),
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
48 changes: 32 additions & 16 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,39 @@ async function run(): Promise<void> {
'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
Expand Down