feat: New action to create follow-up issues for PRs with unresolved code review threads#140
Conversation
…ode review threads
95dcd4e to
ffd0c92
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new composite GitHub Action that scans a specified PR for unresolved review threads, creates/updates a follow-up issue summarizing them, and posts (or updates) a single reference comment on the PR.
Changes:
- Add
create-review-follow-up-issuecomposite action with an embedded Node.js script to query review threads, build a markdown summary, and create/update an issue + PR comment. - Document the new action in the repository README action list.
- Add a workflow that performs basic validation (script syntax + invalid input guard).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| README.md | Adds the new action to the “Available Actions” list. |
| create-review-follow-up-issue/action.yml | Implements the follow-up issue creation/update logic and PR reference comment logic via embedded Node.js script. |
| .github/workflows/test-create-review-follow-up-issue.yml | Adds a basic CI workflow to validate script syntax and reject invalid PR numbers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| node <<'EOF' | ||
| const fs = require("node:fs"); | ||
|
|
||
| const token = process.env.GH_TOKEN; |
There was a problem hiding this comment.
Ok, good point but the proposed solution above is not ideal. I fixed this issue by adding a new first step checking for the Node and its version.
| if (issue.pull_request || issue.state !== "open") | ||
| return null; | ||
|
|
There was a problem hiding this comment.
I think the best way for this action to work is to comply with the state of the follow-up issue. So, if the follow-up issue has been closed, then this action should create a new issue instead of trying to update a closed issue. Therefore no code changes here, but I updated this PR description to clarify the behavior.
| - name: Validate embedded script syntax | ||
| shell: bash | ||
| run: | | ||
| script="${RUNNER_TEMP:-/tmp}/review-follow-up.cjs" | ||
| awk ' | ||
| /node <<.EOF.$/ { capture = 1; next } | ||
| capture && /^ *EOF$/ { exit } | ||
| capture { sub(/^ /, ""); print } | ||
| ' create-review-follow-up-issue/action.yml > "${script}" | ||
|
|
||
| if [[ ! -s "${script}" ]]; then | ||
| echo "Failed to extract the embedded script from action.yml" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| node --check "${script}" | ||
| echo "Embedded review follow-up script is valid JavaScript." | ||
|
|
||
| - name: Reject invalid PR number | ||
| id: invalid_pr | ||
| continue-on-error: true | ||
| uses: ./create-review-follow-up-issue | ||
| with: | ||
| pr_number: 0 | ||
|
|
There was a problem hiding this comment.
I don't know if this is even feasible to test end-to-end because it would require creating a whole PR with a sample code review thread. If the smoke test is sufficient, then I prefer it for now.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| ISSUE_TITLE: ${{ inputs.issue_title }} | ||
| LABELS: ${{ inputs.labels }} | ||
| run: | | ||
| node <<'EOF' |
There was a problem hiding this comment.
Unfortunately, 800 lines of inline code are something unmaintainable.
We need to figure out how to publish it as an npm package
This new action introduces a manually triggered automation that when given a specific PR # number creates a new issue with a summary of unresolved code review threads from that PR and leaves a reference comment under that PR (only once). If the specific PR already has a follow-up issue created by this action, the action updates that issue if it is still open, otherwise a new follow-up issue is created. Additionally, this action attempts to assign that created issue to the author of that specific PR, unless the author is not allowed to be assigned by the repo settings.
An example issue created by this action is visible here: marek-foss-neti/rippled#2
An example PR on which this action was used is visible here: marek-foss-neti/rippled#1