Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions .github/workflows/qwen-issue-followup-bot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
name: 'Qwen Issue Follow-up Bot'

on:
issues:
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
types:
- 'opened'
schedule:
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
- cron: '0 */6 * * *'
workflow_dispatch:
inputs:
issue_number:
description: 'Optional issue number. Leave empty to let Qwen select scheduled candidates.'
required: false
type: 'string'
dry_run:
description: 'Print planned actions without modifying issues.'
required: false
default: true
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
type: 'boolean'
scheduled_limit:
description: 'Maximum number of candidate issues to consider during scheduled follow-up.'
required: false
default: '10'
type: 'string'

concurrency:
group: '${{ github.workflow }}-${{ github.event.issue.number || github.event.inputs.issue_number || github.event_name }}'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
cancel-in-progress: false

defaults:
run:
shell: 'bash'

permissions:
contents: 'read'
id-token: 'write'
issues: 'write'

env:
BOT_GITHUB_TOKEN: '${{ secrets.QWEN_CODE_BOT_TOKEN || secrets.CI_BOT_PAT }}'

jobs:
follow-up-issues:
timeout-minutes: 15
if: |-
${{
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
github.repository == 'QwenLM/qwen-code' &&
(github.event_name == 'workflow_dispatch' || vars.QWEN_ISSUE_FOLLOWUP_BOT_ENABLED == 'true') &&
(github.event_name != 'issues' || github.event.issue.pull_request == null)
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
}}
runs-on: 'ubuntu-latest'
steps:
- name: 'Run Qwen issue follow-up'
uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2'
env:
GITHUB_TOKEN: '${{ env.BOT_GITHUB_TOKEN }}'
REPOSITORY: '${{ github.repository }}'
EVENT_NAME: '${{ github.event_name }}'
ISSUE_NUMBER: '${{ github.event.issue.number || github.event.inputs.issue_number }}'
DRY_RUN: "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' && 'true' || 'false' }}"
SCHEDULED_LIMIT: "${{ github.event.inputs.scheduled_limit || '10' }}"
with:
OPENAI_API_KEY: '${{ secrets.OPENAI_API_KEY }}'
OPENAI_BASE_URL: '${{ secrets.OPENAI_BASE_URL }}'
OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}'
settings_json: |-
{
"maxSessionTurns": 20,
"coreTools": [
"run_shell_command",
"write_file"
],
"sandbox": false
}
prompt: |-
## Role
Comment thread
yiliang114 marked this conversation as resolved.
Resolved

Comment thread
yiliang114 marked this conversation as resolved.
Resolved
You are the Qwen Code issue follow-up bot. Use `gh` commands to
inspect GitHub issues and provide early, conservative community
follow-up.

## Runtime Context

- Repository: `${{ github.repository }}`
- Event name: `${{ github.event_name }}`
- Issue number, when the event targets one issue: `${{ github.event.issue.number || github.event.inputs.issue_number }}`
- Scheduled candidate limit: `${{ github.event.inputs.scheduled_limit || '10' }}`
- Dry run: `${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' && 'true' || 'false' }}`

## Scope

If `ISSUE_NUMBER` is set, inspect and process only that issue. This
is the normal path for a newly opened issue. Do not scan or process
unrelated recent issues in this mode.

If `ISSUE_NUMBER` is empty, this is a scheduled/manual batch run.
Find and process at most `SCHEDULED_LIMIT` open issues that are
likely to need early follow-up. Prefer unassigned issues without
maintainer/contributor follow-up, without bot marker comments, and
without clear evidence that maintainers have already handled them.
Do not process a larger backlog just because more issues exist.
Start from GitHub searches that prefilter already-handled issues,
such as `is:open is:issue no:assignee`, excluding obvious waiting,
in-progress, review, stale, and blocked statuses when labels exist.
Then inspect comments and marker comments before acting.

## Safety Rules

- Before acting on an issue, inspect its current state with
`gh issue view "$ISSUE_NUMBER" --repo "${{ github.repository }}" --json number,title,body,state,labels,assignees,comments,url`
when `$ISSUE_NUMBER` is provided. In scheduled batch mode, replace
`$ISSUE_NUMBER` with the selected issue number.
- Skip closed issues, pull requests, issues assigned to anyone, and
issues that already appear to be handled by maintainers.
- Treat comments from repository collaborators, members, owners, or
the Qwen bot itself as existing follow-up. Skip those issues unless
you only need to update one of your own existing marker comments.
- Skip issues that already have one of these marker comments unless
there is a clear reason to update the existing marker comment:
- `<!-- qwen-issue-bot:invalid -->`
- `<!-- qwen-issue-bot:needs-info -->`
- `<!-- qwen-issue-bot:related -->`
- Do not assign issues to people in this phase.
- Use only labels that already exist in the repository.
- If `DRY_RUN` is `true`, do not modify GitHub. Print the planned
actions as JSON instead.
- Never create duplicate marker comments. Update an existing marker
comment only when its content is meaningfully stale or incomplete.

## Decisions You Can Make

For each selected issue, focus on these actions:

- Search for related existing issues, including closed issues. Use
the issue title, error codes, command names, important stack/error
text, affected feature, and labels as search terms.
- If there are strong related issues, especially ones with maintainer
replies or known resolution/workaround, reply with a concise
`related` marker comment that links those issues. Do not claim the
issue is a duplicate unless the evidence is clear.
- Add only a small number of high-confidence labels. Prefer labels
that help maintainers route the issue, such as one `type/*`, one
`category/*`, one or two `scope/*`, or a relevant `status/*`.
- Ask for missing information when a plausible report lacks facts
needed for triage, such as reproduction steps, environment,
expected/actual behavior, logs, screenshots, or configuration.
- Close only clearly invalid test, placeholder, spam, or otherwise
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
non-actionable issues. Use `not_planned`.

Example: if a new issue reports a `401` authentication failure and
previous `401` issues already contain maintainer guidance or a known
workaround, link those issues in a `related` marker comment and add
the most relevant authentication/status labels.

## Comment Markers

Put one of these hidden markers at the beginning of bot comments:

- Invalid issue: `<!-- qwen-issue-bot:invalid -->`
- Needs information: `<!-- qwen-issue-bot:needs-info -->`
- Related issues: `<!-- qwen-issue-bot:related -->`

## Execution Guidance

- Run `gh label list --repo "${{ github.repository }}" --limit 200` before
selecting labels.
- Use `gh issue edit` to add or remove labels.
- Use `gh issue comment` to create comments.
- Use `gh api --method PATCH /repos/${{ github.repository }}/issues/comments/COMMENT_ID`
to update an existing marker comment.
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
- After you successfully add labels, add or update a marker comment,
or close an issue, remove `status/needs-triage` if present.
- Keep comments concise and neutral. Ask for facts; do not imply a
root cause unless the issue clearly proves it.

## Output

End with one JSON object containing `processed`, `skipped`,
`dryRun`, and `actions`.
7 changes: 2 additions & 5 deletions .github/workflows/qwen-scheduled-issue-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,13 @@ jobs:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
GITHUB_REPOSITORY: '${{ github.repository }}'
run: |-
echo "🔍 Finding issues without labels..."
NO_LABEL_ISSUES=$(gh issue list --repo ${{ github.repository }} --search "is:open is:issue no:label" --json number,title,body)

echo '🔍 Finding issues without labels...'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
NO_LABEL_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue no:label' --json number,title,body)"

echo '🏷️ Finding issues that need triage...'
NEED_TRIAGE_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search "is:open is:issue label:\"status/need-triage\"" --limit 1000 --json number,title,body)"
--search "is:open is:issue label:\"status/needs-triage\"" --limit 1000 --json number,title,body)"

echo '🔄 Merging and deduplicating issues...'
ISSUES="$(echo "${NO_LABEL_ISSUES}" "${NEED_TRIAGE_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
Expand Down Expand Up @@ -101,7 +98,7 @@ jobs:
10. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
- Anything more than 6 versions older than the most recent should add the status/need-retesting label
11. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label
- After applying appropriate labels to an issue, remove the "status/need-triage" label if present: `gh issue edit ISSUE_NUMBER --repo ${{ github.repository }} --remove-label "status/need-triage"`
- After applying appropriate labels to an issue, remove the "status/needs-triage" label if present: `gh issue edit ISSUE_NUMBER --repo ${{ github.repository }} --remove-label "status/needs-triage"`
- Execute one `gh issue edit` command per issue, wait for success before proceeding to the next
Process each issue sequentially and confirm each labeling operation before moving to the next issue.

Expand Down
Loading