feat: add issue duplicate detection and contributor automation - #6
akramcodez wants to merge 5 commits into
Conversation
|
Thanks for this — the architecture is right (reusable workflow + thin caller, no checkout under Flagging the blockers rather than the full list:
|
…kflows Addresses the review on Nano-Collective#6. All nine blockers plus the non-blocking items. duplicate-issue.yml: - job-level GH_REPO so bare gh calls resolve the repository (was fatal at the first skip check) - fix inverted bot check: jq's // fires on false, so every human author was classified as a bot; test is_bot explicitly instead - skip step now writes skip=true to GITHUB_OUTPUT and every downstream step is gated on it; exit 0 alone never gated anything - bodies.tsv -> bodies.ndjson: multi-line issue bodies broke the TSV read loop and crashed --argjson; NDJSON survives any body content - guard the label-iteration jq against the {} fallback (Cannot iterate over null under set -euo pipefail) - add actions/setup-node@v4 / node 22 (nanocoder declares engines >=22); same pin as nc-review - context-limit 32000 -> 128000 to match nc-review; 100 full bodies overflowed 32000 and autoCompact ate the output schema - quote the agents.config.json heredoc (<<'JSON', same as nc-review) and drop the now-redundant \$ escape - fix join(", ") // "(none)": join on [] returns "" which is truthy in jq, so the fallback was unreachable - length-cap (1000 chars) and fence the model-authored summary; it is derived from an untrusted issue body and was posted verbatim in a maintainer-looking comment - callee concurrency group renamed duplicate-issue-callee-* so it does not queue behind the caller's identically-named group first-time-contributor.yml: - fix "ignored = true" -> "ignored=true" in five skip paths (spaces around = made the key "ignored " and every idempotency guard inert) - entry= output written with heredoc delimiter form; the pretty-printed multi-line jq output was rejected by the runner ("Invalid format") and killed the success path too - -f force=true -> -F force=true: the refs API wants a boolean, -f sends the string "true" and 422s - callee concurrency group renamed first-time-contributor-callee-* templates/README.md: - fix ../workflows/ link from templates/ (repo-root path that does not resolve) to ../.github/workflows/ - document the contributors.json write race and search-index latency under a Known limitations section All five files: trailing newlines added. bash -n passes on every run block, YAML parses for all files, caller inputs verified against callee inputs.
Two remaining review items from Nano-Collective#6: - duplicate-issue.yml: replace the per-issue REST loop (100 sequential round-trips per triaged issue) with one batched GraphQL call using aliased issue(number:) lookups. Response is filtered to NDJSON with jq and falls back to the per-issue REST path if the batched call fails, rather than triaging against an empty corpus. - contributors.json: add the initial empty registry file to the repo root, as the README already argued for committing it explicitly so the first contributor PR is not also a "create file" PR.
|
Hey @will-lamerton, addressed all the feedback and pushed the fixes. I believe it’s ready for another look whenever you get a chance. |
Summary
This PR adds GitHub Actions to automate issue and contributor management across Nano Collective repositories.
It introduces three related automations:
The workflows are implemented as reusable workflows in
Nano-Collective/.github, with lightweight caller workflows that can be adopted by individual repositories.Features
1. Duplicate Issue Detection
The duplicate issue workflow runs when an issue is opened or edited.
It:
duplicatelabel when a duplicate is identified.agent:duplicate-uncertainwhen the result has low confidence.The workflow also avoids executing untrusted repository code and uses the configured model input rather than hardcoding a model.
2. First-Time Contributor Label
The contributor automation detects contributors who are making their first contribution to the organization.
This allows repositories to automatically identify first-time contributors and apply the appropriate contributor labeling without requiring manual maintainer intervention.
The detection is organization-scoped rather than simply checking whether the user has ever contributed to GitHub.
3. First Merged PR → Organization Contributor PR
When a first-time contributor's PR is merged, the workflow automatically:
contributors.json.contributors.json.Nano-Collective/.github.The workflow is designed to be idempotent, so repeated contributions from the same user should not result in duplicate contributor entries or onboarding PRs.
Example contributor entry:
{ "github": "octocat", "profile": { "login": "octocat", "name": "The Octocat", "bio": "...", "avatar_url": "...", "html_url": "...", "blog": "...", "company": "@GitHub", "twitter_username": "octocat" }, "first_pr": { "repo": "Nano-Collective/nanocoder", "number": 123, "url": "...", "merged_at": "..." } }Implementation
The workflows are exposed as reusable workflows so individual Nano Collective repositories only need a small caller workflow.
The implementation also:
pull_request_targetfor the contributor workflow to safely handle fork-based PRs.Required Setup
For the first-time contributor onboarding workflow:
Configure
PAT_TOKENwith:contents: writepull-requests: writeon the target
Nano-Collective/.githubrepository.Add
contributors.jsontoNano-Collective/.githubwith an initial value of:pull_request_targetworkflow.Testing
Static validation completed:
bash -npasses for all workflowrunblocks.The recommended live test is to merge a PR from a GitHub account with no previous merged PRs in the organization and verify that the contributor onboarding PR is automatically created.
Notes
This is intended as an initial rollout of the automation. Some operational considerations remain, including GitHub search indexing latency and concurrent updates to
contributors.json.