Skip to content

feat(ci): auto-assign good first issues for new contributors#1179

Merged
muddlebee merged 2 commits intoTracer-Cloud:mainfrom
muddlebee:feat/good-first-issue-auto-assign
May 1, 2026
Merged

feat(ci): auto-assign good first issues for new contributors#1179
muddlebee merged 2 commits intoTracer-Cloud:mainfrom
muddlebee:feat/good-first-issue-auto-assign

Conversation

@muddlebee
Copy link
Copy Markdown
Collaborator

Summary

Adds a GitHub Actions workflow that assigns someone to an issue when they comment on an open issue labeled good first issue, they are not a repo insider (OWNER, MEMBER, or COLLABORATOR), they are not already an assignee, and a search shows zero merged PRs in this repo authored by them. Posts a short issue comment confirming assignment.

Changes

  • .github/scripts/good_first_issue_assign.py — decision logic and notice text
  • .github/workflows/good-first-issue-assign.ymlissue_comment trigger, assign + comment steps
  • tests/github/test_good_first_issue_assign.py — unit tests for screening and decisions

Testing

  • pytest tests/github/test_good_first_issue_assign.py
  • make lint

- Add Actions workflow and script: assign on comment when issue has the label,
  commenter is not OWNER/MEMBER/COLLABORATOR, and merged PR count for the
  author in this repo is zero.
- Post a short assignment notice on the issue.
- Add unit tests for screening, decision logic, and message body.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 1, 2026

Greptile Summary

This PR adds a GitHub Actions workflow and Python script to auto-assign new contributors (zero merged PRs, non-insider) who comment on open good first issue issues. The implementation is clean and the decision logic is well-tested, but there is one correctness bug to address before merging.

  • P1 — PR comment not filtered: issue_comment events fire for PR comments as well as issue comments. Because screen_event_without_api never checks event.issue.pull_request, a new contributor commenting on a PR labeled good first issue will be assigned to the PR rather than the intended issue. Add an early-return guard for issue.pull_request is not None.

Confidence Score: 4/5

One P1 correctness bug (PR comments not filtered) should be fixed before merging; P2 items are non-blocking.

The PR is well-structured with good unit-test coverage and minimal permissions, but the unfiltered PR-comment path in screen_event_without_api is a real behavioural defect that will cause incorrect assignments when the workflow triggers on pull-request comments.

.github/scripts/good_first_issue_assign.py — needs the pull_request guard; .github/workflows/good-first-issue-assign.yml — env-var pattern and concurrency group are recommended improvements.

Security Review

  • Expression injection (P2): ${{ github.event.comment.user.login }}, ${{ github.event.issue.number }}, and ${{ github.repository }} are interpolated directly into the run shell command in .github/workflows/good-first-issue-assign.yml. GitHub usernames are restricted to alphanumeric + hyphens so real injection is not currently possible, but GitHub's own security guidance recommends routing all context values through env: variables to future-proof the workflow.

Important Files Changed

Filename Overview
.github/scripts/good_first_issue_assign.py Core decision logic for screening and assigning new contributors; missing a guard against PR comments (issue_comment events fire for both issues and PRs), which causes unintended assignment to PRs
.github/workflows/good-first-issue-assign.yml Workflow trigger and permissions look correct; inline GitHub expressions in the run step should be passed via env vars per security best practices, and a concurrency group would prevent duplicate assignments
tests/github/test_good_first_issue_assign.py Good coverage of screening and decision paths; no test for the PR-comment edge case (event.issue.pull_request set)

Sequence Diagram

sequenceDiagram
    participant GH as GitHub
    participant WF as Workflow
    participant PY as good_first_issue_assign.py
    participant API as GitHub Search API

    GH->>WF: issue_comment (created)
    WF->>WF: Guard: issue open & commenter not Bot
    WF->>PY: python3 good_first_issue_assign.py
    PY->>PY: screen_event_without_api()
    alt pre-API screen fails
        PY-->>WF: should_assign=false
    else passes pre-API screen
        PY->>API: GET /search/issues?q=repo:… is:merged author:{login}
        API-->>PY: total_count
        PY->>PY: assign_decision(merged_pr_count)
        alt has merged PRs
            PY-->>WF: should_assign=false
        else zero merged PRs
            PY->>PY: write assign_comment.md
            PY-->>WF: should_assign=true
        end
    end
    opt should_assign == true
        WF->>GH: gh issue edit --add-assignee {login}
        WF->>GH: gh issue comment --body-file assign_comment.md
    end
Loading

Reviews (1): Last reviewed commit: "feat(ci): auto-assign good first issues ..." | Re-trigger Greptile

Comment on lines +27 to +36
def screen_event_without_api(event: dict[str, Any]) -> str | None:
"""Return a skip reason before calling the GitHub API, or None if checks should continue."""
issue = event.get("issue") or {}
comment = event.get("comment") or {}
if issue.get("state") != "open":
return "issue_not_open"
labels = issue.get("labels") or []
if not isinstance(labels, list):
return "invalid_labels"
names = {item.get("name") for item in labels if isinstance(item, dict)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 issue_comment fires on PR comments too — missing PR filter

issue_comment events fire for comments on both issues and pull requests. If a PR happens to carry the good first issue label and a first-timer comments on it, screen_event_without_api will pass (the PR is "open", the label is present), and the commenter will be assigned to the PR via gh issue edit <PR_NUMBER> --add-assignee, not the original issue — which is almost certainly unintended.

The fix is to bail out early when the event payload includes issue.pull_request:

if issue.get("pull_request") is not None:
    return "is_pull_request"

A corresponding check at the workflow level (e.g. !github.event.issue.pull_request) would also make the intent explicit.

Comment thread .github/workflows/good-first-issue-assign.yml Outdated
Comment thread .github/workflows/good-first-issue-assign.yml
- Skip issue_comment payloads for PR threads (issue.pull_request set).
- Add concurrency group per repo+issue to avoid parallel duplicate runs.
- Pass gh CLI inputs via env (avoid inline expression interpolation).
- Add unit test for PR-comment screening.
@muddlebee muddlebee merged commit 3d0cc8e into Tracer-Cloud:main May 1, 2026
10 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🧑‍💻 @muddlebee has entered the contributor hall of fame. Merged. Done. Shipped. Go touch grass (then come back with another PR). 🌱


👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant