mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-01-10 09:51:02 +01:00
clean
This commit is contained in:
205
.github/workflows/ai-triage.yml
vendored
205
.github/workflows/ai-triage.yml
vendored
@@ -1,205 +0,0 @@
|
||||
name: AI triage (comment + optional PR)
|
||||
|
||||
on:
|
||||
# issues:
|
||||
# types: [opened]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
ai_first_reply:
|
||||
runs-on: ubuntu-latest
|
||||
# Run when: issue opened OR a '/codex' comment on an issue (not PR)
|
||||
if: >
|
||||
(github.event_name == 'issues' ||
|
||||
(github.event_name == 'issue_comment' &&
|
||||
github.event.action == 'created' &&
|
||||
github.event.comment.body == '/codex' &&
|
||||
github.event.issue.pull_request == null))
|
||||
&& contains(github.event.issue.labels.*.name, 'bug')
|
||||
steps:
|
||||
- name: Compose and post AI reply
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
with:
|
||||
script: |
|
||||
const issue = context.payload.issue;
|
||||
const { owner, repo } = context.repo;
|
||||
|
||||
// Optional repo context
|
||||
let readmeText = '';
|
||||
try {
|
||||
const readme = await github.rest.repos.getReadme({ owner, repo });
|
||||
readmeText = Buffer.from(readme.data.content, 'base64').toString('utf8');
|
||||
if (readmeText.length > 18000) readmeText = readmeText.slice(0, 18000) + "\n...[truncated]...";
|
||||
} catch {}
|
||||
|
||||
const system = `
|
||||
You are an open-source triage assistant.
|
||||
Write a concise, actionable first reply for a new bug report.
|
||||
Focus on diagnosing the problem and suggesting potential fixes.
|
||||
Minimize follow-up questions and avoid inventing repo facts.
|
||||
Propose next steps and link to repo files only when certain.
|
||||
`.trim();
|
||||
|
||||
const user = `
|
||||
Repository: ${owner}/${repo}
|
||||
Issue #${issue.number}: ${issue.title}
|
||||
|
||||
Issue body:
|
||||
${issue.body || '(no body provided)'}
|
||||
|
||||
README excerpt:
|
||||
${readmeText || '(none)'}
|
||||
`.trim();
|
||||
|
||||
const res = await fetch('https://api.openai.com/v1/responses', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'gpt-4o-mini',
|
||||
input: [
|
||||
{ role: 'system', content: system },
|
||||
{ role: 'user', content: user }
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const txt = await res.text();
|
||||
await github.rest.issues.createComment({
|
||||
owner, repo, issue_number: issue.number,
|
||||
body: `⚠️ AI reply failed (${res.status}).\n\n\`\`\`\n${txt}\n\`\`\``
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
const text = data.output_text
|
||||
|| data.output?.map(p => p.content?.map(c => c.text ?? '').join('')).join('\n')
|
||||
|| data?.choices?.[0]?.message?.content
|
||||
|| 'Thanks for opening this issue — we will take a look!';
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner, repo, issue_number: issue.number, body: text
|
||||
});
|
||||
|
||||
ai_autofix_pr:
|
||||
runs-on: ubuntu-latest
|
||||
needs: ai_first_reply
|
||||
# Same trigger conditions as above AND issue has label 'auto-pr'
|
||||
if: >
|
||||
(github.event_name == 'issues' ||
|
||||
(github.event_name == 'issue_comment' &&
|
||||
github.event.action == 'created' &&
|
||||
github.event.comment.body == '/codex' &&
|
||||
github.event.issue.pull_request == null))
|
||||
&& contains(github.event.issue.labels.*.name, 'auto-pr')
|
||||
&& contains(github.event.issue.labels.*.name, 'bug')
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate patch with OpenAI (unified diff)
|
||||
id: genpatch
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const issue = context.payload.issue;
|
||||
|
||||
let readmeText = '';
|
||||
try {
|
||||
const readme = await github.rest.repos.getReadme({ owner, repo });
|
||||
readmeText = Buffer.from(readme.data.content, 'base64').toString('utf8');
|
||||
if (readmeText.length > 12000) readmeText = readmeText.slice(0, 12000) + "\n...[truncated]...";
|
||||
} catch {}
|
||||
|
||||
const system = `
|
||||
You are a code-change generator.
|
||||
Output ONLY a git unified diff (git apply compatible). No prose, no backticks.
|
||||
Keep changes minimal and safe; if unsure, output an empty diff.
|
||||
`.trim();
|
||||
|
||||
const user = `
|
||||
Repo: ${owner}/${repo}
|
||||
Issue #${issue.number}: ${issue.title}
|
||||
|
||||
Issue body:
|
||||
${issue.body || '(no body)'}
|
||||
|
||||
README excerpt:
|
||||
${readmeText || '(none)'}
|
||||
`.trim();
|
||||
|
||||
const res = await fetch('https://api.openai.com/v1/responses', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'gpt-4o-mini',
|
||||
input: [
|
||||
{ role: 'system', content: system },
|
||||
{ role: 'user', content: user }
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const txt = await res.text();
|
||||
core.setFailed(`OpenAI error ${res.status}: ${txt}`);
|
||||
} else {
|
||||
const data = await res.json();
|
||||
const patch = (
|
||||
data.output_text
|
||||
|| data.output?.map(p => p.content?.map(c => c.text ?? '').join('')).join('\n')
|
||||
|| data?.choices?.[0]?.message?.content
|
||||
|| ''
|
||||
).trim();
|
||||
return patch;
|
||||
}
|
||||
|
||||
- name: Apply patch (if any)
|
||||
id: apply
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
patch="${{ steps.genpatch.outputs.result }}"
|
||||
if [ -z "$patch" ]; then
|
||||
echo "No patch produced; skipping PR."
|
||||
echo "skip_pr=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$patch" > ai.patch
|
||||
git apply --whitespace=fix ai.patch
|
||||
echo "skip_pr=false" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.apply.outputs.skip_pr == 'false'
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
branch: ai/autofix-${{ github.event.issue.number }}
|
||||
title: AI autofix for #${{ github.event.issue.number }}
|
||||
commit-message: AI autofix for #${{ github.event.issue.number }}
|
||||
body: |
|
||||
This PR was generated automatically from issue #${{ github.event.issue.number }}.
|
||||
|
||||
Label `auto-pr` triggered patch creation. Please review carefully.
|
||||
labels: auto-pr, ai-generated
|
||||
delete-branch: true
|
||||
Reference in New Issue
Block a user