ci: infer component labels for issues filed without the form (#6471)

This commit is contained in:
Kartik
2026-07-21 21:39:00 +05:30
committed by GitHub
parent 70ab76a053
commit dd5f7e39a8
9 changed files with 301 additions and 33 deletions
+41
View File
@@ -16,11 +16,52 @@ jobs:
- uses: stefanbuck/github-issue-parser@v3
id: issue-parser
continue-on-error: true
with:
template-path: .github/ISSUE_TEMPLATE/bug_report.yml
- uses: redhat-plumbers-in-action/advanced-issue-labeler@v3
continue-on-error: true
with:
issue-form: ${{ steps.issue-parser.outputs.jsonString }}
token: ${{ secrets.GITHUB_TOKEN }}
config-path: .github/advanced-issue-labeler.yml
- name: Infer component from text when the form was not used
uses: actions/github-script@v7
with:
script: |
const {
componentLabels,
inferComponentLabels,
loadKeywords,
} = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/infer-component-labels.js`);
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const keywords = loadKeywords(`${process.env.GITHUB_WORKSPACE}/.github/component-keywords.json`);
const known = componentLabels(keywords);
const existing = issue.labels.map((label) => label.name || label);
if (existing.some((name) => known.includes(name))) {
core.info(`Component label already present: ${existing.join(', ')}`);
return;
}
const labels = inferComponentLabels(`${issue.title}\n\n${issue.body || ''}`, keywords);
if (labels.length === 0) {
core.info('No component could be inferred from the issue text');
return;
}
core.info(`Inferred: ${labels.join(', ')}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels,
});
+24 -17
View File
@@ -4,6 +4,10 @@ on:
pull_request_target:
types: [opened, synchronize, reopened, edited]
concurrency:
group: pr-labeler-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
@@ -22,31 +26,34 @@ jobs:
with:
script: |
const allowed = new Set([
'sdk-python', 'sdk-typescript', 'vector-store', 'openclaw',
'sdk-python', 'sdk-typescript', 'vector-store', 'plugin',
'rest-api', 'openmemory', 'documentation', 'ci', 'cli', 'integrations',
]);
const body = context.payload.pull_request.body || '';
const matches = [...body.matchAll(/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*:?\s*(?:#|https:\/\/github\.com\/mem0ai\/mem0\/issues\/)(\d+)/gi)];
const numbers = [...new Set(matches.map((m) => Number(m[1])))];
const umbrella = { plugin: 'integrations' };
const { repository } = await github.graphql(
`query ($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
closingIssuesReferences(first: 20) {
nodes { labels(first: 50) { nodes { name } } }
}
}
}
}`,
{ owner: context.repo.owner, repo: context.repo.repo, number: context.issue.number },
);
const labels = new Set();
for (const issue_number of numbers) {
let issue;
try {
({ data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
}));
} catch {
continue;
}
if (issue.pull_request) continue;
for (const label of issue.labels) {
for (const issue of repository.pullRequest.closingIssuesReferences.nodes) {
for (const label of issue.labels.nodes) {
if (allowed.has(label.name)) labels.add(label.name);
}
}
for (const label of [...labels]) {
if (umbrella[label]) labels.add(umbrella[label]);
}
if (labels.size > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,