Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,31 @@ Default configuration:
commands:
close:
enabled: false
permission: all
label:
allowedLabels: [] # any label is allowed
enabled: false
permission: all
removeLabel:
allowedLabels: [] # any label is allowed
enabled: false
permission: all
reopen:
enabled: false
permission: all
reviewer:
enabled: false
permission: all
transfer:
enabled: false
permission: all
```

`permission` is optional and defaults to `all`. Supported values are:

- `all` - anyone who can comment can use the command
- `member` - only organization members and owners can use the command

## Getting started

First you will need to create a GitHub app. Add the permissions required for the commands you are using (see next section), and tick "Subscribe to events" > "Issue comment"
Expand Down
86 changes: 72 additions & 14 deletions app/command-enabled.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,75 @@ const enabled = {
enabled: true,
};

const orgMemberAssociations = new Set(["MEMBER", "OWNER"]);

function notEnabled(command) {
return {
enabled: false,
error: `The \`${command}\` command is not enabled for this repository`,
};
}

function invalidPermission(command, permission) {
return {
enabled: false,
error: `The \`${command}\` command has an unsupported permission level \`${permission}\``,
};
}

function notPermitted(command) {
return {
enabled: false,
error: `The \`${command}\` command is restricted to organization members`,
};
}

function trimLabels(labels) {
return labels.map((it) => it.trim());
}

export function transferEnabled(config) {
if (!config.commands.transfer.enabled) {
function permissionEnabled(command, commandConfig, authorAssociation) {
const permission = commandConfig.permission ?? "all";

if (permission === "all") {
return enabled;
}

if (permission === "member") {
return orgMemberAssociations.has(authorAssociation)
? enabled
: notPermitted(command);
}

return invalidPermission(command, permission);
}

export function transferEnabled(config, authorAssociation) {
const transferConfig = config.commands.transfer;

if (!transferConfig.enabled) {
return notEnabled("transfer");
}

return enabled;
return permissionEnabled("transfer", transferConfig, authorAssociation);
}

export function labelEnabled(config, labels) {
export function labelEnabled(config, labels, authorAssociation) {
const labelConfig = config.commands.label;

if (!labelConfig.enabled) {
return notEnabled("label");
}

const permissionResult = permissionEnabled(
"label",
labelConfig,
authorAssociation,
);
if (!permissionResult.enabled) {
return permissionResult;
}

const allowedLabels = trimLabels(labelConfig.allowedLabels);
if (
// if length is = 0 then all labels are allowed
Expand All @@ -45,28 +88,41 @@ export function labelEnabled(config, labels) {
return enabled;
}

export function closeEnabled(config) {
if (!config.commands.close.enabled) {
export function closeEnabled(config, authorAssociation) {
const closeConfig = config.commands.close;

if (!closeConfig.enabled) {
return notEnabled("close");
}

return enabled;
return permissionEnabled("close", closeConfig, authorAssociation);
}

export function reopenEnabled(config) {
if (!config.commands.reopen.enabled) {
export function reopenEnabled(config, authorAssociation) {
const reopenConfig = config.commands.reopen;

if (!reopenConfig.enabled) {
return notEnabled("reopen");
}

return enabled;
return permissionEnabled("reopen", reopenConfig, authorAssociation);
}

export function removeLabelEnabled(config, labels) {
export function removeLabelEnabled(config, labels, authorAssociation) {
const labelConfig = config.commands.removeLabel;
if (!labelConfig.enabled) {
return notEnabled("remove-label");
}

const permissionResult = permissionEnabled(
"remove-label",
labelConfig,
authorAssociation,
);
if (!permissionResult.enabled) {
return permissionResult;
}

const allowedLabels = trimLabels(labelConfig.allowedLabels);
if (
// if length is = 0 then all labels are allowed
Expand All @@ -84,10 +140,12 @@ export function removeLabelEnabled(config, labels) {
return enabled;
}

export function reviewerEnabled(config) {
if (!config.commands.reviewer.enabled) {
export function reviewerEnabled(config, authorAssociation) {
const reviewerConfig = config.commands.reviewer;

if (!reviewerConfig.enabled) {
return notEnabled("reviewer");
}

return enabled;
return permissionEnabled("reviewer", reviewerConfig, authorAssociation);
}
Loading