aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-08-10 21:53:44 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-08-10 21:53:44 +0300
commit66835dba71ceefeaed3f608f1cc34748284e5023 (patch)
tree9d322938a299a86e6fd5a67da05507f4010f6632
parent1ac44afcc091ef70890ebcb5ff409ae6dc0eef53 (diff)
ci: remove automatic issue gate
-rw-r--r--.github/workflows/issue-gate.yml256
1 files changed, 0 insertions, 256 deletions
diff --git a/.github/workflows/issue-gate.yml b/.github/workflows/issue-gate.yml
deleted file mode 100644
index b85c437f..00000000
--- a/.github/workflows/issue-gate.yml
+++ /dev/null
@@ -1,256 +0,0 @@
-name: Issue Gate
-
-on:
- issues:
- types: [opened]
-
-permissions:
- issues: write
-
-jobs:
- check-template:
- if: ${{ !github.event.issue.pull_request }}
- runs-on: ubuntu-latest
-
- steps:
- - name: Close non-template issues
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
- with:
- github-token: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- script: |
- const issue = context.payload.issue;
- const author = issue.user.login;
- const sender = context.payload.sender?.login ?? author;
- const bugConfirmationPattern = /^\s*-\s*\[[xX]\]\s*I confirm this is a reproducible bug, not a feature request, idea, question, contribution proposal, or direction check\.\s*$/m;
- const reproductionConfirmationPattern = /^\s*-\s*\[[xX]\]\s*I reproduced this bug on the version and environment reported below using the exact steps provided\.\s*$/m;
- const requiredSections = [
- '### Is this a reproducible bug?',
- '### Current behavior',
- '### Expected behavior',
- '### Reproduction',
- '### Impact',
- '### Environment',
- ];
- const maxBodyLength = 8000;
- const maxExtraHeadings = 1;
-
- function escapeRegExp(value) {
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- }
-
- function extractSection(body, heading) {
- const pattern = new RegExp(`^${escapeRegExp(heading)}\\s*$`, 'm');
- const match = pattern.exec(body);
- if (!match) {
- return null;
- }
-
- const sectionStart = match.index + match[0].length;
- const rest = body.slice(sectionStart);
- const headingIndex = requiredSections.indexOf(heading);
- const nextTemplateHeading = requiredSections
- .slice(headingIndex + 1)
- .map((section) => {
- const nextPattern = new RegExp(`^${escapeRegExp(section)}\\s*$`, 'm');
- const nextMatch = nextPattern.exec(rest);
- return nextMatch ? nextMatch.index : -1;
- })
- .filter((index) => index !== -1)
- .sort((left, right) => left - right)[0];
- return (nextTemplateHeading === undefined ? rest : rest.slice(0, nextTemplateHeading)).trim();
- }
-
- function hasContent(section) {
- return typeof section === 'string' && section.trim().length > 0;
- }
-
- function hasEnvironmentContent(section) {
- if (!hasContent(section)) {
- return false;
- }
-
- return section.split(/\r?\n/).some((line) => {
- const value = line.trim();
- return value.length > 0 && !/^(?:-\s*)?[^:]+:\s*$/.test(value);
- });
- }
-
- function bodyWithoutFencedCodeBlocks(value) {
- let inFence = false;
- return value
- .split(/\r?\n/)
- .filter((line) => {
- if (/^\s{0,3}(```|~~~)/.test(line)) {
- inFence = !inFence;
- return false;
- }
- return !inFence;
- })
- .join('\n');
- }
-
- async function getPermission(username) {
- try {
- const { data: permissionLevel } = await github.rest.repos.getCollaboratorPermissionLevel({
- owner: context.repo.owner,
- repo: context.repo.repo,
- username,
- });
- return permissionLevel.permission;
- } catch {
- return null;
- }
- }
-
- const maintainerPermissions = ['admin', 'maintain', 'write'];
- const authorPermission = await getPermission(author);
- if (maintainerPermissions.includes(authorPermission)) {
- console.log(`${author} is a collaborator with ${authorPermission} access; leaving issue open`);
- return;
- }
-
- const senderPermission = sender === author ? authorPermission : await getPermission(sender);
- if (maintainerPermissions.includes(senderPermission)) {
- console.log(`${sender} opened this issue with ${senderPermission} access; leaving issue open`);
- return;
- }
-
- const body = issue.body || '';
- const translationConfirmationPattern = /^\s*-\s*\[[xX]\]\s*I confirm this is a translation issue in the herdr docs, not a bug report, feature request, or question\.\s*$/m;
- const translationSections = ['### Page', '### Language', '### What is wrong'];
- if (
- translationConfirmationPattern.test(body) &&
- translationSections.every((section) => body.includes(section))
- ) {
- console.log(`#${issue.number} matches the translation issue template; leaving issue open`);
- return;
- }
-
- const hasBugConfirmation = bugConfirmationPattern.test(body) && reproductionConfirmationPattern.test(body);
- const allowedHeadings = new Set(requiredSections);
- const headingBody = bodyWithoutFencedCodeBlocks(body);
- const headings = [...headingBody.matchAll(/^\s{0,3}#{1,6}\s+(.+?)\s*$/gm)].map((match) => match[0].trim());
- const headingCounts = new Map(
- requiredSections.map((section) => [
- section,
- headings.filter((heading) => heading === section).length,
- ]),
- );
- const hasEveryRequiredHeading = requiredSections.every(
- (section) => headingCounts.get(section) > 0,
- );
- const hasBugTemplate = requiredSections.every(
- (section) => headingCounts.get(section) === 1,
- );
- const repeatedTemplateHeadings = requiredSections.filter(
- (section) => headingCounts.get(section) > 1,
- );
- const extraHeadings = headings.filter((heading) => !allowedHeadings.has(heading));
- const structuralViolations = [];
- if (repeatedTemplateHeadings.length > 0) {
- structuralViolations.push('one or more required template headings are repeated');
- }
- if (extraHeadings.length > maxExtraHeadings) {
- structuralViolations.push(`${extraHeadings.length} extra markdown headings were added`);
- }
- if (body.length > maxBodyLength) {
- structuralViolations.push(`the report is ${body.length} characters; the limit is ${maxBodyLength}`);
- }
-
- const currentBehavior = extractSection(body, '### Current behavior');
- const expectedBehavior = extractSection(body, '### Expected behavior');
- const reproduction = extractSection(body, '### Reproduction');
- const impact = extractSection(body, '### Impact');
- const environment = extractSection(body, '### Environment');
- const hasRequiredContent = [
- currentBehavior,
- expectedBehavior,
- reproduction,
- impact,
- ].every(hasContent);
- const hasEnvironment = hasEnvironmentContent(environment);
-
- if (hasBugConfirmation && hasEveryRequiredHeading && structuralViolations.length > 0) {
- const message = [
- `hi @${author}, thanks for opening this.`,
- '',
- 'this report exceeds the bug report structure limits:',
- ...structuralViolations.map((violation) => `- ${violation}`),
- '',
- 'please keep the report within the required template, under 8,000 characters, and focused on observed behavior, exact reproduction, impact, and environment.',
- '',
- 'closing this so the issue tracker stays limited to concise, actionable bug reports.',
- ].join('\n');
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issue.number,
- body: message,
- });
-
- await github.rest.issues.update({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issue.number,
- state: 'closed',
- state_reason: 'not_planned',
- });
- return;
- }
-
- if (hasBugConfirmation && hasBugTemplate && hasRequiredContent && hasEnvironment) {
- console.log(`#${issue.number} matches the bug report template`);
- return;
- }
-
- if (hasBugConfirmation && hasBugTemplate && hasRequiredContent && !hasEnvironment) {
- const message = [
- `hi @${author}, thanks for opening this.`,
- '',
- 'this bug report has no filled environment details. please edit the environment section with the Herdr version, update channel, operating system, and terminal.',
- '',
- 'shell and relevant config are optional, but they help when they affect the bug.',
- ].join('\n');
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issue.number,
- body: message,
- });
-
- console.log(`#${issue.number} has no environment details; leaving issue open for correction`);
- return;
- }
-
- const message = [
- `hi @${author}, thanks for opening this.`,
- '',
- 'this issue does not appear to use the full bug report template. herdr issues are only for reproducible bugs and maintainer-created or maintainer-converted work items.',
- '',
- 'bug reports must include the reproducible-bug confirmation, current behavior, expected behavior, reproduction, impact, and environment fields with herdr version, update channel, operating system, and terminal.',
- '',
- 'feature requests, ideas, questions, contribution proposals, and direction checks belong in discussions:',
- `https://github.com/${context.repo.owner}/${context.repo.repo}/discussions`,
- '',
- 'please read the contributing guidelines before opening issues or prs:',
- `https://github.com/${context.repo.owner}/${context.repo.repo}/blob/${context.payload.repository.default_branch}/CONTRIBUTING.md`,
- '',
- 'closing this so the issue tracker stays limited to actionable bug reports.',
- ].join('\n');
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issue.number,
- body: message,
- });
-
- await github.rest.issues.update({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issue.number,
- state: 'closed',
- state_reason: 'not_planned',
- });