Skip to content

[ci:fix] Resolved issues with changelog bot for fork PRs#632

Merged
nemesifier merged 5 commits intoopenwisp:masterfrom
pushpitkamboj:fix/bot-changelog
Mar 25, 2026
Merged

[ci:fix] Resolved issues with changelog bot for fork PRs#632
nemesifier merged 5 commits intoopenwisp:masterfrom
pushpitkamboj:fix/bot-changelog

Conversation

@pushpitkamboj
Copy link
Copy Markdown
Contributor

@pushpitkamboj pushpitkamboj commented Mar 24, 2026

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #630

Description of Changes

The pull_request_review event blocks secret access for fork PRs. I Split the workflow into two steps workflow_run pattern (same approach used by the CI failure bot):

  • bot-changelog.yml — triggers on pull_request_review, checks approval + noteworthy title, uploads PR number as artifact. (No secrets needed here)
  • bot-changelog-run.yml — triggers on workflow_run, downloads artifact, calls the reusable workflow with full secret access.
  • reusable-bot-changelog.yml — updated to accept pr_number as input, uses refs/pull/NUMBER/head for checkout (works for forks), upgraded create-github-app-token to v2.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fb1ab7e9-a205-4033-820f-b019fd1ad1e4

📥 Commits

Reviewing files that changed from the base of the PR and between 6e9f200 and fac716c.

📒 Files selected for processing (2)
  • .github/workflows/bot-changelog-trigger.yml
  • docs/developer/reusable-github-utils.rst
📜 Recent 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.12 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.0.0
  • GitHub Check: Python==3.11 | django~=5.2.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.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (6)
📓 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: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.
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.
📚 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/bot-changelog-trigger.yml
📚 Learning: 2026-03-24T16:40:15.783Z
Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.

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
  • .github/workflows/bot-changelog-trigger.yml
📚 Learning: 2026-02-10T20:38:27.593Z
Learnt from: nemesifier
Repo: openwisp/openwisp-utils PR: 593
File: openwisp_utils/releaser/commitizen.py:5-9
Timestamp: 2026-02-10T20:38:27.593Z
Learning: In openwisp-utils commitizen implementation, the `_TITLE_ISSUE_EXTRACT_RE` pattern intentionally matches any space-preceded `#<number>` in commit titles without anchoring to the end. This is acceptable because 99.9% of such patterns are actual issue references, and rare edge cases (like version numbers) will be handled manually if they occur.

Applied to files:

  • docs/developer/reusable-github-utils.rst
📚 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/workflows/bot-changelog-trigger.yml
🔇 Additional comments (5)
.github/workflows/bot-changelog-trigger.yml (1)

1-36: LGTM! Well-structured trigger workflow for fork-safe changelog bot.

The implementation correctly addresses the fork PR secret access limitation:

  • Reviewer association check includes COLLABORATOR as intended per maintainer decision
  • PR title regex matches the strict [feature], [fix], [change] prefix requirements
  • Environment variables are properly used for PR_TITLE and PR_NUMBER to avoid shell injection
  • Artifact upload enables the runner workflow to retrieve the PR number with full secret access

Based on learnings: COLLABORATOR is intentionally allowed because the workflow is non-destructive and only posts a PR comment.

docs/developer/reusable-github-utils.rst (4)

471-476: Clear and accurate description of the fork-safe pattern.

The documentation correctly explains why two workflows are needed and how they interact to solve the secret access limitation for fork PRs.


490-532: Trigger workflow documentation is accurate and complete.

The example correctly demonstrates:

  • The reviewer association check including COLLABORATOR
  • The strict PR title prefix regex ^\[(feature|fix|change)\]
  • Safe shell variable handling via environment variables

Based on learnings: PR title prefixes are strictly limited to [feature], [fix], and [change] — scoped variants are not valid.


534-591: Runner workflow documentation is well-structured with proper security measures.

Key security features correctly documented:

  • Numeric validation of pr_number (^[0-9]+$) prevents injection
  • continue-on-error: true on artifact download gracefully handles non-noteworthy PRs where no artifact exists
  • Conditional execution ensures metadata is only processed on successful download

593-604: Excellent operational notes preventing common pitfalls.

These notes document critical GitHub Actions behaviors that could silently break the workflow:

  1. The workflow_run name coupling requirement
  2. The default branch requirement for workflow_run listeners

This guidance will save users significant debugging time.


📝 Walkthrough

Walkthrough

The PR refactors the changelog bot into a two-workflow, fork-safe pattern: a trigger workflow (.github/workflows/bot-changelog-trigger.yml) that runs on submitted PR reviews, enforces approval and reviewer association, checks PR title for a leading [feature|fix|change], and uploads the PR number as an artifact when noteworthy; a runner workflow (.github/workflows/bot-changelog-runner.yml) that reacts to the trigger's successful completion, downloads and validates the pr_number artifact, and conditionally invokes the reusable changelog workflow with the validated pr_number and required secrets. The reusable workflow now accepts a pr_number input and no longer performs title filtering. The original single-file bot workflow was replaced by an inline check job.

Sequence Diagram(s)

sequenceDiagram
    actor Reviewer
    participant GitHub as GitHub
    participant TriggerWF as Trigger Workflow<br/>(bot-changelog-trigger.yml)
    participant Artifact as Artifact Storage
    participant RunnerWF as Runner Workflow<br/>(bot-changelog-runner.yml)
    participant ReusableWF as Reusable Workflow<br/>(reusable-bot-changelog.yml)
    participant API as GitHub API

    Reviewer ->> GitHub: Submit PR review (approved)
    GitHub ->> TriggerWF: Trigger (pull_request_review event)
    TriggerWF ->> TriggerWF: Check reviewer association<br/>and parse PR title
    alt Title matches & approved
        TriggerWF ->> Artifact: Upload pr_number artifact<br/>(changelog-metadata)
    end
    GitHub ->> RunnerWF: Trigger (workflow_run event) on TriggerWF success
    RunnerWF ->> Artifact: Download changelog-metadata
    RunnerWF ->> RunnerWF: Validate pr_number is numeric
    alt pr_number valid & non-empty
        RunnerWF ->> ReusableWF: Invoke with pr_number input + secrets
        ReusableWF ->> API: Fetch PR, generate changelog
        ReusableWF ->> API: Update PR with changelog
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title '[ci:fix] Resolved issues with changelog bot for fork PRs' uses an unconventional 'ci:fix' format instead of the required '[fix]' or '[ci]' single-type prefix per repository guidelines. Change title to '[fix] Resolved issues with changelog bot for fork PRs' or '[ci] Resolved issues with changelog bot for fork PRs' to conform to the required '[type]' format specification.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The PR description covers linked issue reference (#630), change description, and documentation updates, but is missing manual testing confirmation and new/updated test cases per the checklist.
Linked Issues check ✅ Passed The code changes fully address the root cause: workflow split avoids secrets in pull_request_review [bot-changelog.yml] and delegates secret-requiring operations to workflow_run [bot-changelog-runner.yml], enabling fork PR support [#630].
Out of Scope Changes check ✅ Passed All changes directly support the fork PR secret access issue: workflow restructuring, pr_number input handling, and documentation updates align with the stated objective [#630].
Bug Fixes ✅ Passed The PR fixes the root cause of issue #630 by implementing a two-workflow pattern that avoids secret access in pull_request_review events, which lack secrets in fork PRs. No regression tests are included, but this is justified under the exception for GitHub Actions workflow fixes where programmatic testing is impractical.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot added enhancement github_actions Pull requests that update GitHub Actions code helper-bots Helper bots, release management automation labels Mar 24, 2026
@pushpitkamboj
Copy link
Copy Markdown
Contributor Author

@coderabbitai please review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 24, 2026

@pushpitkamboj Sure, I'll review the changes in this PR now!


🧠 Learnings used
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.

Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:12.455Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.

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.
✅ 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.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Mar 24, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented Mar 24, 2026

Coverage Status

coverage: 97.476%. remained the same
when pulling fac716c on pushpitkamboj:fix/bot-changelog
into 1c893d6 on openwisp:master.

@nemesifier nemesifier changed the title Fix/bot changelog [ci:fix] Resolved issues with changelog bot Mar 24, 2026
@nemesifier nemesifier changed the title [ci:fix] Resolved issues with changelog bot [ci:fix] Resolved issues with changelog bot for fork PRs Mar 24, 2026
@github-project-automation github-project-automation Bot moved this from To do (general) to In progress in OpenWISP Contributor's Board Mar 24, 2026
Copy link
Copy Markdown
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.

Good progress! The workflow_run split is the right approach, the PR number validation is solid, and the create-github-app-token@v2 upgrade aligns with the rest of the bots.

A few things to address before this is ready:

  1. Rename bot-changelog.yml to bot-changelog-trigger.yml and bot-changelog-run.yml to bot-changelog-runner.yml. The current names do not make the relationship or the trust boundary between the two workflows clear. The workflow_run listener name reference inside bot-changelog-runner.yml, the docs code blocks, and the .. note:: callout all need to be updated accordingly.

  2. The docs are missing a note that bot-changelog-runner.yml must exist on the default branch to be picked up at all. The workflow_run listener is only active when the file lives on the default branch: a contributor adding it only to a feature branch will see it silently do nothing and have no obvious way to debug why.

To speed things up I will push commits addressing these points directly. Please review them and make any adjustments you think are needed.

Copy link
Copy Markdown

@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 471-475: Replace the phrase "two-step `workflow_run` pattern" with
clearer wording such as "two-workflow pattern" and explicitly mention that the
first workflow is triggered by `pull_request_review` while the second executes
via `workflow_run`, so readers understand the first step is not a `workflow_run`
invocation; update the sentence containing the `workflow_run` and
`pull_request_review` terms to reflect this precise flow.
🪄 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: c1860b1b-ea72-4618-babe-e4c66ee1be57

📥 Commits

Reviewing files that changed from the base of the PR and between a12b2e7 and ed763cb.

📒 Files selected for processing (3)
  • .github/workflows/bot-changelog-runner.yml
  • .github/workflows/bot-changelog-trigger.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). (14)
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.0.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.0.0
🧰 Additional context used
🧠 Learnings (5)
📓 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: 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.
Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.
📚 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/bot-changelog-trigger.yml
  • docs/developer/reusable-github-utils.rst
  • .github/workflows/bot-changelog-runner.yml
📚 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/workflows/bot-changelog-trigger.yml
  • docs/developer/reusable-github-utils.rst
  • .github/workflows/bot-changelog-runner.yml
📚 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/workflows/bot-changelog-trigger.yml
  • .github/workflows/bot-changelog-runner.yml
📚 Learning: 2026-03-24T16:40:15.783Z
Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.

Applied to files:

  • docs/developer/reusable-github-utils.rst
  • .github/workflows/bot-changelog-runner.yml
🔇 Additional comments (2)
.github/workflows/bot-changelog-trigger.yml (1)

1-34: Good split: trigger stays secret-free and deterministic.

This workflow correctly gates on approved maintainer reviews, enforces the intended title prefix check, and passes only PR metadata via artifact for the runner.

Based on learnings: COLLABORATOR is intentionally allowed for this non-destructive bot workflow, and the ^\[(feature|fix|change)\] prefix check is intentionally strict.

.github/workflows/bot-changelog-runner.yml (1)

1-51: Runner workflow wiring looks solid.

workflow_run filtering, artifact retrieval by run-id, numeric pr_number validation, and downstream reusable workflow invocation are all correctly connected.

Comment thread docs/developer/reusable-github-utils.rst Outdated
Copy link
Copy Markdown

@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: 2

🤖 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/bot-changelog-trigger.yml:
- Around line 25-27: In the "Save PR metadata" workflow step, stop interpolating
`${{ github.event.pull_request.number }}` directly in the run command and
instead expose the PR number as an environment variable (following the same
pattern used for PR_TITLE) and then echo that env var in the run step; update
the step named "Save PR metadata" so its environment contains the PR number and
change the run to write the environment variable (e.g., PR_NUMBER) into the
pr_number file.

In `@docs/developer/reusable-github-utils.rst`:
- Line 523: The run step that writes the PR number to the pr_number file uses
direct interpolation of ${{ github.event.pull_request.number }} which could lead
to shell injection; instead set an environment variable (e.g., PR_NUMBER) from
github.event.pull_request.number in the job/step env and then echo the variable
quoted into the file (echo "$PR_NUMBER" > pr_number) so the value is treated as
data, not parsed by the shell; update the step that creates pr_number to use the
env variable and a quoted echo.
🪄 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: a528ecfa-30d1-44f1-954c-4bf8f72a865b

📥 Commits

Reviewing files that changed from the base of the PR and between ed763cb and 6e9f200.

📒 Files selected for processing (3)
  • .github/workflows/bot-changelog-runner.yml
  • .github/workflows/bot-changelog-trigger.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). (14)
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.0.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.10 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.11 | 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.10 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.0.0
🧰 Additional context used
🧠 Learnings (5)
📓 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: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.
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.
📚 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/bot-changelog-trigger.yml
  • .github/workflows/bot-changelog-runner.yml
📚 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
  • .github/workflows/bot-changelog-trigger.yml
  • .github/workflows/bot-changelog-runner.yml
📚 Learning: 2026-03-24T16:40:15.783Z
Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.

Applied to files:

  • docs/developer/reusable-github-utils.rst
  • .github/workflows/bot-changelog-runner.yml
📚 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:

  • docs/developer/reusable-github-utils.rst
  • .github/workflows/bot-changelog-trigger.yml
  • .github/workflows/bot-changelog-runner.yml
🔇 Additional comments (8)
docs/developer/reusable-github-utils.rst (2)

471-476: Wording has been corrected.

The documentation now correctly describes this as a "two-workflow pattern" with the first workflow triggered by pull_request_review and the second executing via workflow_run. This is accurate and addresses the prior feedback.


591-602: Excellent documentation of critical coupling requirements.

These notes about the strict name coupling between trigger and runner workflows, and the requirement for both files to exist on the default branch, are essential for users setting this up. This will prevent common pitfalls when adopting the two-workflow pattern.

.github/workflows/bot-changelog-trigger.yml (2)

1-14: Workflow structure correctly implements the fork-safe trigger pattern.

The workflow correctly:

  • Triggers on pull_request_review: submitted which doesn't require secrets
  • Gates on approved state with allowed author associations (OWNER, MEMBER, COLLABORATOR)
  • Has no permissions block, which is appropriate since this workflow doesn't need elevated permissions

Based on learnings, allowing COLLABORATOR is intentional since the workflow is non-destructive.


16-23: Title prefix check matches the documented convention.

The case-insensitive regex ^\[(feature|fix|change)\] correctly enforces the strict prefix requirement. Based on learnings, scoped variants like [feature/bots] are intentionally not matched.

.github/workflows/bot-changelog-runner.yml (4)

3-7: Workflow trigger correctly watches for the trigger workflow by exact name.

The workflows: ["Changelog Bot Trigger"] matches the name: in bot-changelog-trigger.yml exactly. This coupling is critical and documented in the RST file.


9-13: Permissions are appropriately scoped.

The permissions block correctly includes:

  • actions: read - needed for downloading artifacts from the triggering run
  • contents: read - needed for checkout in the reusable workflow
  • pull-requests: write and issues: write - needed for posting comments

Based on learnings, the custom GitHub App token used by the reusable workflow is not subject to this permissions block, so actions: read won't interfere with any App-authenticated API calls.


22-40: Robust artifact handling with proper validation.

The implementation correctly:

  • Uses continue-on-error: true on download to gracefully handle cases where the trigger didn't upload an artifact (non-noteworthy PRs)
  • Validates PR number is strictly numeric with ^[0-9]+$ regex before using it
  • Only proceeds if download succeeded via steps.download.outcome == 'success'

This prevents both silent failures and potential injection attacks.


42-51: Reusable workflow invocation matches expected interface.

The call to reusable-bot-changelog.yml correctly passes:

  • pr_number input (string type matches the reusable workflow's declaration)
  • All three required secrets: GEMINI_API_KEY, OPENWISP_BOT_APP_ID, OPENWISP_BOT_PRIVATE_KEY

The conditional if: needs.fetch-metadata.outputs.pr_number != '' ensures the reusable workflow only runs when a valid PR number was extracted.

Comment thread .github/workflows/bot-changelog-trigger.yml Outdated
Comment thread docs/developer/reusable-github-utils.rst Outdated
@pushpitkamboj
Copy link
Copy Markdown
Contributor Author

@coderabbitai review the changes, and approve if everything aligns

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Let me gather the file contents before reviewing.


🏁 Script executed:

#!/bin/bash
echo "=== bot-changelog-trigger.yml ==="
cat .github/workflows/bot-changelog-trigger.yml

echo ""
echo "=== bot-changelog-runner.yml ==="
cat .github/workflows/bot-changelog-runner.yml

echo ""
echo "=== bot-changelog.yml ==="
cat .github/workflows/bot-changelog.yml

echo ""
echo "=== reusable-bot-changelog.yml ==="
cat .github/workflows/reusable-bot-changelog.yml

echo ""
echo "=== docs excerpt ==="
cat docs/developer/reusable-github-utils.rst

Length of output: 26134


@pushpitkamboj I've reviewed all the changed files. Here's a summary of my findings:

bot-changelog-trigger.yml

  • Correctly gates execution on approved reviews from OWNER, MEMBER, or COLLABORATOR (consistent with established policy).
  • Uses the correct case-insensitive regex ^\[(feature|fix|change)\] for PR title matching.
  • Uses env: for PR_TITLE and PR_NUMBER — no expression injection risk.
  • Uploads only a numeric PR number as an artifact. No secrets required — fork-safe by design.

bot-changelog-runner.yml

  • Correctly watches for the exact workflow name "Changelog Bot Trigger" via workflow_run.
  • continue-on-error: true on the download step ensures the workflow doesn't fail for non-noteworthy PRs (where no artifact is produced).
  • PR number is validated as strictly numeric (^[0-9]+$) before any use.
  • changelog job is guarded by if: needs.fetch-metadata.outputs.pr_number != '' — correctly skips when nothing was uploaded.
  • Permissions (actions: read, contents: read, pull-requests: write, issues: write) are appropriate. The App token used in the reusable workflow is not subject to the permissions block (per established learnings — no concern here).

reusable-bot-changelog.yml

  • Clean addition of pr_number as a required string input.
  • Checkout using refs/pull/${{ inputs.pr_number }}/head correctly handles fork PRs.
  • Upgrade of actions/create-github-app-token from v1v2 is a safe improvement.
  • All approval/noteworthy gating correctly delegated to the trigger workflow.

Documentation

  • The setup guide exactly mirrors the actual workflow files — no discrepancy.
  • Important caveats (workflow name coupling, default-branch requirement for workflow_run) are clearly documented.

Everything aligns. Approving the PR.

[approve]


🧠 Learnings used
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.

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.

Learnt from: stktyagi
Repo: openwisp/openwisp-utils PR: 631
File: .github/workflows/bot-ci-failure.yml:71-74
Timestamp: 2026-03-24T16:40:15.783Z
Learning: In openwisp/openwisp-utils reusable-bot-ci-failure.yml, the auto-retry step uses a custom GitHub App token (generated from APP_ID and PRIVATE_KEY secrets) passed to the gh CLI via the GH_TOKEN environment variable. This token is NOT subject to the workflow's `permissions` block (which only restricts GITHUB_TOKEN). Therefore, having `actions: read` in the reusable workflow's permissions block does NOT break the auto-retry `gh api -X POST` call — it authenticates with the App's own permissions. Do not flag this as a permissions issue.

@pushpitkamboj
Copy link
Copy Markdown
Contributor Author

looks good to me, now the naming of files give better clarity.

@nemesifier nemesifier merged commit 6b306a9 into openwisp:master Mar 25, 2026
33 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in OpenWISP Contributor's Board Mar 25, 2026
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

Development

Successfully merging this pull request may close these issues.

[bug] Changelog bot fails on fork PRs due to missing secrets in pull_request_review event

3 participants