From 8731eb92975246143e08f45045609f2284607a10 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 Aug 2025 19:51:18 +0000 Subject: [PATCH 1/3] Initial plan From 6f51dad9d0800a9f78dc1be6e5fcaebb1db43f65 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 Aug 2025 19:55:40 +0000 Subject: [PATCH 2/3] Add GitHub Action for automated issue moderation Co-authored-by: rawveg <308889+rawveg@users.noreply.github.com> --- .github/ISSUE_MODERATION.md | 46 +++++++++ .github/workflows/issue-moderation.yml | 130 +++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 .github/ISSUE_MODERATION.md create mode 100644 .github/workflows/issue-moderation.yml diff --git a/.github/ISSUE_MODERATION.md b/.github/ISSUE_MODERATION.md new file mode 100644 index 0000000..5a7acc0 --- /dev/null +++ b/.github/ISSUE_MODERATION.md @@ -0,0 +1,46 @@ +# Issue Moderation Configuration + +This repository includes an automated GitHub Action that moderates issues and comments based on team membership. + +## How it works + +The GitHub Action (`issue-moderation.yml`) automatically: + +1. **Monitors new issues**: When someone creates an issue, it checks if they're a member of authorized teams +2. **Monitors new comments**: When someone comments on an issue, it checks their team membership +3. **Takes action**: If the user is not in an authorized team: + - Issues: Closes the issue and adds an explanatory comment + - Comments: Deletes the comment immediately + +## Configuration + +To configure which teams are authorized, edit the `allowedTeams` array in `.github/workflows/issue-moderation.yml`: + +```javascript +const allowedTeams = [ + 'core-team', // Replace with your actual team slugs + 'maintainers', // Team slugs are found in your GitHub organization + 'admins' // Multiple teams can be authorized +]; +``` + +## Team Setup + +1. Ensure your GitHub organization has teams created +2. Add the appropriate members to each team +3. Update the `allowedTeams` array with your team slugs +4. The workflow will automatically enforce these permissions + +## Permissions Required + +The workflow requires the following permissions: +- `issues: write` - To close issues and create/delete comments +- `contents: read` - To access repository content +- `metadata: read` - To read organization metadata and team information + +## Important Notes + +- Only organization teams are supported (not repository collaborators) +- Team membership is checked against the organization that owns the repository +- The action provides clear logging for all moderation activities +- Users will receive a clear message when their issue is closed due to team membership \ No newline at end of file diff --git a/.github/workflows/issue-moderation.yml b/.github/workflows/issue-moderation.yml new file mode 100644 index 0000000..09dbf38 --- /dev/null +++ b/.github/workflows/issue-moderation.yml @@ -0,0 +1,130 @@ +--- +name: Issue Moderation + +"on": + issues: + types: [opened] + issue_comment: + types: [created] + +jobs: + moderate: + runs-on: ubuntu-latest + permissions: + issues: write + contents: read + metadata: read + + steps: + - name: Check team membership and moderate + uses: actions/github-script@v7 + with: + script: | + // Configuration: Define the teams that are allowed to create issues + // You can modify this list to include your organization's team slugs + const allowedTeams = [ + 'core-team', + 'maintainers', + 'admins' + ]; + + // Get the organization name from the repository + const org = context.repo.owner; + + async function isUserInAllowedTeams(username) { + try { + // Check if user is a member of any allowed team + for (const teamSlug of allowedTeams) { + try { + await github.rest.teams.getMembershipForUserInOrg({ + org: org, + team_slug: teamSlug, + username: username + }); + const msg = `User ${username} is a member of team ${teamSlug}`; + console.log(msg); + return true; + } catch (error) { + // User is not in this team, continue checking other teams + const msg = `User ${username} is not in team ${teamSlug}`; + console.log(msg); + } + } + return false; + } catch (error) { + const msg = `Error checking team membership for ${username}:`; + console.error(msg, error); + return false; + } + } + + // Handle issue opened event + const eventName = context.eventName; + const action = context.payload.action; + if (eventName === 'issues' && action === 'opened') { + const issue = context.payload.issue; + const issueAuthor = issue.user.login; + + const msg1 = `Checking issue #${issue.number} created by ${issueAuthor}`; + console.log(msg1); + + const isAuthorInTeam = await isUserInAllowedTeams(issueAuthor); + + if (!isAuthorInTeam) { + const msg2 = `Issue author ${issueAuthor} is not in any allowed team. Closing issue.`; + console.log(msg2); + + // Add a comment explaining why the issue is being closed + const body = '🤖 This issue has been automatically closed because it was not created by a member of an authorized team. Only team members can create issues in this repository.'; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: body + }); + + // Close the issue + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + state: 'closed', + state_reason: 'not_planned' + }); + + console.log(`Issue #${issue.number} has been closed.`); + } else { + const msg3 = `Issue author ${issueAuthor} is authorized. Issue will remain open.`; + console.log(msg3); + } + } + + // Handle issue comment event + if (eventName === 'issue_comment' && action === 'created') { + const comment = context.payload.comment; + const commentAuthor = comment.user.login; + const issue = context.payload.issue; + + const msg4 = `Checking comment by ${commentAuthor} on issue #${issue.number}`; + console.log(msg4); + + const isAuthorInTeam = await isUserInAllowedTeams(commentAuthor); + + if (!isAuthorInTeam) { + const msg5 = `Comment author ${commentAuthor} is not in any allowed team. Deleting comment.`; + console.log(msg5); + + // Delete the comment + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }); + + const msg6 = `Comment ${comment.id} by ${commentAuthor} has been deleted.`; + console.log(msg6); + } else { + const msg7 = `Comment author ${commentAuthor} is authorized. Comment will remain.`; + console.log(msg7); + } + } From 8f3f378f40db46a94dcee63b14664a643f9450d6 Mon Sep 17 00:00:00 2001 From: Tim Green Date: Wed, 20 Aug 2025 21:08:19 +0100 Subject: [PATCH 3/3] Update issue-moderation.yml Modified allowed teams in configuration array --- .github/workflows/issue-moderation.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue-moderation.yml b/.github/workflows/issue-moderation.yml index 09dbf38..aeb7a31 100644 --- a/.github/workflows/issue-moderation.yml +++ b/.github/workflows/issue-moderation.yml @@ -23,9 +23,8 @@ jobs: // Configuration: Define the teams that are allowed to create issues // You can modify this list to include your organization's team slugs const allowedTeams = [ - 'core-team', - 'maintainers', - 'admins' + 'creator-magic-admin-team', + 'premium-team' ]; // Get the organization name from the repository