|
@@ -17,70 +17,53 @@ jobs:
|
|
|
with:
|
|
with:
|
|
|
fetch-depth: 1
|
|
fetch-depth: 1
|
|
|
|
|
|
|
|
- - uses: ./.github/actions/setup-bun
|
|
|
|
|
-
|
|
|
|
|
- - name: Install dependencies
|
|
|
|
|
- run: bun install
|
|
|
|
|
-
|
|
|
|
|
- name: Install opencode
|
|
- name: Install opencode
|
|
|
run: curl -fsSL https://opencode.ai/install | bash
|
|
run: curl -fsSL https://opencode.ai/install | bash
|
|
|
|
|
|
|
|
- - name: Build prompt
|
|
|
|
|
- uses: actions/github-script@v8
|
|
|
|
|
- with:
|
|
|
|
|
- script: |
|
|
|
|
|
- const fs = require("fs")
|
|
|
|
|
- const issue = context.payload.issue
|
|
|
|
|
- const body = issue.body ?? ""
|
|
|
|
|
- const text = [
|
|
|
|
|
- "Check this new issue for compliance and duplicates:",
|
|
|
|
|
- "",
|
|
|
|
|
- `CURRENT_ISSUE_NUMBER: ${issue.number}`,
|
|
|
|
|
- "",
|
|
|
|
|
- `Title: ${issue.title}`,
|
|
|
|
|
- "",
|
|
|
|
|
- "Description:",
|
|
|
|
|
- body,
|
|
|
|
|
- ].join("\n")
|
|
|
|
|
-
|
|
|
|
|
- fs.writeFileSync("issue_info.txt", text)
|
|
|
|
|
-
|
|
|
|
|
- name: Check duplicates and compliance
|
|
- name: Check duplicates and compliance
|
|
|
env:
|
|
env:
|
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
|
+ OPENCODE_PERMISSION: |
|
|
|
|
|
+ {
|
|
|
|
|
+ "bash": "deny",
|
|
|
|
|
+ "webfetch": "deny",
|
|
|
|
|
+ "edit": "deny",
|
|
|
|
|
+ "write": "deny"
|
|
|
|
|
+ }
|
|
|
|
|
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
|
|
|
+ REPO: ${{ github.repository }}
|
|
|
run: |
|
|
run: |
|
|
|
- bun script/duplicate-issue.ts -f issue_info.txt "Check the attached file for issue details and return either a comment body or No action required" > issue_comment.txt
|
|
|
|
|
|
|
+ ISSUE_TITLE=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json title --jq .title)
|
|
|
|
|
+ ISSUE_BODY=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json body --jq .body)
|
|
|
|
|
|
|
|
- - name: Post comment and label issue
|
|
|
|
|
- env:
|
|
|
|
|
- COMMENT: ${{ github.workspace }}/issue_comment.txt
|
|
|
|
|
- uses: actions/github-script@v8
|
|
|
|
|
- with:
|
|
|
|
|
- script: |
|
|
|
|
|
- const fs = require("fs")
|
|
|
|
|
- const comment = fs.readFileSync(process.env.COMMENT, "utf8").trim()
|
|
|
|
|
|
|
+ PROMPT=$(cat <<EOF
|
|
|
|
|
+ Check this new issue for compliance and duplicates:
|
|
|
|
|
|
|
|
- if (comment === "No action required") {
|
|
|
|
|
- core.info("No comment needed")
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ CURRENT_ISSUE_NUMBER: $ISSUE_NUMBER
|
|
|
|
|
|
|
|
- await github.rest.issues.createComment({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number: context.payload.issue.number,
|
|
|
|
|
- body: `_The following comment was made by an LLM, it may be inaccurate:_\n\n${comment}`,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ Title: $ISSUE_TITLE
|
|
|
|
|
|
|
|
- if (!comment.includes("<!-- issue-compliance -->")) return
|
|
|
|
|
|
|
+ Description:
|
|
|
|
|
+ $ISSUE_BODY
|
|
|
|
|
+ EOF
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- await github.rest.issues.addLabels({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number: context.payload.issue.number,
|
|
|
|
|
- labels: ["needs:compliance"],
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ COMMENT=$(opencode run --agent duplicate-issue "$PROMPT")
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$COMMENT" = "No action required" ]; then
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ BODY="_The following comment was made by an LLM, it may be inaccurate:_
|
|
|
|
|
+
|
|
|
|
|
+ $COMMENT"
|
|
|
|
|
+
|
|
|
|
|
+ gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "$BODY"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "$COMMENT" == *"<!-- issue-compliance -->"* ]]; then
|
|
|
|
|
+ gh issue edit "$ISSUE_NUMBER" --repo "$REPO" --add-label needs:compliance
|
|
|
|
|
+ fi
|
|
|
|
|
|
|
|
recheck-compliance:
|
|
recheck-compliance:
|
|
|
if: github.event.action == 'edited' && contains(github.event.issue.labels.*.name, 'needs:compliance')
|
|
if: github.event.action == 'edited' && contains(github.event.issue.labels.*.name, 'needs:compliance')
|
|
@@ -94,111 +77,63 @@ jobs:
|
|
|
with:
|
|
with:
|
|
|
fetch-depth: 1
|
|
fetch-depth: 1
|
|
|
|
|
|
|
|
- - uses: ./.github/actions/setup-bun
|
|
|
|
|
-
|
|
|
|
|
- - name: Install dependencies
|
|
|
|
|
- run: bun install
|
|
|
|
|
-
|
|
|
|
|
- name: Install opencode
|
|
- name: Install opencode
|
|
|
run: curl -fsSL https://opencode.ai/install | bash
|
|
run: curl -fsSL https://opencode.ai/install | bash
|
|
|
|
|
|
|
|
- - name: Build recheck prompt
|
|
|
|
|
- uses: actions/github-script@v8
|
|
|
|
|
- with:
|
|
|
|
|
- script: |
|
|
|
|
|
- const fs = require("fs")
|
|
|
|
|
- const issue = context.payload.issue
|
|
|
|
|
- const body = issue.body ?? ""
|
|
|
|
|
- const text = [
|
|
|
|
|
- "Recheck this edited issue for compliance:",
|
|
|
|
|
- "",
|
|
|
|
|
- "MODE: recheck-compliance",
|
|
|
|
|
- `CURRENT_ISSUE_NUMBER: ${issue.number}`,
|
|
|
|
|
- "",
|
|
|
|
|
- `Title: ${issue.title}`,
|
|
|
|
|
- "",
|
|
|
|
|
- "Description:",
|
|
|
|
|
- body,
|
|
|
|
|
- ].join("\n")
|
|
|
|
|
-
|
|
|
|
|
- fs.writeFileSync("issue_info.txt", text)
|
|
|
|
|
-
|
|
|
|
|
- name: Recheck compliance
|
|
- name: Recheck compliance
|
|
|
env:
|
|
env:
|
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
|
+ OPENCODE_PERMISSION: |
|
|
|
|
|
+ {
|
|
|
|
|
+ "bash": "deny",
|
|
|
|
|
+ "webfetch": "deny",
|
|
|
|
|
+ "edit": "deny",
|
|
|
|
|
+ "write": "deny"
|
|
|
|
|
+ }
|
|
|
|
|
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
|
|
|
+ REPO: ${{ github.repository }}
|
|
|
run: |
|
|
run: |
|
|
|
- bun script/duplicate-issue.ts -f issue_info.txt "Recheck compliance for this edited issue and return either No action required or a compliance comment body" > issue_comment.txt
|
|
|
|
|
|
|
+ ISSUE_TITLE=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json title --jq .title)
|
|
|
|
|
+ ISSUE_BODY=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json body --jq .body)
|
|
|
|
|
|
|
|
- - name: Update compliance state
|
|
|
|
|
- env:
|
|
|
|
|
- COMMENT: ${{ github.workspace }}/issue_comment.txt
|
|
|
|
|
- uses: actions/github-script@v8
|
|
|
|
|
- with:
|
|
|
|
|
- script: |
|
|
|
|
|
- const fs = require("fs")
|
|
|
|
|
- const marker = "<!-- issue-compliance -->"
|
|
|
|
|
- const comment = fs.readFileSync(process.env.COMMENT, "utf8").trim()
|
|
|
|
|
- const issue_number = context.payload.issue.number
|
|
|
|
|
-
|
|
|
|
|
- const { data: comments } = await github.rest.issues.listComments({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number,
|
|
|
|
|
- per_page: 100,
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- const compliance = comments.filter((x) => (x.body ?? "").includes(marker))
|
|
|
|
|
-
|
|
|
|
|
- if (comment === "No action required") {
|
|
|
|
|
- try {
|
|
|
|
|
- await github.rest.issues.removeLabel({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number,
|
|
|
|
|
- name: "needs:compliance",
|
|
|
|
|
- })
|
|
|
|
|
- } catch {}
|
|
|
|
|
-
|
|
|
|
|
- for (const entry of compliance) {
|
|
|
|
|
- await github.rest.issues.deleteComment({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- comment_id: entry.id,
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await github.rest.issues.createComment({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number,
|
|
|
|
|
- body: "Thanks for updating your issue. It now meets our contributing guidelines. :+1:",
|
|
|
|
|
- })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ PROMPT=$(cat <<EOF
|
|
|
|
|
+ Recheck this edited issue for compliance:
|
|
|
|
|
|
|
|
- await github.rest.issues.addLabels({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number,
|
|
|
|
|
- labels: ["needs:compliance"],
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- const body = `_The following comment was made by an LLM, it may be inaccurate:_\n\n${comment}`
|
|
|
|
|
- const existing = compliance.at(-1)
|
|
|
|
|
- if (!existing) {
|
|
|
|
|
- await github.rest.issues.createComment({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- issue_number,
|
|
|
|
|
- body,
|
|
|
|
|
- })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ MODE: recheck-compliance
|
|
|
|
|
+ CURRENT_ISSUE_NUMBER: $ISSUE_NUMBER
|
|
|
|
|
+
|
|
|
|
|
+ Title: $ISSUE_TITLE
|
|
|
|
|
+
|
|
|
|
|
+ Description:
|
|
|
|
|
+ $ISSUE_BODY
|
|
|
|
|
+ EOF
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ COMMENT=$(opencode run --agent duplicate-issue "$PROMPT")
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$COMMENT" = "No action required" ]; then
|
|
|
|
|
+ gh issue edit "$ISSUE_NUMBER" --repo "$REPO" --remove-label needs:compliance || true
|
|
|
|
|
+
|
|
|
|
|
+ IDS=$(gh api "repos/$REPO/issues/$ISSUE_NUMBER/comments" --jq '.[] | select(.body | contains("<!-- issue-compliance -->")) | .id')
|
|
|
|
|
+ for id in $IDS; do
|
|
|
|
|
+ gh api -X DELETE "repos/$REPO/issues/comments/$id"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "Thanks for updating your issue. It now meets our contributing guidelines. :+1:"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ gh issue edit "$ISSUE_NUMBER" --repo "$REPO" --add-label needs:compliance
|
|
|
|
|
+
|
|
|
|
|
+ BODY="_The following comment was made by an LLM, it may be inaccurate:_
|
|
|
|
|
+
|
|
|
|
|
+ $COMMENT"
|
|
|
|
|
+
|
|
|
|
|
+ EXISTING=$(gh api "repos/$REPO/issues/$ISSUE_NUMBER/comments" --jq '[.[] | select(.body | contains("<!-- issue-compliance -->")) | .id] | last // empty')
|
|
|
|
|
+ if [ -n "$EXISTING" ]; then
|
|
|
|
|
+ gh api -X PATCH "repos/$REPO/issues/comments/$EXISTING" -f body="$BODY"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
|
|
|
- await github.rest.issues.updateComment({
|
|
|
|
|
- owner: context.repo.owner,
|
|
|
|
|
- repo: context.repo.repo,
|
|
|
|
|
- comment_id: existing.id,
|
|
|
|
|
- body,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "$BODY"
|