-
Notifications
You must be signed in to change notification settings - Fork 403
134 lines (116 loc) · 4.69 KB
/
auto-answer-issues.yml
File metadata and controls
134 lines (116 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
name: Auto-Answer Issues
on:
issues:
types: [opened, labeled]
permissions:
issues: write
contents: read
jobs:
answer-issue:
runs-on: ubuntu-latest
# Only run for issues created by org members or owners (i.e., Microsoft Open Source enterprise members).
# github.event.issue.author_association is set by GitHub based on the issue author's relationship
# to this repository. MEMBER = org member, OWNER = repo/org owner. This prevents untrusted
# external contributors from triggering the Azure OpenAI-backed responder and consuming secrets/tokens.
if: |
github.event.issue.author_association == 'MEMBER' ||
github.event.issue.author_association == 'OWNER' ||
github.event.issue.author_association == 'COLLABORATOR'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install @octokit/rest openai
- name: Generate and post response
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_DEPLOYMENT: ${{ secrets.AZURE_OPENAI_DEPLOYMENT }}
AZURE_OPENAI_API_VERSION: "2024-12-01-preview"
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
run: |
node - << 'EOF'
const { Octokit } = require("@octokit/rest");
const { AzureOpenAI } = require("openai");
async function main() {
const {
GITHUB_TOKEN,
AZURE_OPENAI_API_KEY,
AZURE_OPENAI_ENDPOINT,
AZURE_OPENAI_DEPLOYMENT,
AZURE_OPENAI_API_VERSION,
ISSUE_NUMBER,
ISSUE_TITLE,
ISSUE_BODY,
REPO_OWNER,
REPO_NAME
} = process.env;
if (!GITHUB_TOKEN) {
throw new Error("GITHUB_TOKEN is not set.");
}
if (!AZURE_OPENAI_API_KEY) {
throw new Error("AZURE_OPENAI_API_KEY is not set.");
}
if (!AZURE_OPENAI_ENDPOINT) {
throw new Error("AZURE_OPENAI_ENDPOINT is not set.");
}
if (!AZURE_OPENAI_DEPLOYMENT) {
throw new Error("AZURE_OPENAI_DEPLOYMENT is not set.");
}
if (!ISSUE_NUMBER || !REPO_OWNER || !REPO_NAME) {
throw new Error("Required issue/repository environment variables are missing.");
}
const issueNumber = parseInt(ISSUE_NUMBER, 10);
const title = ISSUE_TITLE || "";
const body = ISSUE_BODY || "";
const octokit = new Octokit({ auth: GITHUB_TOKEN });
const openai = new AzureOpenAI({
apiKey: AZURE_OPENAI_API_KEY,
endpoint: AZURE_OPENAI_ENDPOINT,
deployment: AZURE_OPENAI_DEPLOYMENT,
apiVersion: AZURE_OPENAI_API_VERSION
});
const prompt = `
You are a helpful GitHub assistant. An issue has been opened in the repository \`${REPO_OWNER}/${REPO_NAME}\`.
Title:
${title}
Body:
${body}
Please write a concise, friendly reply that:
- Acknowledges the question or issue.
- Asks for any missing information if needed.
- Suggests next steps or possible causes based only on the information provided.
- Uses markdown formatting suitable for a GitHub issue comment.
`;
const completion = await openai.chat.completions.create({
model: AZURE_OPENAI_DEPLOYMENT,
messages: [
{ role: "system", content: "You are a helpful assistant for triaging GitHub issues." },
{ role: "user", content: prompt }
]
});
const reply = (completion.choices[0]?.message?.content || "").trim();
if (!reply) {
throw new Error("Azure OpenAI returned an empty response.");
}
await octokit.issues.createComment({
owner: REPO_OWNER,
repo: REPO_NAME,
issue_number: issueNumber,
body: reply
});
}
main().catch((error) => {
console.error("Failed to generate or post response:", error);
process.exit(1);
});
EOF