summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/close-issues.yml101
1 files changed, 101 insertions, 0 deletions
diff --git a/.github/workflows/close-issues.yml b/.github/workflows/close-issues.yml
new file mode 100644
index 00000000..55f4e126
--- /dev/null
+++ b/.github/workflows/close-issues.yml
@@ -0,0 +1,101 @@
+name: Close Unauthorized Issues
+
+on:
+ workflow_dispatch:
+ issues:
+ types: [opened]
+
+jobs:
+ close-unauthorized-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ steps:
+ # XXX: This *could* be done in Bash by abusing GitHub's own tool to interact with its API
+ # but that's too much of a hack, and we'll be adding a layer of abstraction. github-script
+ # is a workflow that eases interaction with GitHub API in the workflow run context.
+ - name: "Close 'unauthorized' issues"
+ uses: actions/github-script@v7
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const ALLOWED_USERS = ['vaxerski', 'fufexan', 'NotAShelf'];
+ const CLOSING_COMMENT = 'Users are no longer allowed to open issues themselves, please open a discussion instead.\n\nPlease see the [wiki](https://wiki.hyprland.org/Contributing-and-Debugging/Issue-Guidelines/) on why this is the case.\n\nWe are volunteers, and we need your cooperation to make the best software we can. Thank you for understanding! ❤️\n\n[Open a discussion here](https://github.com/hyprwm/Hyprland/discussions)';
+
+ async function closeUnauthorizedIssue(issueNumber, userName) {
+ if (ALLOWED_USERS.includes(userName)) {
+ console.log(`Issue #${issueNumber} - Created by authorized user ${userName}`);
+ return;
+ }
+
+ console.log(`Issue #${issueNumber} - Unauthorized, closing`);
+
+ await github.rest.issues.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issueNumber,
+ state: 'closed',
+ state_reason: 'not_planned'
+ });
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issueNumber,
+ body: CLOSING_COMMENT
+ });
+ }
+
+ if (context.eventName === 'issues' && context.payload.action === 'opened') {
+ // Direct access to the issue that triggered the workflow
+ const issue = context.payload.issue;
+
+ // Skip if this is a PR
+ if (issue.pull_request) {
+ console.log(`Issue #${issue.number} - Skipping, this is a pull request`);
+ return;
+ }
+
+ // Process the single issue that triggered the workflow
+ await closeUnauthorizedIssue(issue.number, issue.user.login);
+ } else {
+ // For manual runs, we need to handle pagination
+ async function* fetchAllOpenIssues() {
+ let page = 1;
+ let hasNextPage = true;
+
+ while (hasNextPage) {
+ const response = await github.rest.issues.listForRepo({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ state: 'open',
+ per_page: 100,
+ page: page
+ });
+
+ if (response.data.length === 0) {
+ hasNextPage = false;
+ } else {
+ for (const issue of response.data) {
+ yield issue;
+ }
+ page++;
+ }
+ }
+ }
+
+ // Process issues one by one
+ for await (const issue of fetchAllOpenIssues()) {
+ try {
+ // Skip pull requests
+ if (issue.pull_request) {
+ console.log(`Issue #${issue.number} - Skipping, this is a pull request`);
+ continue;
+ }
+
+ await closeUnauthorizedIssue(issue.number, issue.user.login);
+ } catch (error) {
+ console.error(`Error processing issue #${issue.number}: ${error.message}`);
+ }
+ }
+ }