mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-24 20:02:58 +02:00
chore: workflow cleanup
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
name: Duplicate Issue Check
|
name: Issue Compliance Check
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
@@ -12,7 +12,7 @@ env:
|
|||||||
MODEL: z-ai/glm-5.1
|
MODEL: z-ai/glm-5.1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-duplicates:
|
check-compliance:
|
||||||
if: github.repository == 'zhom/donutbrowser' && github.event.action == 'opened'
|
if: github.repository == 'zhom/donutbrowser' && github.event.action == 'opened'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -21,29 +21,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Gather context
|
- name: Gather context
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
||||||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||||
run: |
|
run: |
|
||||||
printf '%s' "$ISSUE_TITLE" > /tmp/issue-title.txt
|
printf '%s' "$ISSUE_TITLE" > /tmp/issue-title.txt
|
||||||
printf '%s' "${ISSUE_BODY:-}" > /tmp/issue-body.txt
|
printf '%s' "${ISSUE_BODY:-}" > /tmp/issue-body.txt
|
||||||
|
|
||||||
# Pull up to 150 open/closed issues for the LLM to compare against.
|
|
||||||
# Exclude the issue under inspection and any PRs (gh issue list does
|
|
||||||
# this naturally).
|
|
||||||
gh issue list \
|
|
||||||
--repo "$GITHUB_REPOSITORY" \
|
|
||||||
--state all \
|
|
||||||
--limit 150 \
|
|
||||||
--json number,title,state,body \
|
|
||||||
--jq "[.[] | select(.number != $ISSUE_NUMBER) | {number, title, state, body: (.body[:400] // \"\")}]" \
|
|
||||||
> /tmp/existing-issues.json
|
|
||||||
|
|
||||||
- name: Build prompt
|
- name: Build prompt
|
||||||
run: |
|
run: |
|
||||||
cat > /tmp/system.txt <<'PROMPT'
|
cat > /tmp/system.txt <<'PROMPT'
|
||||||
You are reviewing a new GitHub issue for two things — template compliance and possible duplicates. Return ONLY a single JSON object, no prose, no markdown fences.
|
You are reviewing a new GitHub issue for template compliance. Return ONLY a single JSON object, no prose, no markdown fences.
|
||||||
|
|
||||||
Project: Donut Browser. There are three valid templates:
|
Project: Donut Browser. There are three valid templates:
|
||||||
- Bug Report (Description + Operating System + Donut Browser version + Which browser is affected + Steps to reproduce + Error logs/screenshots fields)
|
- Bug Report (Description + Operating System + Donut Browser version + Which browser is affected + Steps to reproduce + Error logs/screenshots fields)
|
||||||
@@ -59,22 +46,14 @@ jobs:
|
|||||||
|
|
||||||
Do NOT flag for missing optional fields, missing screenshots, short titles, or stylistic issues. Be conservative.
|
Do NOT flag for missing optional fields, missing screenshots, short titles, or stylistic issues. Be conservative.
|
||||||
|
|
||||||
## Duplicates — flag candidates ONLY when at least one of these is true
|
|
||||||
- Same error message, exception, or symptom
|
|
||||||
- Same feature being requested
|
|
||||||
- Same root cause area (e.g. "proxy disconnects on Camoufox/Windows")
|
|
||||||
|
|
||||||
Prefer false negatives over false positives. Two issues about Wayfern are not duplicates if they are about different features.
|
|
||||||
|
|
||||||
## Output schema
|
## Output schema
|
||||||
{
|
{
|
||||||
"is_compliant": true | false,
|
"is_compliant": true | false,
|
||||||
"non_compliance_reasons": ["short bullet", ...],
|
"non_compliance_reasons": ["short bullet", ...]
|
||||||
"duplicates": [{"number": 123, "reason": "short reason"}]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Empty arrays are fine. If there is nothing to flag, return:
|
If there is nothing to flag, return:
|
||||||
{"is_compliant": true, "non_compliance_reasons": [], "duplicates": []}
|
{"is_compliant": true, "non_compliance_reasons": []}
|
||||||
PROMPT
|
PROMPT
|
||||||
|
|
||||||
- name: Call OpenRouter
|
- name: Call OpenRouter
|
||||||
@@ -86,13 +65,12 @@ jobs:
|
|||||||
--rawfile system_prompt /tmp/system.txt \
|
--rawfile system_prompt /tmp/system.txt \
|
||||||
--rawfile title /tmp/issue-title.txt \
|
--rawfile title /tmp/issue-title.txt \
|
||||||
--rawfile body /tmp/issue-body.txt \
|
--rawfile body /tmp/issue-body.txt \
|
||||||
--rawfile existing /tmp/existing-issues.json \
|
|
||||||
'{
|
'{
|
||||||
model: $model,
|
model: $model,
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "system", content: $system_prompt },
|
{ role: "system", content: $system_prompt },
|
||||||
{ role: "user",
|
{ role: "user",
|
||||||
content: ("New issue title: " + $title + "\n\nNew issue body:\n" + $body + "\n\nExisting issues (JSON array):\n" + $existing) }
|
content: ("New issue title: " + $title + "\n\nNew issue body:\n" + $body) }
|
||||||
],
|
],
|
||||||
response_format: { type: "json_object" }
|
response_format: { type: "json_object" }
|
||||||
}')
|
}')
|
||||||
@@ -108,9 +86,9 @@ jobs:
|
|||||||
# to a noop result so the workflow doesn't fail the issue author's run.
|
# to a noop result so the workflow doesn't fail the issue author's run.
|
||||||
sed -E 's/^```(json)?$//; s/```$//' /tmp/raw.txt > /tmp/result.json
|
sed -E 's/^```(json)?$//; s/```$//' /tmp/raw.txt > /tmp/result.json
|
||||||
if ! jq -e . /tmp/result.json >/dev/null 2>&1; then
|
if ! jq -e . /tmp/result.json >/dev/null 2>&1; then
|
||||||
echo "::warning::Model returned non-JSON; treating as no-op"
|
echo "::warning::Model returned non-JSON; treating as compliant"
|
||||||
cat /tmp/raw.txt
|
cat /tmp/raw.txt
|
||||||
echo '{"is_compliant": true, "non_compliance_reasons": [], "duplicates": []}' > /tmp/result.json
|
echo '{"is_compliant": true, "non_compliance_reasons": []}' > /tmp/result.json
|
||||||
fi
|
fi
|
||||||
echo "Result:"
|
echo "Result:"
|
||||||
cat /tmp/result.json
|
cat /tmp/result.json
|
||||||
@@ -122,7 +100,6 @@ jobs:
|
|||||||
r = json.load(open('/tmp/result.json'))
|
r = json.load(open('/tmp/result.json'))
|
||||||
compliant = bool(r.get('is_compliant', True))
|
compliant = bool(r.get('is_compliant', True))
|
||||||
reasons = r.get('non_compliance_reasons') or []
|
reasons = r.get('non_compliance_reasons') or []
|
||||||
dups = r.get('duplicates') or []
|
|
||||||
|
|
||||||
parts = []
|
parts = []
|
||||||
if not compliant:
|
if not compliant:
|
||||||
@@ -134,25 +111,11 @@ jobs:
|
|||||||
parts.append(f'- {reason}')
|
parts.append(f'- {reason}')
|
||||||
parts.append('')
|
parts.append('')
|
||||||
parts.append('Please edit this issue to address the above within **24 hours**, or it will be automatically closed.')
|
parts.append('Please edit this issue to address the above within **24 hours**, or it will be automatically closed.')
|
||||||
|
|
||||||
if dups:
|
|
||||||
if parts:
|
|
||||||
parts.append('')
|
|
||||||
parts.append('---')
|
|
||||||
parts.append('This issue might duplicate existing reports. Please check:')
|
|
||||||
for d in dups:
|
|
||||||
num = d.get('number')
|
|
||||||
reason = d.get('reason', '').strip()
|
|
||||||
if num:
|
|
||||||
parts.append(f'- #{num}{" — " + reason if reason else ""}')
|
|
||||||
|
|
||||||
if not compliant:
|
|
||||||
parts.append('')
|
parts.append('')
|
||||||
parts.append('If you believe this was flagged incorrectly, please let a maintainer know.')
|
parts.append('If you believe this was flagged incorrectly, please let a maintainer know.')
|
||||||
|
|
||||||
comment = '\n'.join(parts).strip()
|
comment = '\n'.join(parts).strip()
|
||||||
open('/tmp/comment.md', 'w').write(comment)
|
open('/tmp/comment.md', 'w').write(comment)
|
||||||
# Expose flags for downstream steps via GITHUB_OUTPUT-style write.
|
|
||||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||||
fh.write(f'has_comment={"true" if comment else "false"}\n')
|
fh.write(f'has_comment={"true" if comment else "false"}\n')
|
||||||
fh.write(f'non_compliant={"true" if not compliant else "false"}\n')
|
fh.write(f'non_compliant={"true" if not compliant else "false"}\n')
|
||||||
@@ -102,12 +102,14 @@ jobs:
|
|||||||
its API, MCP server, and the bundled `donut-sync` self-hosted server.
|
its API, MCP server, and the bundled `donut-sync` self-hosted server.
|
||||||
- **Wayfern** — a Chromium fork maintained by zhom (the same maintainer). Wayfern
|
- **Wayfern** — a Chromium fork maintained by zhom (the same maintainer). Wayfern
|
||||||
bugs are in-scope here unless they are obviously upstream Chromium issues.
|
bugs are in-scope here unless they are obviously upstream Chromium issues.
|
||||||
- **Camoufox** — a Firefox fork by daijro. The maintainer of THIS repo does NOT
|
- **Camoufox** — a Firefox fork by daijro, used by Donut but maintained in a
|
||||||
contribute to Camoufox and CANNOT fix bugs in it.
|
separate repository. Bugs about Camoufox's *internal* behavior are outside
|
||||||
|
the scope of this project.
|
||||||
- Bugs about Camoufox's *internal* behavior (page rendering, JS engine,
|
- Bugs about Camoufox's *internal* behavior (page rendering, JS engine,
|
||||||
dropdowns, form widgets, fingerprinting *as Camoufox implements it*,
|
dropdowns, form widgets, fingerprinting *as Camoufox implements it*,
|
||||||
checkbox/radio quirks) are UPSTREAM ONLY. Redirect to
|
checkbox/radio quirks) are out of scope here. Ask the user to first
|
||||||
https://github.com/daijro/camoufox/issues.
|
search https://github.com/daijro/camoufox/issues for a matching report,
|
||||||
|
and if they don't find one, to open it there themselves.
|
||||||
- Bugs about how Donut *launches, configures, or downloads* Camoufox are
|
- Bugs about how Donut *launches, configures, or downloads* Camoufox are
|
||||||
in-scope here.
|
in-scope here.
|
||||||
- **Forks of Wayfern or Camoufox** (e.g. CloverLabsAI, VulpineOS) are NOT
|
- **Forks of Wayfern or Camoufox** (e.g. CloverLabsAI, VulpineOS) are NOT
|
||||||
@@ -146,7 +148,10 @@ jobs:
|
|||||||
dismiss as "known issue" / "expected" / "false positive in Tauri apps". Ask
|
dismiss as "known issue" / "expected" / "false positive in Tauri apps". Ask
|
||||||
which exact version was the last working one and what changed.
|
which exact version was the last working one and what changed.
|
||||||
- **Out-of-scope (upstream Camoufox)**: report is about Camoufox's own
|
- **Out-of-scope (upstream Camoufox)**: report is about Camoufox's own
|
||||||
behavior. Redirect, do not collect logs.
|
behavior. Tell the user it's outside the scope of this project and ask
|
||||||
|
them to search the Camoufox repo and, if no matching issue exists, file
|
||||||
|
one there. Do NOT say the maintainer doesn't contribute / can't fix it
|
||||||
|
— keep it strictly about project scope. Do not collect logs.
|
||||||
- **Fork-support request**: asks the maintainer to support an alternative
|
- **Fork-support request**: asks the maintainer to support an alternative
|
||||||
Wayfern/Camoufox fork. Acknowledge in one neutral sentence — do NOT call it
|
Wayfern/Camoufox fork. Acknowledge in one neutral sentence — do NOT call it
|
||||||
"clear", "reasonable", "well-thought-out", etc.
|
"clear", "reasonable", "well-thought-out", etc.
|
||||||
@@ -342,7 +347,7 @@ jobs:
|
|||||||
The triage classification (`triage.classification`) determines the response shape:
|
The triage classification (`triage.classification`) determines the response shape:
|
||||||
|
|
||||||
- `bug-in-scope`: ask for what is missing using the user's reported OS log path. Be concrete about how to obtain logs.
|
- `bug-in-scope`: ask for what is missing using the user's reported OS log path. Be concrete about how to obtain logs.
|
||||||
- `bug-upstream-camoufox`: redirect ONLY. One sentence acknowledging, then a sentence saying this is a Camoufox-internal issue and the maintainer of this repo does not contribute to Camoufox; ask the user to file at https://github.com/daijro/camoufox/issues. Do NOT ask for Donut logs. Stop after that.
|
- `bug-upstream-camoufox`: redirect ONLY. One sentence acknowledging, then say this is outside the scope of this project — ask the user to first search https://github.com/daijro/camoufox/issues for a matching report and, if none exists, to open one there themselves. Do NOT phrase it as "the maintainer does not contribute" or anything personal — keep it strictly about scope. Do NOT ask for Donut logs. Stop after that.
|
||||||
- `bug-template-violation` or `ai-generated-junk`: politely ask the user to refile using the bug-report template (the Operating System, Donut Browser version, Which browser, Steps to reproduce, Error logs sections). If they cited "documentation" from any non-`donutbrowser.com`/non-`github.com/zhom` URL (e.g. context7, deepwiki), gently note that those are AI-generated third-party summaries and the only authoritative sources are this repo and donutbrowser.com.
|
- `bug-template-violation` or `ai-generated-junk`: politely ask the user to refile using the bug-report template (the Operating System, Donut Browser version, Which browser, Steps to reproduce, Error logs sections). If they cited "documentation" from any non-`donutbrowser.com`/non-`github.com/zhom` URL (e.g. context7, deepwiki), gently note that those are AI-generated third-party summaries and the only authoritative sources are this repo and donutbrowser.com.
|
||||||
- `feature-request`: one neutral sentence acknowledging, then ask only what is genuinely needed (concrete use case, whether a workaround would suffice). Do NOT validate.
|
- `feature-request`: one neutral sentence acknowledging, then ask only what is genuinely needed (concrete use case, whether a workaround would suffice). Do NOT validate.
|
||||||
- `fork-request`: one neutral sentence acknowledging the request. Note that this would substantially increase support burden and the maintainer evaluates such requests on a case-by-case basis. Ask whether the alternative fork supports all platforms the user uses (macOS / Windows / Linux). No "clear enhancement" language.
|
- `fork-request`: one neutral sentence acknowledging the request. Note that this would substantially increase support burden and the maintainer evaluates such requests on a case-by-case basis. Ask whether the alternative fork supports all platforms the user uses (macOS / Windows / Linux). No "clear enhancement" language.
|
||||||
|
|||||||
Reference in New Issue
Block a user