Skip to content

Subtle Discrepancies in PBR Implementation #2

Subtle Discrepancies in PBR Implementation

Subtle Discrepancies in PBR Implementation #2

Workflow file for this run

name: Bounty detector
on:
issues:
types: [labeled]
permissions:
issues: write
pull-requests: read
jobs:
notify:
runs-on: ubuntu-latest
if: startsWith(github.event.label.name, 'diff:')
steps:
- name: Comment bounty info
uses: actions/github-script@v7
env:
FORUM_URL: "https://hub.jmonkeyengine.org/t/proposal-experimental-bounty-program-in-jme/49385"
RESERVE_HOURS: "48"
with:
script: |
const issue = context.payload.issue;
const label = context.payload.label?.name ?? "";
const actor = context.actor; // person who applied the label
const issueOwner = issue.user?.login; // original issue author
if (!issueOwner) return;
const forumUrl = process.env.FORUM_URL || "TBD";
const reserveHours = Number(process.env.RESERVE_HOURS || "48");
// "previous contributor" = has at least one merged PR authored in this repo
const repoFull = `${context.repo.owner}/${context.repo.repo}`;
const q = `repo:${repoFull} type:pr author:${issueOwner} is:merged`;
let isPreviousContributor = false;
try {
const search = await github.rest.search.issuesAndPullRequests({ q, per_page: 1 });
isPreviousContributor = (search.data.total_count ?? 0) > 0;
} catch (e) {
isPreviousContributor = false;
}
// Reserve only if previous contributor AND labeler is NOT the issue owner
const shouldReserve = isPreviousContributor && (actor !== issueOwner);
const lines = [];
lines.push(`# 💰 This issue has a bounty`);
lines.push(`Resolve it to receive a reward.`);
lines.push(`For details (amount, rules, eligibility), see: ${forumUrl}`);
lines.push("");
lines.push(`If you want to start working on this, **comment on this issue** with your intent.`);
lines.push(`If accepted by a maintainer, the issue will be **assigned** to you.`);
lines.push("");
if (shouldReserve) {
const reservedUntil = new Date(Date.now() + reserveHours * 60 * 60 * 1000);
const reservedUntilIso = reservedUntil.toISOString();
lines.push(
`<sub>` +
`⏳ **Temporary reservation for @${issueOwner}:** since they are a previous contributor, they have priority for this bounty ` +
`for <relative-time datetime="${reservedUntilIso}"></relative-time> ` +
`(until **${reservedUntilIso}**). After that, it is **open to everyone**.` +
`</sub>`
);
lines.push("");
}
// Avoid duplicate comments for the same label
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
per_page: 100,
});
const already = comments.data.some(c =>
c.user?.login === "github-actions[bot]" &&
typeof c.body === "string" &&
c.body.includes("**This issue has a bounty.**") &&
c.body.includes(`see: ${forumUrl}`)
);
if (already) return;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: lines.join("\n"),
});