* feat: Add GitHub Actions workflows for security audits, CodeQL analysis, contributor updates, performance benchmarks, integration tests, fuzz testing, and reusable Rust build jobs - Implemented `sec-audit.yml` for Rust package security audits using `rustsec/audit-check` and `cargo-deny-action`. - Created `sec-codeql.yml` for CodeQL analysis scheduled twice daily. - Added `sync-contributors.yml` to update the NOTICE file with new contributors automatically. - Introduced `test-benchmarks.yml` for performance benchmarks using Criterion. - Established `test-e2e.yml` for running integration and end-to-end tests. - Developed `test-fuzz.yml` for fuzz testing with configurable runtime. - Created `test-rust-build.yml` as a reusable job for executing Rust commands with customizable parameters. - Documented main branch delivery flows in `main-branch-flow.md` for clarity on CI/CD processes. * ci(workflows): update workflow scripts and rename for clarity; remove obsolete lint feedback script * chore(ci): externalize workflow scripts and relocate main flow doc
94 lines
2.5 KiB
JavaScript
94 lines
2.5 KiB
JavaScript
// Extracted from pr-auto-response.yml step: Handle label-driven responses
|
|
|
|
module.exports = async ({ github, context, core }) => {
|
|
const label = context.payload.label?.name;
|
|
if (!label) return;
|
|
|
|
const issue = context.payload.issue;
|
|
const pullRequest = context.payload.pull_request;
|
|
const target = issue ?? pullRequest;
|
|
if (!target) return;
|
|
|
|
const isIssue = Boolean(issue);
|
|
const issueNumber = target.number;
|
|
const owner = context.repo.owner;
|
|
const repo = context.repo.repo;
|
|
|
|
const rules = [
|
|
{
|
|
label: "r:support",
|
|
close: true,
|
|
closeIssuesOnly: true,
|
|
closeReason: "not_planned",
|
|
message:
|
|
"This looks like a usage/support request. Please use README + docs first, then open a focused bug with repro details if behavior is incorrect.",
|
|
},
|
|
{
|
|
label: "r:needs-repro",
|
|
close: false,
|
|
message:
|
|
"Thanks for the report. Please add deterministic repro steps, exact environment, and redacted logs so maintainers can triage quickly.",
|
|
},
|
|
{
|
|
label: "invalid",
|
|
close: true,
|
|
closeIssuesOnly: true,
|
|
closeReason: "not_planned",
|
|
message:
|
|
"Closing as invalid based on current information. If this is still relevant, open a new issue with updated evidence and reproducible steps.",
|
|
},
|
|
{
|
|
label: "duplicate",
|
|
close: true,
|
|
closeIssuesOnly: true,
|
|
closeReason: "not_planned",
|
|
message:
|
|
"Closing as duplicate. Please continue discussion in the canonical linked issue/PR.",
|
|
},
|
|
];
|
|
|
|
const rule = rules.find((entry) => entry.label === label);
|
|
if (!rule) return;
|
|
|
|
const marker = `<!-- auto-response:${rule.label} -->`;
|
|
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
per_page: 100,
|
|
});
|
|
|
|
const alreadyCommented = comments.some((comment) =>
|
|
(comment.body || "").includes(marker)
|
|
);
|
|
|
|
if (!alreadyCommented) {
|
|
await github.rest.issues.createComment({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
body: `${rule.message}\n\n${marker}`,
|
|
});
|
|
}
|
|
|
|
if (!rule.close) return;
|
|
if (rule.closeIssuesOnly && !isIssue) return;
|
|
if (target.state === "closed") return;
|
|
|
|
if (isIssue) {
|
|
await github.rest.issues.update({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
state: "closed",
|
|
state_reason: rule.closeReason || "not_planned",
|
|
});
|
|
} else {
|
|
await github.rest.issues.update({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
state: "closed",
|
|
});
|
|
}
|
|
};
|