Skip to content

feat: /assign self-assignment for good first issue (#62)#64

Open
rtibblesbot wants to merge 12 commits intolearningequality:mainfrom
rtibblesbot:issue-62-1abd3e
Open

feat: /assign self-assignment for good first issue (#62)#64
rtibblesbot wants to merge 12 commits intolearningequality:mainfrom
rtibblesbot:issue-62-1abd3e

Conversation

@rtibblesbot
Copy link
Contributor

@rtibblesbot rtibblesbot commented Mar 19, 2026

Summary

Implements the /assign self-assignment mechanism for good first issue issues, as agreed in #47.

Contributors can comment /assign on issues labeled help wanted + good first issue to self-assign, subject to a 2-issue cross-repo limit and 7-day cooldown on recently dropped issues. The bot posts a guidance comment when the good first issue label is applied, and keyword-based assignment requests on GFI issues now include /assign guidance.

All /assign Slack notifications route to #support-dev-notifications only.

References

Reviewer guidance

Manual testing is done in test-actions. Temporarily update reusable workflow references to point to this branch.

Key test scenarios:

  • Comment /assign on an unassigned help wanted + good first issue issue → bot assigns and confirms
  • Comment /assign when at the 2-issue limit → bot declines with assignment list and cooldown info
  • Add good first issue label to a help wanted issue → bot posts guidance comment
  • Comment "can I work on this" on a GFI issue → bot replies with /assign guidance

Risky areas:

  • Cross-repo limit checking via search API + timeline events (scripts/utils.js:getRecentUnassignments) — depends on GitHub search indexing latency and timeline event format
  • Unassignment deduplication logic (scripts/utils.js ~line 320) — ensures multiple assign/unassign cycles on the same issue count as one slot
  • /assign decision tree in handleAssignCommand (scripts/contributor-issue-comment.js) — many branches with specific Slack routing per path

AI usage

Built entirely by Claude Code following a detailed implementation plan (see PLAN/index.md). Each task was implemented incrementally with tests written alongside. Code was reviewed for correctness after each step, and all 34 tests pass.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

rtibblesbot and others added 12 commits March 19, 2026 12:18
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rningequality#62)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ality#62)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…equality#62)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove unused `labels` parameter from `makeContext`, unused `opts`
parameter from paginate mock, and unused `mockGithub` helper function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rningequality#62)

getRecentUnassignments could return multiple unassignment events for the
same issue if a user was assigned/unassigned multiple times within the
cooldown window, inflating the slot count and unfairly blocking
contributors. Deduplicate by issueUrl, keeping the most recent event.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ity#62)

- Extract sendAssignReplyAndNotify to reduce duplication in handleAssignCommand
- Add getLabels utility for fetching labels once and checking multiple
- Parallelize getRecentUnassignments across repos with Promise.all
- Extract shared mockCore test helper to test-helpers.js

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ingequality#62)

The `shouldSendBotReply` keyword GFI condition used
`!isIssueAssignedToSomeoneElse` which is true both when unassigned and
when assigned to the commenter. This caused an already-assigned
contributor using keywords to get a misleading "comment /assign to
assign yourself" message.

Add `isUnassigned` parameter to distinguish the two cases, and add a
test verifying the fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
)

Adds a test verifying that 1 assigned issue + 1 cooldown issue correctly
triggers the at-limit rejection, exercising the filteredUnassignments logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The yarn.lock was not committed when jest was added to
devDependencies in package.json. Without this update,
`yarn install --frozen-lockfile` fails in CI workflows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rtibblesbot rtibblesbot marked this pull request as ready for review March 19, 2026 20:06
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.

Implement /assign self-assignment for good first issue issues

1 participant