mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
ci: split issue dedupe into find and post jobs
In this commit, we give the issue dedupe workflow the same shape: one job finds the duplicate candidates, another posts the comment. The find job records the candidate issue numbers to a file, and the post job hands those numbers to comment-on-duplicates.sh, which already validates each number and renders the comment from a fixed template. Keeping detection and posting apart mirrors how the script is already factored, so the post job ends up a thin wrapper over it. We also drop the unused id-token permission and turn off checkout credential persistence while we're in here.
This commit is contained in:
parent
05c625275e
commit
d1ea8687c0
1 changed files with 148 additions and 7 deletions
155
.github/workflows/claude-dedupe-issues.yml
vendored
155
.github/workflows/claude-dedupe-issues.yml
vendored
|
|
@ -10,26 +10,167 @@ on:
|
|||
required: true
|
||||
type: string
|
||||
|
||||
# Default to read-only. The find-duplicates job reads untrusted issue text with
|
||||
# the model, so it must not hold a write token; post-comment takes issues: write
|
||||
# but runs no model and only shells out to scripts/comment-on-duplicates.sh,
|
||||
# which re-validates every issue number it is handed.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Serialize runs for the same issue so an `issues: opened` event and a
|
||||
# workflow_dispatch for the same number can't both read "no prior comment" and
|
||||
# double-post. Mirrors pr-severity.yml.
|
||||
concurrency:
|
||||
group: claude-dedupe-${{ github.event.issue.number || inputs.issue_number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
claude-dedupe-issues:
|
||||
find-duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
# Read-only: the model inspects the issue and searches for duplicates, then
|
||||
# records the candidate issue numbers to a file.
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
id-token: write
|
||||
issues: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run Claude Code slash command
|
||||
uses: anthropics/claude-code-action@v1
|
||||
- name: Find duplicate issues with Claude
|
||||
# Pinned to a full commit SHA rather than the mutable @v1 tag: this step
|
||||
# feeds untrusted issue text to the model with CLAUDE_CODE_OAUTH_TOKEN in
|
||||
# process, so a repointed tag would run attacker-controlled action code
|
||||
# with that secret present. Bump deliberately when updating.
|
||||
uses: anthropics/claude-code-action@ba0aafd4308cbba7165f9f2cdb0cfbed5a3c99ce # v1
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
|
||||
# Accept any issue author: this job holds only read scope and merely
|
||||
# records candidate issue numbers to a file; the comment is posted by
|
||||
# a separate, model-free job. "*" is safe ONLY while this job stays
|
||||
# read-only. Before granting this job a write token or a mutating tool
|
||||
# (a write-capable gh subcommand, a Bash mutation), replace "*" with
|
||||
# an explicit allowlist — otherwise any fork author's issue text would
|
||||
# steer a privileged model.
|
||||
allowed_non_write_users: "*"
|
||||
model: claude-haiku-4-5-20251001
|
||||
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
|
||||
# Read-only gh tools plus Write to record the result. No comment or
|
||||
# edit tools, and no access to the duplicate-comment script.
|
||||
claude_args: >-
|
||||
--allowedTools
|
||||
"Bash(gh issue view:*)"
|
||||
"Bash(gh search:*)"
|
||||
"Bash(gh issue list:*)"
|
||||
"Write"
|
||||
|
||||
prompt: |
|
||||
Find up to 3 likely duplicate issues for issue
|
||||
#${{ github.event.issue.number || inputs.issue_number }} in the
|
||||
${{ github.repository }} repository. Follow these steps precisely:
|
||||
|
||||
1. View the issue and check whether it (a) is closed, (b) does not
|
||||
need deduping (e.g. broad product feedback without a specific
|
||||
solution, or positive feedback), or (c) already has a duplicates
|
||||
comment. If any of these hold, write an empty `duplicates.txt`
|
||||
(create the file with no content) and stop.
|
||||
|
||||
2. Summarize the issue.
|
||||
|
||||
3. Search GitHub for duplicates of this issue using several diverse
|
||||
keyword searches and search approaches, based on the summary.
|
||||
|
||||
4. Filter out false positives that are likely not actually
|
||||
duplicates of the original issue. If no plausible duplicates
|
||||
remain, write an empty `duplicates.txt` and stop.
|
||||
|
||||
5. Otherwise, write the chosen duplicate issue numbers to a file
|
||||
named `duplicates.txt` in the current working directory: digits
|
||||
only, one issue number per line, at most 3 lines. Do not include
|
||||
`#`, URLs, or any other text.
|
||||
|
||||
Notes:
|
||||
- Use `gh` to interact with GitHub, not web fetch.
|
||||
- Do NOT use any tools beyond `gh issue view`, `gh search`,
|
||||
`gh issue list`, and `Write`. You do NOT post comments; a separate
|
||||
step does that from the file you write.
|
||||
- Make a todo list first.
|
||||
|
||||
- name: Upload duplicate candidates
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: dedupe-result
|
||||
path: duplicates.txt
|
||||
if-no-files-found: warn
|
||||
retention-days: 1
|
||||
|
||||
post-comment:
|
||||
runs-on: ubuntu-latest
|
||||
needs: find-duplicates
|
||||
timeout-minutes: 5
|
||||
# Write scope lives here, in a job that runs no model. The base issue number
|
||||
# comes from the trusted event payload, and comment-on-duplicates.sh
|
||||
# re-validates every candidate issue number before posting.
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download duplicate candidates
|
||||
uses: actions/download-artifact@v4
|
||||
# find-duplicates uploads with if-no-files-found: warn, so when the
|
||||
# model writes no file at all (timeout, refusal) no artifact exists and
|
||||
# download-artifact would otherwise hard-fail the job. Tolerate a
|
||||
# missing artifact so the no-op guard in the next step is reachable.
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: dedupe-result
|
||||
path: result
|
||||
|
||||
- name: Post duplicate comment
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
BASE_ISSUE: ${{ github.event.issue.number || inputs.issue_number }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Distinguish a genuine "no duplicates" verdict from a find-duplicates
|
||||
# run that produced no artifact at all (model crash/timeout, or a
|
||||
# tolerated missing-artifact download). The latter gets a warning so a
|
||||
# broken run doesn't read as a healthy no-op, mirroring the pr-severity
|
||||
# apply step; the present-but-empty case stays a silent no-op.
|
||||
if [[ ! -f result/duplicates.txt ]]; then
|
||||
echo "::warning::dedupe find-duplicates produced no result; nothing posted."
|
||||
exit 0
|
||||
fi
|
||||
if [[ ! -s result/duplicates.txt ]]; then
|
||||
echo "No duplicate candidates; nothing to post."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract up to 3 purely-numeric issue ids. comment-on-duplicates.sh
|
||||
# re-validates these and the base issue (numeric, existing, at most 3)
|
||||
# before posting.
|
||||
mapfile -t DUPS < <(grep -oE '^[0-9]+$' result/duplicates.txt | head -n 3)
|
||||
|
||||
if [[ ${#DUPS[@]} -eq 0 ]]; then
|
||||
echo "No valid numeric duplicate ids; nothing to post."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
./scripts/comment-on-duplicates.sh \
|
||||
--base-issue "$BASE_ISSUE" \
|
||||
--potential-duplicates "${DUPS[@]}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue