88 lines
4.4 KiB
YAML
88 lines
4.4 KiB
YAML
name: Auto-triage scan output
|
|
|
|
# career-ops runs locally. Some users point their own scheduled automation at
|
|
# this repo by mistake and file their personal scan results / run reports as
|
|
# issues here. Those are created via the API / `gh issue create`, which bypasses
|
|
# the issue templates and `blank_issues_enabled: false` entirely — so only a
|
|
# workflow can catch them. This one explains, labels, and closes them: it
|
|
# protects users' personal job-search data and keeps the public tracker clean.
|
|
#
|
|
# Deliberately CONSERVATIVE — it acts only when BOTH are true:
|
|
# (a) the issue did NOT come through a template (no Code of Conduct checkbox), and
|
|
# (b) it carries an unmistakable automated-report marker (boilerplate the
|
|
# scheduled-scan reports ship with — not merely the word "scan", which
|
|
# legitimate scanner-provider features use).
|
|
# It never locks the issue, so a real report can always be reopened.
|
|
|
|
on:
|
|
issues:
|
|
types: [opened, reopened]
|
|
|
|
permissions:
|
|
issues: write
|
|
|
|
jobs:
|
|
triage:
|
|
runs-on: ubuntu-latest
|
|
# Never auto-close issues opened by the owner or org members.
|
|
if: ${{ github.event.issue.author_association != 'OWNER' && github.event.issue.author_association != 'MEMBER' }}
|
|
steps:
|
|
- uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const issue = context.payload.issue;
|
|
const body = issue.body || '';
|
|
const hay = `${issue.title || ''}\n${body}`;
|
|
|
|
// Gate A — template-created issues carry the CoC checkbox. Real
|
|
// contributions always come through a template, so never touch them.
|
|
if (/Code of Conduct/i.test(body)) return;
|
|
|
|
// Gate B — must carry an unmistakable automated-report marker.
|
|
const markers = [
|
|
/Generated by career-ops automated routine/i,
|
|
/Scheduled Portal Scan/i,
|
|
/Scheduled Run Report/i,
|
|
// Original shipped marker (unchanged): bare "Automated Scan"[ Result| Failed].
|
|
/Automated [Ss]can( (Result|Failed))?/i,
|
|
// Also catch the machine report header "## Automated <Weekly|Daily|Nightly|…> Scan"
|
|
// (one interposed adjective). Header-anchored (`^#{1,6}\s+…`, multiline) so human issue
|
|
// titles or prose that merely mention an "automated … scan" are NOT auto-closed — only
|
|
// the generated markdown section header matches.
|
|
/^#{1,6}\s+Automated (?:\w+ )?[Ss]can\b/im,
|
|
// Emoji-led scan-digest title, e.g. "🔍 Scan results — <date> — N new leads" (#1791).
|
|
/^\s*(?:🔍|🔎|📊|📋|🧭|📡|✨)\s*Scan\b/iu,
|
|
/Auto-scan Results/i,
|
|
/Daily AI Job Scan/i,
|
|
/Morning (Briefing|Automation Run)/i,
|
|
/Nightly Graphify/i,
|
|
/This is an automated scan result/i,
|
|
/onboarding (required|not complete)/i,
|
|
/Gmail MCP token/i,
|
|
/new offers added to pipeline/i,
|
|
];
|
|
if (!markers.some((re) => re.test(hay))) return;
|
|
|
|
const { owner, repo } = context.repo;
|
|
const issue_number = issue.number;
|
|
|
|
await github.rest.issues.createComment({
|
|
owner, repo, issue_number,
|
|
body: [
|
|
`Hey @${issue.user.login} — this looks like automated output from your own career-ops setup landing on the upstream repo. 👋`,
|
|
``,
|
|
`career-ops runs **entirely locally**: your pipeline, scans, and reports live on your own machine (\`data/\`, \`reports/\`) — they never need to be filed here, and posting them upstream puts personal job-search data on a public tracker. Closing to keep your data private and the tracker tidy.`,
|
|
``,
|
|
`If you have a scheduled run that opens issues, point it at your **own fork** or a private repo — not \`${owner}/${repo}\`. Real bugs are always welcome via the bug-report template. Thanks for building with career-ops! 🚀`,
|
|
].join('\n'),
|
|
});
|
|
|
|
try {
|
|
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['scan-output'] });
|
|
} catch (e) {
|
|
core.info(`label add skipped: ${e.message}`);
|
|
}
|
|
|
|
await github.rest.issues.update({ owner, repo, issue_number, state: 'closed', state_reason: 'not_planned' });
|
|
core.info(`Closed #${issue_number} as scan-output.`);
|