From 848ea75d3614ba0d131e0f2a9da87981592f7fd2 Mon Sep 17 00:00:00 2001 From: Heeyaa Date: Tue, 7 Apr 2026 16:08:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20=EC=9D=B4=EC=8A=88=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..550b516 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ +## Summary + +- + +## Problem + +- + +## Expected + +- + +## Notes + +- From f03efd7ac48548285fd5f76be4ae8a48f10928a4 Mon Sep 17 00:00:00 2001 From: Heeyaa Date: Tue, 7 Apr 2026 16:38:03 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20frog=20github=20writeback=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/github-writeback.mjs | 136 +++++++++++++++++++++++++++ .github/workflows/github-intake.yml | 8 ++ 2 files changed, 144 insertions(+) create mode 100644 .github/scripts/github-writeback.mjs diff --git a/.github/scripts/github-writeback.mjs b/.github/scripts/github-writeback.mjs new file mode 100644 index 0000000..40873c3 --- /dev/null +++ b/.github/scripts/github-writeback.mjs @@ -0,0 +1,136 @@ +#!/usr/bin/env node + +import fs from 'node:fs/promises'; + +const token = process.env.GITHUB_TOKEN; + +if (!token) { + throw new Error('GITHUB_TOKEN environment variable is required'); +} + +function usage() { + console.error( + [ + 'Usage:', + ' node .github/scripts/github-writeback.mjs pr-review --repo owner/repo --number 123 --body-file /tmp/review.md [--commit-sha abc123]', + ' node .github/scripts/github-writeback.mjs issue-comment --repo owner/repo --number 88 --body-file /tmp/comment.md', + ].join('\n'), + ); + process.exit(1); +} + +function parseArgs(argv) { + const [command, ...rest] = argv; + if (!command) usage(); + + const options = { command }; + for (let i = 0; i < rest.length; i += 1) { + const key = rest[i]; + const value = rest[i + 1]; + + if (!key.startsWith('--') || value === undefined) usage(); + options[key.slice(2)] = value; + i += 1; + } + + return options; +} + +async function githubRequest(path, init = {}) { + const response = await fetch(`https://api.github.com${path}`, { + ...init, + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${token}`, + 'User-Agent': 'frog-github-writeback', + 'Content-Type': 'application/json', + ...(init.headers ?? {}), + }, + }); + + if (!response.ok) { + const body = await response.text(); + throw new Error(`GitHub API ${path} failed: ${response.status} ${body}`); + } + + const text = await response.text(); + return text ? JSON.parse(text) : null; +} + +async function main() { + const args = parseArgs(process.argv.slice(2)); + const repo = args.repo; + const number = args.number; + const bodyFile = args['body-file']; + + if (!repo || !number || !bodyFile) usage(); + + const [owner, name] = repo.split('/'); + if (!owner || !name) { + throw new Error(`Invalid repo: ${repo}`); + } + + const body = (await fs.readFile(bodyFile, 'utf8')).trim(); + if (!body) { + throw new Error('Body file is empty'); + } + + if (args.command === 'pr-review') { + const payload = { + event: 'COMMENT', + body, + }; + + if (args['commit-sha']) { + payload.commit_id = args['commit-sha']; + } + + const review = await githubRequest(`/repos/${owner}/${name}/pulls/${number}/reviews`, { + method: 'POST', + body: JSON.stringify(payload), + }); + + console.log( + JSON.stringify( + { + ok: true, + type: 'pr-review', + repo, + number, + review_id: review?.id ?? null, + html_url: review?.html_url ?? null, + }, + null, + 2, + ), + ); + return; + } + + if (args.command === 'issue-comment') { + const comment = await githubRequest(`/repos/${owner}/${name}/issues/${number}/comments`, { + method: 'POST', + body: JSON.stringify({ body }), + }); + + console.log( + JSON.stringify( + { + ok: true, + type: 'issue-comment', + repo, + number, + comment_id: comment?.id ?? null, + html_url: comment?.html_url ?? null, + }, + null, + 2, + ), + ); + return; + } + + usage(); +} + +await main(); diff --git a/.github/workflows/github-intake.yml b/.github/workflows/github-intake.yml index be0d43a..e24644c 100644 --- a/.github/workflows/github-intake.yml +++ b/.github/workflows/github-intake.yml @@ -46,7 +46,15 @@ jobs: `author=${context.actor}`, `url=${payload.pull_request.html_url}`, `base=${payload.pull_request.base.ref}`, + `base_sha=${payload.pull_request.base.sha}`, `head=${payload.pull_request.head.ref}`, + `head_sha=${payload.pull_request.head.sha}`, + `draft=${payload.pull_request.draft}`, + `changed_files=${payload.pull_request.changed_files}`, + `additions=${payload.pull_request.additions}`, + `deletions=${payload.pull_request.deletions}`, + `diff_url=${payload.pull_request.diff_url}`, + `patch_url=${payload.pull_request.patch_url}`, 'action=review', ]; } else if (eventName === 'issues') {