mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
100 lines
3.8 KiB
YAML
100 lines
3.8 KiB
YAML
name: Maintainer Command Reactions
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created, edited]
|
|
|
|
permissions: {}
|
|
|
|
concurrency:
|
|
group: maintainer-command-reactions-${{ github.event.comment.id }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
react:
|
|
if: ${{ !endsWith(github.actor, '[bot]') }}
|
|
runs-on: ubuntu-24.04
|
|
permissions:
|
|
issues: write
|
|
pull-requests: write
|
|
env:
|
|
MAINTAINER_COMMAND_REACTIONS: ${{ vars.MAINTAINER_COMMAND_REACTIONS || '/autoclose,/clawsweeper autoclose,/clawsweeper automerge,/merge,/land,/landpr' }}
|
|
steps:
|
|
- name: React to maintainer slash command
|
|
uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const comment = context.payload.comment;
|
|
const issue = context.payload.issue;
|
|
|
|
const commands = (process.env.MAINTAINER_COMMAND_REACTIONS || "")
|
|
.split(",")
|
|
.map((command) => command.trim())
|
|
.filter(Boolean);
|
|
const commandLine = String(comment.body || "")
|
|
.split(/\r?\n/)
|
|
.map((line) => line.trim())
|
|
.find((line) => commands.some((command) => line === command || line.startsWith(`${command} `)));
|
|
|
|
if (!commandLine) {
|
|
core.info(`Skipping comment ${comment.id}; no tracked maintainer command found.`);
|
|
return;
|
|
}
|
|
|
|
const isAutocloseCommand =
|
|
commandLine === "/autoclose" ||
|
|
commandLine.startsWith("/autoclose ") ||
|
|
commandLine === "/clawsweeper autoclose" ||
|
|
commandLine.startsWith("/clawsweeper autoclose ");
|
|
if (!issue.pull_request && !isAutocloseCommand) {
|
|
core.info("Skipping non-autoclose command reaction because the comment is not on a pull request.");
|
|
return;
|
|
}
|
|
|
|
const maintainerPermissions = new Set(["admin", "maintain", "write"]);
|
|
let permission = "none";
|
|
try {
|
|
const result = await github.rest.repos.getCollaboratorPermissionLevel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
username: comment.user.login,
|
|
});
|
|
permission = String(result.data.permission || "none").toLowerCase();
|
|
} catch (error) {
|
|
if (error.status !== 404) {
|
|
core.info(`Could not resolve repository permission for ${comment.user.login}: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
if (!maintainerPermissions.has(permission)) {
|
|
core.info(
|
|
`Skipping non-maintainer command reaction for ${comment.user.login}; repository permission is ${permission}.`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
async function react(content) {
|
|
try {
|
|
await github.rest.reactions.createForIssueComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: comment.id,
|
|
content,
|
|
});
|
|
core.info(`Added ${content} reaction to comment ${comment.id}.`);
|
|
} catch (error) {
|
|
if (error.status === 422 && /already exists/i.test(String(error.message))) {
|
|
core.info(`${content} reaction already exists on comment ${comment.id}.`);
|
|
return;
|
|
}
|
|
if (error.status === 403 && /resource not accessible by integration/i.test(String(error.message))) {
|
|
core.warning(`${content} reaction could not be added with this token: ${error.message}`);
|
|
return;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
await react("eyes");
|
|
core.info(`Maintainer command observed on ${issue.pull_request ? "PR" : "issue"} #${issue.number}: ${commandLine}`);
|