mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2026-03-26 18:22:08 -04:00
114 lines
3.7 KiB
YAML
114 lines
3.7 KiB
YAML
name: AdventureLog Bot
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, edited, synchronize]
|
|
|
|
jobs:
|
|
enforce-ready:
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
pull-requests: write
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Validate linked issue
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const pr = context.payload.pull_request;
|
|
const repoFullName = `${context.repo.owner}/${context.repo.repo}`;
|
|
|
|
async function safeCreateComment(body) {
|
|
try {
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: pr.number,
|
|
body
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
if (error.status === 403) {
|
|
core.warning(`Unable to comment on PR #${pr.number}: ${error.message}`);
|
|
return false;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function safeClosePr() {
|
|
try {
|
|
await github.rest.pulls.update({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: pr.number,
|
|
state: "closed"
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
if (error.status === 403) {
|
|
core.warning(`Unable to close PR #${pr.number}: ${error.message}`);
|
|
return false;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function safeCommentAndClose(message) {
|
|
await safeCreateComment(message);
|
|
await safeClosePr();
|
|
}
|
|
|
|
// Ignore specific user
|
|
if (context.actor === "seanmorley15") {
|
|
console.log("Skipping maintainer PR");
|
|
return;
|
|
}
|
|
|
|
// Ignore PRs created before enforcement date
|
|
const cutoff = new Date("2026-03-16T00:00:00Z");
|
|
const created = new Date(pr.created_at);
|
|
|
|
if (created < cutoff) {
|
|
console.log("Skipping PR created before enforcement date");
|
|
return;
|
|
}
|
|
|
|
const body = pr.body || "";
|
|
const match = body.match(/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)\b/i);
|
|
|
|
if (!match) {
|
|
await safeCommentAndClose("🤖 **AdventureLog Bot**\n\n🚫 This PR was automatically closed because it does not reference an issue.\n\nPlease link an issue using `Closes #issue-number`.");
|
|
|
|
return;
|
|
}
|
|
|
|
const issueNumber = Number(match[1]);
|
|
|
|
let issue;
|
|
|
|
try {
|
|
({ data: issue } = await github.rest.issues.get({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: issueNumber
|
|
}));
|
|
} catch (error) {
|
|
if (error.status === 404) {
|
|
await safeCommentAndClose(`🤖 **AdventureLog Bot**\n\n🚫 This PR was automatically closed because the referenced issue #${issueNumber} was not found.\n\nPlease link a valid issue in this repository using \`Closes #issue-number\`.`);
|
|
|
|
return;
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
|
|
const labels = issue.labels.map(l => l.name);
|
|
|
|
if (!labels.includes("ready") && !labels.includes("in progress")) {
|
|
await safeCommentAndClose("🤖 **AdventureLog Bot**\n\n🚫 This PR was automatically closed.\n\nPull requests may only be opened for issues labeled **ready**.");
|
|
|
|
}
|