Skip to content

Conversation

@MonaaEid
Copy link
Contributor

@MonaaEid MonaaEid commented Jan 5, 2026

This pull request introduces an automated system for maintaining a spam user list in the repository.

Automated Spam List Management

  • Added .github/scripts/update-spam-list.js, a script that:
    • Identifies spam users from closed, unmerged PRs labeled as 'spam' and rehabilitated users from merged PRs labeled as 'Good First Issue'.
    • Updates .github/spam-list.txt by adding or removing users based on their most recent activity.
    • Updates CHANGELOG.md with an entry describing the spam list update.
    • Generates a summary for the PR title and body describing the changes.

Related issue(s):

Fixes #1303

Checklist

  • Documented
  • Tested

Signed-off-by: MonaaEid <monaa_eid@hotmail.com>
@codecov
Copy link

codecov bot commented Jan 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1359   +/-   ##
=======================================
  Coverage   92.44%   92.44%           
=======================================
  Files         139      139           
  Lines        8528     8528           
=======================================
  Hits         7884     7884           
  Misses        644      644           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Hi, this is MergeConflictBot.
Your pull request cannot be merged because it contains merge conflicts.

Please resolve these conflicts locally and push the changes.

To assist you, please read:

Thank you for contributing!

MonaaEid and others added 2 commits January 7, 2026 02:19
Signed-off-by: MonaaEid <monaa_eid@hotmail.com>
Signed-off-by: MontyPokemon <59332150+MonaaEid@users.noreply.github.com>
@MonaaEid MonaaEid marked this pull request as ready for review January 7, 2026 00:27
Copilot AI review requested due to automatic review settings January 7, 2026 00:27
@MonaaEid MonaaEid review requested due to automatic review settings January 7, 2026 00:29
@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

📝 Walkthrough

Walkthrough

Adds a monthly/manual GitHub Actions workflow and a new helper script that scans closed PRs labeled "spam" and merged "Good First Issue" PRs, computes additions/removals by timeline, and opens an automated PR updating .github/spam-list.txt when changes are detected.

Changes

Cohort / File(s) Summary
GitHub Actions Script
.github/scripts/update-spam-list.js
New script that lists closed PRs labeled spam and merged PRs labeled Good First Issue, extracts latest dates per user, computes timeline-based additions/removals, reads existing .github/spam-list.txt, supports DRY_RUN, writes updates when not dry-run, and emits outputs: has-changes, pr-title, pr-body, branch-name.
GitHub Actions Workflow
.github/workflows/cron-update-spam-list.yml
New scheduled (monthly) + manual workflow that runs the script via actions/github-script, provides DRY_RUN input and GITHUB_TOKEN, captures script outputs, and conditionally creates a pull request using peter-evans/create-pull-request with labels automated and spam-management when changes exist and not in dry-run.
Changelog
CHANGELOG.md
Added entry documenting the new automated spam list update workflow and helper script.

Sequence Diagram

sequenceDiagram
    actor Scheduler as Monthly Scheduler
    participant Workflow as GitHub Actions Workflow
    participant Script as update-spam-list.js
    participant API as GitHub API
    participant FS as Repo FS (.github/spam-list.txt)
    participant PR as PR Service

    Scheduler->>Workflow: trigger (cron / manual)
    Workflow->>Workflow: checkout repo, set env (DRY_RUN, GITHUB_TOKEN)
    Workflow->>Script: run with github, context, core

    Script->>API: list closed PRs labeled "spam"
    API-->>Script: spam PRs
    Script->>Script: determine latest spam date per user

    Script->>API: list merged PRs labeled "Good First Issue"
    API-->>Script: merged PRs
    Script->>Script: determine latest rehab date per user

    Script->>Script: compute additions / removals by comparing timelines

    Script->>FS: read `.github/spam-list.txt`
    FS-->>Script: current list
    Script->>Script: produce updated list, prepare pr-title/pr-body/branch-name

    rect rgb(200,230,200)
    Script-->>Workflow: outputs: has-changes, pr-title, pr-body, branch-name
    end

    alt has-changes AND NOT DRY_RUN
        Workflow->>FS: write updated `.github/spam-list.txt` on branch
        FS-->>Workflow: file updated
        Workflow->>PR: create pull request with title/body/labels
        PR-->>Workflow: PR created
    else
        Workflow->>Workflow: no PR created (dry-run or no changes)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding a GitHub Actions workflow for automatic spam list updates.
Description check ✅ Passed The description clearly explains the automated spam list management system and its key components, directly related to the changeset.
Linked Issues check ✅ Passed The PR implements the core requirements from issue #1303: parsing spam/good-first-issue PRs, updating spam-list.txt, creating automated PRs, and following project conventions.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #1303: the update-spam-list.js script, cron workflow, and CHANGELOG.md entry are all in scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 438c6d0 and 86ce204.

📒 Files selected for processing (2)
  • .github/scripts/update-spam-list.js
  • .github/workflows/cron-update-spam-list.yml
🧰 Additional context used
📓 Path-based instructions (2)
.github/scripts/**/*.js

⚙️ CodeRabbit configuration file

.github/scripts/**/*.js: Review JavaScript scripts as long-lived automation code.

Scripts must remain:

  • Focused

  • Readable

  • Purpose-built

  • All context.payload fields MUST be validated

  • Free-form text MUST NOT be trusted

  • Dynamic code execution is prohibited

  • Avoid child_process.exec; prefer execFile if needed

  • All async operations MUST be wrapped in try/catch

  • Errors MUST include contextual metadata

  • Duplicate API calls MUST be avoided

  • Marker-based deduplication is required

  • Scripts MUST NOT assume write access

  • Permission failures MUST be handled gracefully

Files:

  • .github/scripts/update-spam-list.js
.github/workflows/**/*

⚙️ CodeRabbit configuration file

.github/workflows/**/*: Review workflows as security-sensitive infrastructure.

A good workflow is small, focused, and boring.
If a workflow is clever, generic, or overly flexible, it is a risk.


PRIORITY 0 — ABSOLUTE REQUIREMENTS

  • All third-party actions MUST be pinned to full commit SHAs, similar to other workflows.
  • permissions: MUST be explicitly declared and minimally scoped.
  • Workflows MUST behave safely when executed from forks.
  • YAML MUST orchestrate steps, not implement business logic.
  • Any workflow that mutates GitHub state MUST support dry-run mode.
  • Dry-run behavior must be explicit and visible in logs.
  • Workflows MUST NOT modify repository source code outside .github/.

PRIORITY 1 — SCOPE, FOCUS & RESTRAINT

  • The title of each workflow must be relevant, match similar naming schemes, and match its script filename.
  • Each workflow MUST have a single, clearly defined objective and SHOULD document this in a top-level comment.
  • Flag workflows that:
    • Attempt to be generic “frameworks”
    • Include speculative or future-facing logic
    • Perform actions unrelated to the stated goal
  • Over-abstraction and excess flexibility are maintenance risks.

PRIORITY 2 — INPUT HARDENING

  • Treat ALL GitHub event data as potentially hostile input, including:
    • issue titles, bodies, and comments
    • labels, usernames, branch names
  • Free-form user input MUST NOT be passed directly into:
    • shell commands
    • gh CLI arguments
    • Node.js exec / spawn calls
  • Require strict allowlists or exact string matches.
  • Flag any use of:
    • eval or bash -c
    • backticks or $(...) with user-controlled input

------------------...

Files:

  • .github/workflows/cron-update-spam-list.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Agent
  • GitHub Check: run-examples
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: StepSecurity Harden-Runner
🔇 Additional comments (1)
.github/scripts/update-spam-list.js (1)

186-207: Add hard upper bound to pagination per coding guidelines.

The pagination loop processes all matching PRs without a hard upper bound. Per coding guidelines (PRIORITY 5), pagination must "enforce hard upper bounds" to prevent excessive API usage and long run times.

Consider adding a safeguard:

♻️ Proposed fix with maximum result limit
+    const MAX_RESULTS_PER_SEARCH = 1000; // Safeguard against excessive API calls
+
     // Use pagination iterator with your existing pattern
     for (const { name, query, process } of searches) {
       console.log(`Fetching ${name}...`);
+      let processedCount = 0;
       
       const iterator = github.paginate.iterator(
         github.rest.search.issuesAndPullRequests,
         {
           q: query,
           per_page: 100,
           sort: 'updated',
           order: 'desc'
         }
       );
 
       for await (const { data: items } of iterator) {
         for (const pr of items) {
+          if (processedCount >= MAX_RESULTS_PER_SEARCH) {
+            console.log(`⚠️  Reached maximum of ${MAX_RESULTS_PER_SEARCH} results for ${name}`);
+            break;
+          }
           // Sequential processing keeps API pressure predictable
           // eslint-disable-next-line no-await-in-loop
           await process(pr);
+          processedCount++;
         }
+        if (processedCount >= MAX_RESULTS_PER_SEARCH) break;
       }
+      console.log(`Processed ${processedCount} ${name}`);
     }

Based on coding guidelines, PRIORITY 5 — API EFFICIENCY & DISCIPLINE.

Likely an incorrect or invalid review comment.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f4767a and 7835d31.

📒 Files selected for processing (3)
  • .github/scripts/update-spam-list.js
  • .github/workflows/cron-update-spam-list.yml
  • CHANGELOG.md
🧰 Additional context used
📓 Path-based instructions (2)
.github/scripts/**/*.js

⚙️ CodeRabbit configuration file

.github/scripts/**/*.js: Review JavaScript scripts as long-lived automation code.

Scripts must remain:

  • Focused

  • Readable

  • Purpose-built

  • All context.payload fields MUST be validated

  • Free-form text MUST NOT be trusted

  • Dynamic code execution is prohibited

  • Avoid child_process.exec; prefer execFile if needed

  • All async operations MUST be wrapped in try/catch

  • Errors MUST include contextual metadata

  • Duplicate API calls MUST be avoided

  • Marker-based deduplication is required

  • Scripts MUST NOT assume write access

  • Permission failures MUST be handled gracefully

Files:

  • .github/scripts/update-spam-list.js
.github/workflows/**/*

⚙️ CodeRabbit configuration file

.github/workflows/**/*: Review workflows as security-sensitive infrastructure.

A good workflow is small, focused, and boring.
If a workflow is clever, generic, or overly flexible, it is a risk.


PRIORITY 0 — ABSOLUTE REQUIREMENTS

  • All third-party actions MUST be pinned to full commit SHAs, similar to other workflows.
  • permissions: MUST be explicitly declared and minimally scoped.
  • Workflows MUST behave safely when executed from forks.
  • YAML MUST orchestrate steps, not implement business logic.
  • Any workflow that mutates GitHub state MUST support dry-run mode.
  • Dry-run behavior must be explicit and visible in logs.
  • Workflows MUST NOT modify repository source code outside .github/.

PRIORITY 1 — SCOPE, FOCUS & RESTRAINT

  • The title of each workflow must be relevant, match similar naming schemes, and match its script filename.
  • Each workflow MUST have a single, clearly defined objective and SHOULD document this in a top-level comment.
  • Flag workflows that:
    • Attempt to be generic “frameworks”
    • Include speculative or future-facing logic
    • Perform actions unrelated to the stated goal
  • Over-abstraction and excess flexibility are maintenance risks.

PRIORITY 2 — INPUT HARDENING

  • Treat ALL GitHub event data as potentially hostile input, including:
    • issue titles, bodies, and comments
    • labels, usernames, branch names
  • Free-form user input MUST NOT be passed directly into:
    • shell commands
    • gh CLI arguments
    • Node.js exec / spawn calls
  • Require strict allowlists or exact string matches.
  • Flag any use of:
    • eval or bash -c
    • backticks or $(...) with user-controlled input

------------------...

Files:

  • .github/workflows/cron-update-spam-list.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Agent
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: run-examples
  • GitHub Check: StepSecurity Harden-Runner
🔇 Additional comments (7)
CHANGELOG.md (1)

90-90: LGTM!

The changelog entry is concise and accurately describes the new feature. Consider adding an issue reference (e.g., (#1303)) for traceability, consistent with many other entries in this file.

.github/scripts/update-spam-list.js (4)

18-73: LGTM!

The computation logic correctly handles the date-based precedence for spam vs rehabilitation, including the edge cases where users may have multiple events. Error handling for missing files is appropriate.


76-91: LGTM!

Dry-run mode is properly implemented with clear logging, and the directory creation is a good defensive measure.


95-125: LGTM!

The summary generation provides clear, well-formatted output for the automated PR.


192-198: This review comment is incorrect—the code is working as intended.

The github.paginate.iterator() yields response objects where data contains the array directly (from other usages in the codebase like coderabbit_plan_trigger.js, which does for await (const { data: page } of iterator) followed by comments.push(...page)). The destructuring { data: items } correctly assigns the array to items, and the subsequent loop for (const pr of items) properly iterates over PR objects. No fix is needed.

.github/workflows/cron-update-spam-list.yml (2)

3-19: LGTM!

Good implementation:

  • Monthly schedule is appropriate for spam list maintenance
  • Dry-run defaults to true for manual runs (safe)
  • Scheduled runs default to false (operational)
  • Permissions are minimal and appropriate for the operations

48-59: LGTM!

The PR creation step correctly:

  • Gates on both has-changes and DRY_RUN
  • Scopes the commit to only .github/spam-list.txt via add-paths
  • Uses appropriate labels for tracking automated changes

Comment on lines +221 to +224
core.setOutput('has-changes', hasChanges.toString());
core.setOutput('pr-title', title);
core.setOutput('pr-body', body);
core.setOutput('branch-name', branchName);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Minor: Outputs are set redundantly.

The script sets outputs via core.setOutput here, but the workflow YAML also sets them from the returned object. Consider removing one set to avoid confusion. The workflow's inline setting (lines 42-45) can be removed since the script already handles it.

Comment on lines +20 to +22
jobs:
update-spam-list:
runs-on: ubuntu-latest
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add a concurrency group to prevent overlapping runs.

Per coding guidelines, workflows that mutate state must define a deterministic concurrency group to be safe under retries and parallel execution. Without this, overlapping scheduled or manual runs could create conflicting branches/PRs.

🔎 Proposed fix
 jobs:
   update-spam-list:
     runs-on: ubuntu-latest
+    concurrency:
+      group: spam-list-update
+      cancel-in-progress: false
     steps:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
jobs:
update-spam-list:
runs-on: ubuntu-latest
jobs:
update-spam-list:
runs-on: ubuntu-latest
concurrency:
group: spam-list-update
cancel-in-progress: false
steps:

Copilot AI review requested due to automatic review settings January 7, 2026 12:17
@MonaaEid MonaaEid review requested due to automatic review settings January 7, 2026 12:18
Signed-off-by: MonaaEid <monaa_eid@hotmail.com>
@MonaaEid MonaaEid requested review from Copilot and removed request for Copilot January 7, 2026 12:19
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7835d31 and 438c6d0.

📒 Files selected for processing (1)
  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Agent
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build-and-test (3.10)
  • GitHub Check: build-and-test (3.13)
  • GitHub Check: build-and-test (3.11)
  • GitHub Check: build-and-test (3.12)
  • GitHub Check: run-examples
  • GitHub Check: StepSecurity Harden-Runner

- Added workflow to prevent assigning intermediate issues to contributors without prior Good First Issue completion (#1143).
- Added `Client.from_env()` and network-specific factory methods (e.g., `Client.for_testnet()`) to simplify client initialization and reduce boilerplate. [[#1251](https://github.com/hiero-ledger/hiero-sdk-python/issues/1251)]
- Improved unit test coverage for `TransactionId` class, covering parsing logic, hashing, and scheduled transactions.
- Add GitHub Actions script and workflow for automatic spam list updates.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add issue reference for consistency with similar entries.

While the changelog entry is factually accurate, it should include a reference to issue #1303 (as mentioned in the PR objectives) to maintain consistency with similar workflow entries throughout the CHANGELOG (e.g., cron-check-broken-links references #1210, merge-conflict-bot references #1247).

Consider updating the entry to:

- Add GitHub Actions script and workflow for automatic spam list updates. (#1303)

Copy link
Contributor

@aceppaluni aceppaluni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MonaaEid This is great work! 👍

Please make sure to adjust the changelog entry.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Intermediate]: Create cron job that creates an automated pull request with an update to spam-list.txt

2 participants