Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/1.bug_report_v3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@ body:
- 'Not sure'
- 'area: core'
- 'area: docs'
- 'area: graphql'
- 'area: live-preview'
- 'area: templates'
- 'area: ui'
- 'db: d1-sqlite'
- 'db: mongodb'
- 'db: postgres'
- 'db: sqlite'
- 'db: vercel-postgres'
- 'email-nodemailer'
- 'plugin: cloud-storage'
- 'plugin: ecommerce'
- 'plugin: form-builder'
- 'plugin: import-export'
- 'plugin: mcp'
- 'plugin: multi-tenant'
- 'plugin: nested-docs'
- 'plugin: redirects'
Expand Down
8 changes: 8 additions & 0 deletions .github/actions/triage/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ inputs:
actions-to-perform:
description: 'Comma-separated list of actions to perform on the issue. Example: "tag,comment,close"'
default: 'tag,comment,close'
area-label-section:
description: 'Regex to extract area labels from issue body. First capture group should contain comma-separated values.'
default: ''
area-label-skip:
description: 'Comma-separated values to skip (not apply as labels). Example: "Not sure"'
default: ''

runs:
using: 'composite'
Expand All @@ -38,3 +44,5 @@ runs:
'INPUT_REPRODUCTION_ISSUE_LABELS': ${{inputs.reproduction-issue-labels}}
'INPUT_REPRODUCTION_LINK_SECTION': ${{inputs.reproduction-link-section}}
'INPUT_ACTIONS_TO_PERFORM': ${{inputs.actions-to-perform}}
'INPUT_AREA_LABEL_SECTION': ${{inputs.area-label-section}}
'INPUT_AREA_LABEL_SKIP': ${{inputs.area-label-skip}}
64 changes: 62 additions & 2 deletions .github/actions/triage/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33854,6 +33854,13 @@ var config = {
label: (0,core.getInput)('reproduction_invalid_label') || 'invalid-reproduction',
linkSection: (0,core.getInput)('reproduction_link_section') || '### Link to reproduction(.*)### To reproduce',
},
areaLabels: {
section: (0,core.getInput)('area_label_section') || '',
skip: ((0,core.getInput)('area_label_skip') || '')
.split(',')
.map(function (s) { return s.trim(); })
.filter(Boolean),
},
actionsToPerform: ((0,core.getInput)('actions_to_perform') || validActionsToPerform.join(','))
.split(',')
.map(function (a) {
Expand Down Expand Up @@ -33925,7 +33932,7 @@ function checkValidReproduction() {
case 4:
// Adjust labels
_f.sent();
if (!!config.actionsToPerform.includes('tag')) return [3 /*break*/, 6];
if (!config.actionsToPerform.includes('tag')) return [3 /*break*/, 6];
(0,core.info)("Added label: ".concat(config.invalidLink.label));
return [4 /*yield*/, client.issues.addLabels(__assign(__assign({}, common), { labels: [config.invalidLink.label] }))];
case 5:
Expand Down Expand Up @@ -34042,6 +34049,56 @@ function getCommentBody(pathOrComment) {
});
});
}
/**
* Apply area labels from the issue body dropdown selection
*/
function checkAreaLabels() {
var _a, _b;
return __awaiter(this, void 0, Promise, function () {
var _c, issue, action, sectionRegex, match, labels, client, common, err_1;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
if (!config.areaLabels.section) {
(0,core.info)('Area labels - skipped, no section regex configured');
return [2 /*return*/];
}
_c = github.context.payload, issue = _c.issue, action = _c.action;
if (action !== 'opened' || !(issue === null || issue === void 0 ? void 0 : issue.body))
return [2 /*return*/];
sectionRegex = new RegExp(config.areaLabels.section, 'is');
match = (_b = (_a = issue.body.match(sectionRegex)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.trim();
if (!match) {
(0,core.info)('Area labels - no matching section found in issue body');
return [2 /*return*/];
}
labels = match
.split(',')
.map(function (l) { return l.trim(); })
.filter(function (l) { return l && !config.areaLabels.skip.includes(l); });
if (labels.length === 0) {
(0,core.info)('Area labels - no labels to apply after filtering');
return [2 /*return*/];
}
client = (0,github.getOctokit)(config.token).rest;
common = __assign(__assign({}, github.context.repo), { issue_number: issue.number });
_d.label = 1;
case 1:
_d.trys.push([1, 3, , 4]);
return [4 /*yield*/, client.issues.addLabels(__assign(__assign({}, common), { labels: labels }))];
case 2:
_d.sent();
(0,core.info)("Applied area labels: ".concat(labels.join(', ')));
return [3 /*break*/, 4];
case 3:
err_1 = _d.sent();
(0,core.error)("Failed to apply area labels: ".concat(err_1 instanceof Error ? err_1.message : err_1));
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
}
function run() {
return __awaiter(this, void 0, void 0, function () {
var token, workspace, safeConfig;
Expand All @@ -34051,8 +34108,11 @@ function run() {
token = config.token, workspace = config.workspace, safeConfig = __rest(config, ["token", "workspace"]);
(0,core.info)('Configuration:');
(0,core.info)(JSON.stringify(safeConfig, null, 2));
return [4 /*yield*/, checkValidReproduction()];
return [4 /*yield*/, checkAreaLabels()];
case 1:
_a.sent();
return [4 /*yield*/, checkValidReproduction()];
case 2:
_a.sent();
return [2 /*return*/];
}
Expand Down
57 changes: 57 additions & 0 deletions .github/actions/triage/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ interface Config {
label: string
linkSection: string
}
areaLabels: {
section: string
skip: string[]
}
actionsToPerform: ActionsToPerform[]
token: string
workspace: string
Expand All @@ -36,6 +40,13 @@ const config: Config = {
linkSection:
getInput('reproduction_link_section') || '### Link to reproduction(.*)### To reproduce',
},
areaLabels: {
section: getInput('area_label_section') || '',
skip: (getInput('area_label_skip') || '')
.split(',')
.map((s) => s.trim())
.filter(Boolean),
},
actionsToPerform: (getInput('actions_to_perform') || validActionsToPerform.join(','))
.split(',')
.map((a) => {
Expand Down Expand Up @@ -204,11 +215,57 @@ async function getCommentBody(pathOrComment: string) {
}
}

/**
* Apply area labels from the issue body dropdown selection
*/
async function checkAreaLabels(): Promise<void> {
if (!config.areaLabels.section) {
info('Area labels - skipped, no section regex configured')
return
}

const { issue, action } = context.payload as {
issue: { number: number; body: string } | undefined
action: string
}

if (action !== 'opened' || !issue?.body) return

const sectionRegex = new RegExp(config.areaLabels.section, 'is')
const match = issue.body.match(sectionRegex)?.[1]?.trim()

if (!match) {
info('Area labels - no matching section found in issue body')
return
}

const labels = match
.split(',')
.map((l) => l.trim())
.filter((l) => l && !config.areaLabels.skip.includes(l))

if (labels.length === 0) {
info('Area labels - no labels to apply after filtering')
return
}

const { rest: client } = getOctokit(config.token)
const common = { ...context.repo, issue_number: issue.number }

try {
await client.issues.addLabels({ ...common, labels })
info(`Applied area labels: ${labels.join(', ')}`)
} catch (err) {
error(`Failed to apply area labels: ${err instanceof Error ? err.message : err}`)
}
}

async function run() {
const { token, workspace, ...safeConfig } = config
info('Configuration:')
info(JSON.stringify(safeConfig, null, 2))

await checkAreaLabels()
await checkValidReproduction()
}

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,5 @@ jobs:
reproduction-link-section: '### Link to the code that reproduces this issue(.*)### Reproduction Steps'
reproduction-issue-labels: 'validate-reproduction'
actions-to-perform: 'tag,comment'
area-label-section: '### Which area\(s\) are affected\?(.*)### Environment Info'
area-label-skip: 'Not sure'