Skip to content

[chore] Added reusable active autoassign bots workflow and fixed exit codes#613

Open
Eeshu-Yadav wants to merge 6 commits intoopenwisp:masterfrom
Eeshu-Yadav:feature/reusable-autoassign-workflow
Open

[chore] Added reusable active autoassign bots workflow and fixed exit codes#613
Eeshu-Yadav wants to merge 6 commits intoopenwisp:masterfrom
Eeshu-Yadav:feature/reusable-autoassign-workflow

Conversation

@Eeshu-Yadav
Copy link
Contributor

This PR adds a reusable GitHub Actions workflow for the auto-assignment bots to reduce boilerplate code across OpenWISP repositories. It also includes fixes for the Python script return values so they exit successfully when skipping irrelevant events, avoiding false-positive CI failures.

Copilot AI review requested due to automatic review settings March 8, 2026 19:21
@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Handlers in .github/actions/bot-autoassign (issue_assignment_bot.py, pr_reopen_bot.py, stale_pr_bot.py) were updated to return True in many early-return/no-op/error branches where they previously returned False; corresponding unit tests were adjusted to expect True. A reusable GitHub Actions workflow was added at .github/workflows/reusable-bot-autoassign.yml to generate a GitHub App token, checkout the repository, set up Python, install dependencies, and run the bot CLI with BOT_COMMAND and optional GITHUB_EVENT_PATH. Documentation was updated to reference and demonstrate using the reusable workflow.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Workflow as GitHub Workflow
participant TokenAction as actions/create-github-app-token
participant Runner as GitHub Actions Runner
participant Checkout as actions/checkout
participant Python as actions/setup-python
participant Bot as Bot CLI (.main.py)
participant GitHubAPI as GitHub API

Workflow->>TokenAction: request app token (APP_ID, PRIVATE_KEY)
TokenAction-->>Workflow: return TOKEN
Runner->>Checkout: checkout openwisp-utils (subpath)
Runner->>Python: setup Python 3.13
Runner->>Runner: pip install -e 'openwisp-utils/.[github_actions]'
Runner->>Bot: run Bot CLI with BOT_COMMAND (and optional GITHUB_EVENT_PATH)
Bot->>GitHubAPI: call API using TOKEN / GITHUB_TOKEN
GitHubAPI-->>Bot: event handling responses
Bot-->>Runner: exit status (handled / ok)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing most required template sections including checklist, issue reference, and screenshots, though it provides a basic summary of changes. Add the missing sections from the template: checklist confirmation, issue reference, and update description to follow the structured template format.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding a reusable workflow and fixing exit codes in the auto-assignment bots.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a 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.

@kilo-code-bot
Copy link

kilo-code-bot bot commented Mar 8, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The changes in this PR correctly fix a semantic issue where bot scripts were returning failure exit codes when they simply had nothing to do (e.g., comment on a PR instead of an issue, unsupported event type). Now True is returned for "successfully skipped" scenarios and False is reserved for actual errors.

The new reusable workflow (reusable-bot-autoassign.yml) is well-structured with proper secret handling and uses validated bot commands.

Files Reviewed (5 files)
  • .github/actions/bot-autoassign/issue_assignment_bot.py - Return value fixes for skip conditions
  • .github/actions/bot-autoassign/pr_reopen_bot.py - Return value fixes for skip conditions
  • .github/actions/bot-autoassign/tests/test_issue_assignment_bot.py - Updated test assertions
  • .github/actions/bot-autoassign/tests/test_pr_reopen_bot.py - Updated test assertions
  • .github/workflows/reusable-bot-autoassign.yml - New reusable workflow (new file)

@coderabbitai coderabbitai bot added enhancement github_actions Pull requests that update GitHub Actions code helper-bots Helper bots, release management automation labels Mar 8, 2026
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/reusable-bot-autoassign.yml:
- Around line 48-51: The workflow currently passes the bot_command input
unquoted to the Python script; update both invocations in the
reusable-bot-autoassign.yml snippet to quote ${{ inputs.bot_command }} (e.g.,
use "${{ inputs.bot_command }}") so that the bot_command argument is passed
robustly even if it contains whitespace or special characters, keeping the
existing conditional that appends "$GITHUB_EVENT_PATH" intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4e565351-663d-4043-b38a-a25e2515a1b3

📥 Commits

Reviewing files that changed from the base of the PR and between 918944a and 42aae10.

📒 Files selected for processing (5)
  • .github/actions/bot-autoassign/issue_assignment_bot.py
  • .github/actions/bot-autoassign/pr_reopen_bot.py
  • .github/actions/bot-autoassign/tests/test_issue_assignment_bot.py
  • .github/actions/bot-autoassign/tests/test_pr_reopen_bot.py
  • .github/workflows/reusable-bot-autoassign.yml
📜 Review details
⏰ 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). (7)
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 0
File: :0-0
Timestamp: 2026-03-05T20:55:29.968Z
Learning: For the openwisp/openwisp-utils repository (and the broader openwisp org), the maintainers have explicitly decided to use mutable version tags (e.g. `v2`, `v6`) for GitHub Actions and to use `ref: master` for internal script checkouts. Do NOT flag unpinned action versions or `master`/version-tag usage as security issues in any openwisp-utils workflow file. The maintainers are aware of the trade-offs and are intentionally fine with this approach.
📚 Learning: 2026-03-05T14:23:55.528Z
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.

Applied to files:

  • .github/workflows/reusable-bot-autoassign.yml
  • .github/actions/bot-autoassign/pr_reopen_bot.py
📚 Learning: 2026-03-05T09:38:10.320Z
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.

Applied to files:

  • .github/actions/bot-autoassign/pr_reopen_bot.py
🔇 Additional comments (5)
.github/actions/bot-autoassign/pr_reopen_bot.py (1)

92-92: LGTM! Return value semantics correctly updated for skip paths.

The change from return False to return True for non-critical skip scenarios (unsupported events, comments on issues vs PRs, non-author comments, non-stale PRs) aligns with the PR objective. These paths represent successful "no-op" handling rather than errors, so returning True (exit code 0) prevents false-positive CI failures.

The error paths (missing payload, exceptions, missing required data) still correctly return False.

Also applies to: 116-116, 120-120, 124-124, 172-172

.github/actions/bot-autoassign/issue_assignment_bot.py (1)

276-276: LGTM! Consistent return value semantics for non-error skip paths.

The updated return values correctly distinguish between:

  • True: Event was processed or intentionally skipped (comment on PR, no assignment request, unsupported action/event)
  • False: Actual errors (missing payload, exceptions, missing required data)

This prevents CI failures when the bot encounters events it doesn't need to act on, which is the intended behavior per the PR objectives.

Also applies to: 288-288, 314-314, 331-331

.github/actions/bot-autoassign/tests/test_pr_reopen_bot.py (1)

108-112: LGTM! Test expectations correctly updated to match implementation.

The test assertions properly reflect the new return value semantics:

  • Unsupported events and non-critical skip paths now expect True
  • Error conditions (e.g., test_handle_contributor_activity_no_payload at line 197) still correctly expect False

This ensures the tests validate the intended behavior where skipping irrelevant events is a success, not a failure.

Also applies to: 147-163, 165-180, 182-193, 199-202

.github/actions/bot-autoassign/tests/test_issue_assignment_bot.py (1)

278-294: LGTM! Test expectations correctly aligned with implementation changes.

The test updates properly validate:

  • Skip paths (test_skip_pr_comment, test_non_assignment_comment, test_unsupported_action, test_unsupported_event) now expect True
  • Error paths (test_no_payload, test_no_github_client) still correctly expect False

This maintains proper test coverage for both success and failure scenarios.

Also applies to: 296-307, 376-388, 431-434

.github/workflows/reusable-bot-autoassign.yml (1)

1-52: LGTM! Well-structured reusable workflow.

The workflow correctly:

  • Generates a GitHub App token for authentication
  • Checks out openwisp-utils and sets up Python 3.13
  • Installs dependencies via the [github_actions] extras
  • Conditionally passes GITHUB_EVENT_PATH when available
  • Provides the required environment variables (GITHUB_TOKEN, REPOSITORY, GITHUB_EVENT_NAME) that match what GitHubBot base class expects

The invocation pattern matches the existing bot-autoassign-issue.yml workflow, ensuring compatibility. Based on learnings, the use of mutable version tags (v2, v6) and ref: master is intentional and acceptable for this repository.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a reusable GitHub Actions workflow (reusable-bot-autoassign.yml) that other OpenWISP repositories can call via workflow_call to run the auto-assignment bots, avoiding duplication of the full bot workflow boilerplate across repos. It also fixes the Python bot scripts to return True (exit 0) instead of False (exit 1) when skipping irrelevant or inapplicable events, preventing false-positive CI failures.

Changes:

  • Added a new reusable workflow (reusable-bot-autoassign.yml) that checks out openwisp-utils and runs any bot command via workflow_call.
  • Fixed return values in issue_assignment_bot.py and pr_reopen_bot.py so that "skip" conditions (unsupported events, non-applicable payloads) return True instead of False.
  • Updated test assertions in test_issue_assignment_bot.py and test_pr_reopen_bot.py to reflect the corrected return semantics.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
.github/workflows/reusable-bot-autoassign.yml New reusable workflow for running bot scripts in other repos
.github/actions/bot-autoassign/issue_assignment_bot.py Fixed skip-case return values from False to True
.github/actions/bot-autoassign/pr_reopen_bot.py Fixed skip-case return values from False to True
.github/actions/bot-autoassign/tests/test_issue_assignment_bot.py Updated test assertions to match corrected return semantics
.github/actions/bot-autoassign/tests/test_pr_reopen_bot.py Updated test assertions to match corrected return semantics

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@Eeshu-Yadav Eeshu-Yadav changed the title chores: add reusable active autoassign bots workflow and fix exit codes [chore] Added reusable active autoassign bots workflow and fixed exit codes Mar 8, 2026
@coveralls
Copy link

coveralls commented Mar 8, 2026

Coverage Status

coverage: 97.348%. remained the same
when pulling 984dcd6 on Eeshu-Yadav:feature/reusable-autoassign-workflow
into bbe1520 on openwisp:master.

Eeshu-Yadav added a commit to Eeshu-Yadav/openwisp-utils that referenced this pull request Mar 8, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 8, 2026
@Eeshu-Yadav Eeshu-Yadav force-pushed the feature/reusable-autoassign-workflow branch from 686b04a to d9ec4a7 Compare March 8, 2026 19:35
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

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

@Eeshu-Yadav can you please update the bot testin ground accordingly so we can test this there before merging?

What about the worfklows added before? And what about the docs? Does the docs need to be updated?

@openwisp-companion
Copy link

### ReStructuredText Formatting Failure

Hello @Eeshu-Yadav,
*(Analysis for commit 836205d)*

**Explanation:**
The CI pipeline failed because the ReStructuredText formatting check failed. Specifically, the file `/home/runner/work/openwisp-utils/openwisp-utils/docs/developer/reusable-github-utils.rst` could not be reformatted by the `docstrfmt` tool, indicating a formatting issue within that file. This check is part of the `run-qa-checks` script.

**Remediation:**
To fix this, you need to reformat the `docs/developer/reusable-github-utils.rst` file. You can do this by running the `openwisp-qa-format` command locally. This command will attempt to automatically fix the formatting issues.

If the automatic formatting does not resolve the issue, you may need to manually inspect and correct the formatting in `docs/developer/reusable-github-utils.rst` according to ReStructuredText conventions.

```bash
openwisp-qa-format
```

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 9, 2026
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/developer/reusable-github-utils.rst`:
- Around line 89-98: The reusable workflow incorrectly maps inputs.bot_command
to BOT_TOKEN and never sets BOT_COMMAND, so downstream examples passing
bot_command fail; update reusable-bot-autoassign.yml to set the environment
variables correctly by assigning BOT_COMMAND: ${{ inputs.bot_command }} (and
ensure BOT_TOKEN is assigned from the appropriate input, e.g., BOT_TOKEN: ${{
inputs.bot_token }}), and keep invoking the script with __main__.py
"$BOT_COMMAND" (or pass the input as an argument) so the script receives the
command under the name it expects.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a5ae685e-7d49-4cd6-9d22-610630ee3ac2

📥 Commits

Reviewing files that changed from the base of the PR and between 836205d and a483dbe.

📒 Files selected for processing (1)
  • docs/developer/reusable-github-utils.rst
📜 Review details
⏰ 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). (14)
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.0.0
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.
📚 Learning: 2026-03-05T14:23:55.528Z
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.

Applied to files:

  • docs/developer/reusable-github-utils.rst
📚 Learning: 2026-03-05T09:38:10.320Z
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.

Applied to files:

  • docs/developer/reusable-github-utils.rst
🔇 Additional comments (1)
docs/developer/reusable-github-utils.rst (1)

118-123: This follows the project maintainers' explicit approach for openwisp-utils.

While GitHub best practices recommend pinning to immutable refs (commit SHAs) for production stability, the openwisp-utils maintainers have explicitly decided to use @master and mutable version tags for their workflows, and have documented awareness of the trade-offs. This approach is intentional for the project.

			> Likely an incorrect or invalid review comment.

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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/bot-autoassign/issue_assignment_bot.py:
- Around line 289-291: The three broad except Exception as e blocks that
currently just print messages like "Error handling issue comment: {e}" and then
return True should be changed to not mask real failures: for unexpected
exceptions either re-raise the exception or return False so the workflow fails
(and include the full traceback via logging.exception or similar), while keeping
intentional skips returning True where the code explicitly detects
non-assignment/unsupported events; update the except blocks (the ones that print
"Error handling issue comment: {e}" and the two other similar exception
handlers) to differentiate expected skips vs unexpected errors, log full error
details, and adjust the return value accordingly (or add a clear comment
documenting why an exception would be swallowed if you choose to preserve the
current behavior).

In @.github/actions/bot-autoassign/pr_reopen_bot.py:
- Around line 101-104: The method handle_contributor_activity currently returns
True when self.event_payload is missing, which is inconsistent with
handle_pr_reopen (which returns False); change handle_contributor_activity to
return False in the empty-payload branch so both methods treat a missing
event_payload the same way (i.e., treat it as an unexpected error case), keeping
the check on self.event_payload and the print("No event payload available")
intact.

In @.github/actions/bot-autoassign/stale_pr_bot.py:
- Around line 321-324: The check in process_stale_prs currently prints "GitHub
repository not initialized" and returns True, which is inconsistent with run()'s
behavior for initialization failures; change process_stale_prs (method name) to
return False when self.repo is not set so it signals failure like run() does,
keeping the existing print/log message unchanged.

In @.github/actions/bot-autoassign/tests/test_pr_reopen_bot.py:
- Around line 195-197: The test shows handle_contributor_activity() returns True
when called with no payload but handle_pr_reopen() returns False for missing
payload; either add a brief inline comment in the PRActivityBot class explaining
why handle_contributor_activity is intentionally permissive, referencing the
method name handle_contributor_activity to justify this behavior, or change the
implementation of handle_contributor_activity to mirror handle_pr_reopen's
behavior (return False on missing payload) and update the test accordingly;
ensure you modify the method body (and its test) or add the explanatory comment
near the handle_contributor_activity definition so future readers understand the
discrepancy.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: df45aca3-0767-46d2-9397-0c3b7c9fb48c

📥 Commits

Reviewing files that changed from the base of the PR and between a483dbe and 46f5bad.

📒 Files selected for processing (5)
  • .github/actions/bot-autoassign/issue_assignment_bot.py
  • .github/actions/bot-autoassign/pr_reopen_bot.py
  • .github/actions/bot-autoassign/stale_pr_bot.py
  • .github/actions/bot-autoassign/tests/test_pr_reopen_bot.py
  • .github/actions/bot-autoassign/tests/test_stale_pr_bot.py
📜 Review details
⏰ 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). (14)
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=4.2.0
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.
📚 Learning: 2026-03-05T09:59:22.581Z
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/actions/bot-changelog-generator/generate_changelog.py:356-364
Timestamp: 2026-03-05T09:59:22.581Z
Learning: In `.github/actions/bot-changelog-generator/generate_changelog.py`, the `validate_changelog_output` function's purpose is to act as an output safety filter — ensuring no sensitive information or arbitrary LLM-generated text gets posted as a PR comment. It checks that the output starts with a valid tag ([feature]/[fix]/[change]) and contains a correctly structured PR reference pattern. It is NOT intended to strictly validate that the referenced PR number/URL matches the current PR.

Applied to files:

  • .github/actions/bot-autoassign/stale_pr_bot.py
🔇 Additional comments (5)
.github/actions/bot-autoassign/issue_assignment_bot.py (1)

329-334: LGTM for unsupported event handling.

Returning True for unsupported event types correctly signals that the bot handled the situation (by intentionally skipping) rather than failing. This prevents false-positive CI failures when the workflow is triggered by events the bot doesn't handle.

.github/actions/bot-autoassign/stale_pr_bot.py (1)

144-147: LGTM for already-closed PR handling.

Returning True when the PR is already closed is correct - this is an expected condition, not an error.

.github/actions/bot-autoassign/pr_reopen_bot.py (1)

114-124: LGTM for early-exit skip conditions.

Returning True for these conditions is appropriate:

  • Comment is on an issue, not a PR (line 116)
  • Comment not from PR author (line 120)
  • PR is not stale (line 124)

These are "not my job" conditions where the bot correctly identifies the event doesn't require action.

.github/actions/bot-autoassign/tests/test_pr_reopen_bot.py (1)

108-111: LGTM for unsupported event test updates.

Both test_run_unsupported_event tests correctly expect True, matching the updated behavior where unsupported events are treated as handled (skip) rather than errors.

Also applies to: 199-202

.github/actions/bot-autoassign/tests/test_stale_pr_bot.py (1)

230-236: LGTM for already-closed PR test update.

The test correctly expects True when attempting to close an already-closed PR, matching the updated implementation. The assertions that create_issue_comment and edit are not called remain correct - the bot properly skips redundant actions.

@Eeshu-Yadav Eeshu-Yadav force-pushed the feature/reusable-autoassign-workflow branch from c5b0652 to 984dcd6 Compare March 11, 2026 19:30
@Eeshu-Yadav
Copy link
Contributor Author

Eeshu-Yadav commented Mar 11, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@openwisp-companion
Copy link

Selenium Test Failure

Hello @Eeshu-Yadav,
(Analysis for commit 984dcd6)

There is one test failure in the CI logs:

  1. Test Failure: The test_input_filters test in test_project.tests.test_selenium.TestInputFilters failed with an InvalidSessionIdException.

    • Explanation: This exception typically occurs when Selenium tries to interact with a browser session that has already been closed or invalidated. In this specific case, the traceback indicates the failure happened during the self.login() call within the test, which is trying to navigate to the admin login page. This suggests that the browser session might have been terminated prematurely or an issue occurred during the login process, leading to an invalid session ID when subsequent actions were attempted. The test retries also failed, indicating a persistent issue rather than a transient one.

    • Remediation: To fix this, investigate the login() method in openwisp_utils/tests/selenium.py and the test_input_filters method in tests/test_project/tests/test_selenium.py. Ensure that the browser session remains active and valid throughout the test execution. Check for any potential race conditions or unexpected browser closures that might be happening before or during the login process. Debugging the login() method to ensure it correctly establishes and maintains a valid session would be the first step.

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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/bot-autoassign/issue_assignment_bot.py:
- Around line 282-284: The current checks that print "Missing required comment
data" and return True silently treat malformed event payloads as success; change
these to treat missing required fields as failures by returning False (or
raising an error) instead of True. Specifically update the branch that checks
comment_body, commenter, issue_number to return False when any are missing, and
similarly update the branch checking pr_number and pr_author (the other block
noted) to return False; locate these checks by the variable names comment_body,
commenter, issue_number, pr_number, and pr_author and adjust the return value so
malformed payloads do not exit 0.

In @.github/actions/bot-autoassign/pr_reopen_bot.py:
- Around line 70-72: The branch that checks required payload fields uses `if not
all([pr_number, pr_author]):` but returns True (treating it as a skip); change
it to return False so missing PR/comment fields are treated as failures. Update
the `process`/handler function where `pr_number` and `pr_author` are validated
to log the missing-data case and return False instead of True, and make the same
change for the analogous check around the other occurrence (the block referenced
at lines 111-113) to ensure both validation failures return False rather than
True.

In @.github/actions/bot-autoassign/stale_pr_bot.py:
- Around line 149-151: The current checks that set pr_author = pr.user.login if
pr.user else None and then return True when missing cause PRs with no author to
be treated as successfully processed; change those branches in
send_stale_warning, mark_pr_stale, and close_stale_pr so they do not return True
for missing authors — either (A) return False so process_stale_prs knows the PR
was not handled, or preferably (B) continue processing using a generic
salutation (e.g., set pr_author to "there" or "maintainer") and proceed with the
warning/unassign/close logic; update the pr_author assignment sites (where
pr.user is checked) to implement one of these fixes consistently and ensure
process_stale_prs receives a proper success/failure result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7e0110ea-60fd-40d1-83e3-6e80480fbac9

📥 Commits

Reviewing files that changed from the base of the PR and between 46f5bad and 984dcd6.

📒 Files selected for processing (8)
  • .github/actions/bot-autoassign/issue_assignment_bot.py
  • .github/actions/bot-autoassign/pr_reopen_bot.py
  • .github/actions/bot-autoassign/stale_pr_bot.py
  • .github/actions/bot-autoassign/tests/test_issue_assignment_bot.py
  • .github/actions/bot-autoassign/tests/test_pr_reopen_bot.py
  • .github/actions/bot-autoassign/tests/test_stale_pr_bot.py
  • .github/workflows/reusable-bot-autoassign.yml
  • docs/developer/reusable-github-utils.rst
📜 Review details
⏰ 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). (2)
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.
📚 Learning: 2026-03-05T09:38:10.320Z
Learnt from: pushpitkamboj
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:49-49
Timestamp: 2026-03-05T09:38:10.320Z
Learning: In openwisp-utils, PR title prefixes are strictly limited to `[feature]`, `[fix]`, and `[change]` (exact bracketed tags, no scoping/sub-types). The regex `^\[(feature|fix|change)\]` in `.github/workflows/reusable-bot-changelog.yml` is intentional and correct — scoped variants like `[feature/bots]` are not valid and should not be matched.

Applied to files:

  • .github/actions/bot-autoassign/tests/test_pr_reopen_bot.py
  • docs/developer/reusable-github-utils.rst
  • .github/workflows/reusable-bot-autoassign.yml
📚 Learning: 2026-03-05T14:23:55.528Z
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 584
File: .github/workflows/reusable-bot-changelog.yml:22-24
Timestamp: 2026-03-05T14:23:55.528Z
Learning: In `.github/workflows/reusable-bot-changelog.yml`, the maintainer (nemesifier) has explicitly decided that `github.event.review.author_association == 'COLLABORATOR'` should be allowed (alongside `OWNER` and `MEMBER`) to trigger the changelog bot workflow. The rationale is that the workflow is non-destructive and only posts a PR comment — it cannot make code changes. Do not flag `COLLABORATOR` as a security issue for this workflow.

Applied to files:

  • docs/developer/reusable-github-utils.rst
  • .github/workflows/reusable-bot-autoassign.yml
🔇 Additional comments (1)
.github/workflows/reusable-bot-autoassign.yml (1)

27-32: The current approach is intentional per project guidelines.

The maintainers of openwisp-utils have explicitly decided to use ref: master for internal script checkouts in workflow files. This is an intentional design choice, and the trade-offs are understood and accepted.

			> Likely an incorrect or invalid review comment.

Comment on lines 282 to +284
if not all([comment_body, commenter, issue_number]):
print("Missing required comment data")
return False
return True
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

Keep malformed event payloads as failures.

These branches now treat missing required webhook fields as a successful skip. That makes sense for irrelevant events, but not for malformed issue_comment / pull_request_target payloads. If issue_number, commenter, pr_number, or pr_author is missing, something is broken and the workflow should not exit 0 silently.

🛠️ Proposed fix
             if not all([comment_body, commenter, issue_number]):
                 print("Missing required comment data")
-                return True
+                return False
@@
             if not all([pr_number, pr_author]):
                 print("Missing required PR data")
-                return True
+                return False

Also applies to: 303-305

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/bot-autoassign/issue_assignment_bot.py around lines 282 -
284, The current checks that print "Missing required comment data" and return
True silently treat malformed event payloads as success; change these to treat
missing required fields as failures by returning False (or raising an error)
instead of True. Specifically update the branch that checks comment_body,
commenter, issue_number to return False when any are missing, and similarly
update the branch checking pr_number and pr_author (the other block noted) to
return False; locate these checks by the variable names comment_body, commenter,
issue_number, pr_number, and pr_author and adjust the return value so malformed
payloads do not exit 0.

Comment on lines 70 to +72
if not all([pr_number, pr_author]):
print("Missing required PR data")
return False
return True
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

Treat missing payload fields as failures, not handled skips.

These branches now return True when required PR/comment fields are absent. That is different from an intentional skip and will mask broken payload loading or event-shape regressions. The permissive True paths for "not a PR", "not author", and "not stale" are fine; these data-validation failures should still be False.

🛠️ Proposed fix
             if not all([pr_number, pr_author]):
                 print("Missing required PR data")
-                return True
+                return False
@@
             if not all([pr_number, commenter]):
                 print("Missing required comment data")
-                return True
+                return False

Also applies to: 111-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/bot-autoassign/pr_reopen_bot.py around lines 70 - 72, The
branch that checks required payload fields uses `if not all([pr_number,
pr_author]):` but returns True (treating it as a skip); change it to return
False so missing PR/comment fields are treated as failures. Update the
`process`/handler function where `pr_number` and `pr_author` are validated to
log the missing-data case and return False instead of True, and make the same
change for the analogous check around the other occurrence (the block referenced
at lines 111-113) to ensure both validation failures return False rather than
True.

Comment on lines 149 to +151
pr_author = pr.user.login if pr.user else None
if not pr_author:
return False
return True
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

Don't report missing-author PRs as successfully processed.

These branches skip the actual warning/stale/close work but still return True, so process_stale_prs() counts the PR as processed. A PR whose author account is unavailable will therefore never be warned, unassigned, or closed, and the logs will still say it was handled.

At minimum, this should return False; better yet, keep processing with a generic salutation instead of requiring pr.user.login.

🛠️ Minimal safe fix
             pr_author = pr.user.login if pr.user else None
             if not pr_author:
-                return True
+                return False

Apply the same change in close_stale_pr, mark_pr_stale, and send_stale_warning.

Also applies to: 211-213, 274-276

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/bot-autoassign/stale_pr_bot.py around lines 149 - 151, The
current checks that set pr_author = pr.user.login if pr.user else None and then
return True when missing cause PRs with no author to be treated as successfully
processed; change those branches in send_stale_warning, mark_pr_stale, and
close_stale_pr so they do not return True for missing authors — either (A)
return False so process_stale_prs knows the PR was not handled, or preferably
(B) continue processing using a generic salutation (e.g., set pr_author to
"there" or "maintainer") and proceed with the warning/unassign/close logic;
update the pr_author assignment sites (where pr.user is checked) to implement
one of these fixes consistently and ensure process_stale_prs receives a proper
success/failure result.

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

Labels

enhancement github_actions Pull requests that update GitHub Actions code helper-bots Helper bots, release management automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants