Skip to content

Commit f94c65a

Browse files
authored
docs: clarify rate-limit-safe dispatcher setup (#344)
1 parent 1566ad6 commit f94c65a

1 file changed

Lines changed: 50 additions & 14 deletions

File tree

docs/target-dispatcher.md

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ opened issues get stronger duplicate and adjacent-report context. Set repository
3434
variable `CLAWSWEEPER_RELATED_GITHUB_SEARCH=0` on `openclaw/clawsweeper` to turn
3535
that enrichment off without editing the target dispatcher.
3636

37+
Before enabling the workflow:
38+
39+
1. Install the `clawsweeper` GitHub App on the target repository.
40+
2. Add the App private key as the target repository Actions secret
41+
`CLAWSWEEPER_APP_PRIVATE_KEY`.
42+
3. Install exactly one target dispatcher. Do not add separate comment, spam, and
43+
generic-activity dispatch workflows that forward the same event twice.
44+
4. Keep the target write token limited to the comment acknowledgement path.
45+
Issue/PR review dispatch only needs the ClawSweeper installation token.
46+
3747
```yaml
3848
name: ClawSweeper Dispatch
3949

@@ -76,9 +86,27 @@ jobs:
7686
repositories: clawsweeper
7787
permission-contents: write
7888

89+
- name: Pre-filter ClawSweeper comment
90+
id: comment_filter
91+
if: ${{ github.event_name == 'issue_comment' }}
92+
env:
93+
COMMENT_BODY: ${{ github.event.comment.body }}
94+
run: |
95+
set -euo pipefail
96+
if grep -Eiq '(^|[[:space:]])@(clawsweeper|openclaw-clawsweeper)\b(\[bot\])?|(^|[[:space:]])/(clawsweeper|review|re-review|rerun[ -]?review|status|explain|fix|build|implement|create[ -]?pr|fix[ -]?issue|autofix|auto[ -]?fix|automerge|auto[ -]?merge|approve|stop|autoclose)\b' <<< "$COMMENT_BODY"; then
97+
echo "is_command=true" >> "$GITHUB_OUTPUT"
98+
else
99+
echo "is_command=false" >> "$GITHUB_OUTPUT"
100+
fi
101+
79102
- name: Create target comment token
80103
id: target_token
81-
if: ${{ github.event_name == 'issue_comment' && env.HAS_CLAWSWEEPER_APP_PRIVATE_KEY == 'true' }}
104+
if: >-
105+
${{
106+
github.event_name == 'issue_comment' &&
107+
steps.comment_filter.outputs.is_command == 'true' &&
108+
env.HAS_CLAWSWEEPER_APP_PRIVATE_KEY == 'true'
109+
}}
82110
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
83111
with:
84112
client-id: ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
@@ -115,7 +143,11 @@ jobs:
115143
--input - <<< "$payload"
116144
117145
- name: Acknowledge and dispatch ClawSweeper comment
118-
if: ${{ github.event_name == 'issue_comment' }}
146+
if: >-
147+
${{
148+
github.event_name == 'issue_comment' &&
149+
steps.comment_filter.outputs.is_command == 'true'
150+
}}
119151
env:
120152
DISPATCH_TOKEN: ${{ steps.token.outputs.token }}
121153
TARGET_TOKEN: ${{ steps.target_token.outputs.token }}
@@ -136,10 +168,6 @@ jobs:
136168
echo "Ignoring ClawSweeper proof-nudge comment."
137169
exit 0
138170
fi
139-
if ! grep -Eiq '(^|[[:space:]])@clawsweeper\b|(^|[[:space:]])/(clawsweeper|review|re-review|rerun[ -]?review|status|explain|fix|build|implement|create[ -]?pr|fix[ -]?issue|autofix|auto[ -]?fix|automerge|auto[ -]?merge|approve|stop|autoclose)\b' "$body_file"; then
140-
echo "No ClawSweeper command found in comment."
141-
exit 0
142-
fi
143171
if [ -n "$TARGET_TOKEN" ]; then
144172
GH_TOKEN="$TARGET_TOKEN" gh api -X POST \
145173
-H "Accept: application/vnd.github+json" \
@@ -237,9 +265,8 @@ Install one dispatcher workflow per target repository. Keep the event fanout
237265
inside that workflow; do not add separate comment, spam, or generic-activity
238266
dispatch workflows in the target repository.
239267

240-
The snippet below is only the trigger, permission, and concurrency fragment.
241-
It is not a complete workflow; use the full dispatcher example above as the
242-
copy-pasteable job definition.
268+
The full dispatcher example above is the copy-pasteable job definition. Its
269+
important rate-limit properties are:
243270

244271
```yaml
245272
name: ClawSweeper Dispatch
@@ -260,11 +287,20 @@ concurrency:
260287
cancel-in-progress: ${{ github.event.action == 'edited' || github.event.action == 'synchronize' || github.event.action == 'ready_for_review' }}
261288
```
262289

263-
The job should mint one short-lived `clawsweeper` App token scoped to
264-
`openclaw/clawsweeper`, then send one `clawsweeper_item` or
265-
`clawsweeper_comment` `repository_dispatch`. For comments, check the command
266-
syntax before minting a target write token. Do not use a PAT or dispatch the
267-
same comment through both the exact router and a second spam/generic workflow.
290+
The job mints one short-lived `clawsweeper` App token scoped to
291+
`openclaw/clawsweeper`, then sends one `clawsweeper_item` or
292+
`clawsweeper_comment` `repository_dispatch`. For comments, the
293+
`Pre-filter ClawSweeper comment` step runs before the target write token is
294+
minted, so ordinary comments consume neither a target installation token nor a
295+
dispatch. Do not use a PAT or dispatch the same comment through both the exact
296+
router and a second spam/generic workflow.
297+
298+
To verify a target installation, open a pull request or issue and confirm one
299+
`ClawSweeper Dispatch` run. Add a maintainer comment containing `@clawsweeper`
300+
or a supported slash command and confirm one `clawsweeper_comment` dispatch.
301+
An ordinary comment should produce no ClawSweeper comment dispatch and no
302+
target-token step. If the target app secret is absent, the workflow should
303+
finish with a notice rather than fall back to a maintainer PAT.
268304

269305
The ClawSweeper `github-activity` workflow performs spam-candidate
270306
classification in-process and only dispatches the scanner for an accepted

0 commit comments

Comments
 (0)