@@ -472,28 +472,137 @@ maintainer. It analyzes the PR's title, description, code changes, and
472472linked issues, then posts a properly formatted changelog entry as a
473473comment on the PR.
474474
475+ The bot uses a two-workflow pattern to support PRs from forks. The first
476+ workflow is triggered by ``pull_request_review ``: it checks whether the PR
477+ qualifies and uploads the PR number as an artifact, but requires no
478+ secrets. The second workflow executes via ``workflow_run `` once the first
479+ completes: it runs in the context of the base repository, has full access
480+ to secrets, and is the one that generates and posts the changelog comment.
481+
475482**Secrets **
476483
477484- ``GEMINI_API_KEY `` (required): Google Gemini API key.
478485- ``OPENWISP_BOT_APP_ID `` (required): OpenWISP Bot GitHub App ID.
479486- ``OPENWISP_BOT_PRIVATE_KEY `` (required): OpenWISP Bot GitHub App private
480487 key.
481488
482- **Usage Example **
489+ **Setup for Other Repositories **
483490
484- To enable the changelog bot in any OpenWISP repository, create a workflow
485- file at ``.github/workflows/changelog-bot.yml ``:
491+ To enable the changelog bot in any OpenWISP repository, create the
492+ following two workflow files.
493+
494+ **1. Trigger ** (``.github/workflows/bot-changelog-trigger.yml ``)
495+
496+ This workflow fires on PR approval, checks if the PR is noteworthy, and
497+ uploads the PR number as an artifact for the runner to pick up.
486498
487499.. code-block :: yaml
488500
489- name : Changelog Bot
501+ name : Changelog Bot Trigger
502+
490503 on :
491504 pull_request_review :
492505 types : [submitted]
506+
507+ jobs :
508+ check :
509+ if : |
510+ github.event.review.state == 'approved' &&
511+ (github.event.review.author_association == 'OWNER' ||
512+ github.event.review.author_association == 'MEMBER' ||
513+ github.event.review.author_association == 'COLLABORATOR')
514+ runs-on : ubuntu-latest
515+ steps :
516+ - name : Check for noteworthy PR
517+ id : check
518+ env :
519+ PR_TITLE : ${{ github.event.pull_request.title }}
520+ run : |
521+ if echo "$PR_TITLE" | grep -qiE '^\[(feature|fix|change)\]'; then
522+ echo "has_noteworthy=true" >> $GITHUB_OUTPUT
523+ fi
524+
525+ - name : Save PR metadata
526+ if : steps.check.outputs.has_noteworthy == 'true'
527+ env :
528+ PR_NUMBER : ${{ github.event.pull_request.number }}
529+ run : echo "$PR_NUMBER" > pr_number
530+
531+ - name : Upload PR metadata
532+ if : steps.check.outputs.has_noteworthy == 'true'
533+ uses : actions/upload-artifact@v4
534+ with :
535+ name : changelog-metadata
536+ path : pr_number
537+
538+ **2. Runner ** (``.github/workflows/bot-changelog-runner.yml ``)
539+
540+ This workflow triggers after the trigger completes, downloads the
541+ artifact, and calls the reusable workflow with full secret access.
542+
543+ .. code-block :: yaml
544+
545+ name : Changelog Bot Runner
546+
547+ on :
548+ workflow_run :
549+ workflows : ["Changelog Bot Trigger"]
550+ types :
551+ - completed
552+
553+ permissions :
554+ actions : read
555+ contents : read
556+ pull-requests : write
557+ issues : write
558+
493559 jobs :
560+ fetch-metadata :
561+ runs-on : ubuntu-latest
562+ if : github.event.workflow_run.conclusion == 'success'
563+ outputs :
564+ pr_number : ${{ steps.metadata.outputs.pr_number }}
565+ steps :
566+ - name : Download PR metadata
567+ id : download
568+ uses : actions/download-artifact@v4
569+ with :
570+ name : changelog-metadata
571+ github-token : ${{ secrets.GITHUB_TOKEN }}
572+ run-id : ${{ github.event.workflow_run.id }}
573+ continue-on-error : true
574+
575+ - name : Read PR metadata
576+ if : steps.download.outcome == 'success'
577+ id : metadata
578+ run : |
579+ PR_NUMBER=$(cat pr_number)
580+ if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
581+ echo "::error::Invalid PR number: $PR_NUMBER"
582+ exit 1
583+ fi
584+ echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
585+
494586 changelog :
587+ needs : fetch-metadata
588+ if : needs.fetch-metadata.outputs.pr_number != ''
495589 uses : openwisp/openwisp-utils/.github/workflows/reusable-bot-changelog.yml@master
590+ with :
591+ pr_number : ${{ needs.fetch-metadata.outputs.pr_number }}
496592 secrets :
497593 GEMINI_API_KEY : ${{ secrets.GEMINI_API_KEY }}
498594 OPENWISP_BOT_APP_ID : ${{ secrets.OPENWISP_BOT_APP_ID }}
499595 OPENWISP_BOT_PRIVATE_KEY : ${{ secrets.OPENWISP_BOT_PRIVATE_KEY }}
596+
597+ .. note ::
598+
599+ The ``name `` field in the trigger workflow must be exactly ``Changelog
600+ Bot Trigger ``. The runner watches for this name via ``workflow_run ``.
601+ Changing it will silently break the connection between the two
602+ workflows.
603+
604+ Both ``bot-changelog-trigger.yml `` and ``bot-changelog-runner.yml ``
605+ must be committed to the **default branch ** of the repository. GitHub
606+ only activates ``workflow_run `` listeners that exist on the default
607+ branch: adding the runner only to a feature branch will cause it to
608+ silently do nothing.
0 commit comments