Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/scripts/bot-gfi-assign-on-comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// .github/scripts/gfi_assign_on_comment.js
//
// Assigns human user to Good First Issue when they comment "/assign".
// Posts a comment if the issue is already assigned.
// All other validation and additional GFI comments are handled by other existing bots which can be refactored with time.

const GOOD_FIRST_ISSUE_LABEL = 'Good First Issue';
const UNASSIGNED_GFI_SEARCH_URL =
'https://github.com/hiero-ledger/hiero-sdk-python/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Good%20First%20Issue%22%20no%3Aassignee';

/// HELPERS FOR ASSIGNING ///

/**
* Returns true if /assign appears at the start of a line or comment
* Optionally preceded or followed by whitespace
*/
function commentRequestsAssignment(body) {
return typeof body === 'string' &&
/(^|\n)\s*\/assign(\s|$)/i.test(body);
}

/**
* Returns true if the issue has the good first issue label.
*/
function issueIsGoodFirstIssue(issue) {
return issue?.labels?.some(label => label.name === GOOD_FIRST_ISSUE_LABEL);
}

/// HELPERS FOR COMMENTING ///

/**
* Returns a formatted @username for the current assignee of the issue.
*/
function getCurrentAssigneeMention(issue) {
const login = issue?.assignees?.[0]?.login;
return login ? `@${login}` : 'someone';
}

/**
* Builds a comment explaining that the issue is already assigned.
* Requester username is passed from main
*/
function commentAlreadyAssigned(requesterUsername, issue) {
return (
`Hi @${requesterUsername} — this issue is already assigned to ${getCurrentAssigneeMention(issue)}, so I can’t assign it again.

👉 **Choose a different Good First Issue to work on next:**
[Browse unassigned Good First Issues](${UNASSIGNED_GFI_SEARCH_URL})

Once you find one you like, comment \`/assign\` to get started.`
);
}


/// START OF SCRIPT ///
module.exports = async ({ github, context }) => {
const { issue, comment } = context.payload;
const { owner, repo } = context.repo;

// Reject if issue, comment or comment user is missing, reject bots, or if no /assign message
if (
!issue?.number ||
!comment?.body ||
!comment?.user?.login ||
comment.user.type === 'Bot' ||
!commentRequestsAssignment(comment.body)
) {
return;
}
// Reject if issue is not a Good First Issue
if (!issueIsGoodFirstIssue(issue)) return;

// Get requester username and issue number to enable comments and assignments
const requesterUsername = comment.user.login;
const issueNumber = issue.number;

// Reject if issue is already assigned
// Comment failure to the requester
if (issue.assignees?.length > 0) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: commentAlreadyAssigned(requesterUsername, issue),
});
return;
}

// All validations passed and user has requested assignment on a GFI
// Assign the issue to the requester
// Do not comment on success
await github.rest.issues.addAssignees({
owner,
repo,
issue_number: issueNumber,
assignees: [requesterUsername],
});
};
38 changes: 38 additions & 0 deletions .github/workflows/bot-gfi-assign-on-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: GFI Assign on /assign

on:
issue_comment:
types:
- created

permissions:
issues: write
contents: read

jobs:
gfi-assign:
# Only run on issue comments (not PR comments)
if: github.event.issue.pull_request == null

runs-on: ubuntu-latest

# Prevent race conditions: always wait for the first assignment request to finish processing
concurrency:
group: gfi-assign-${{ github.event.issue.number }}
cancel-in-progress: false

steps:
- name: Harden runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Run GFI /assign handler
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
with:
script: |
const script = require('./.github/scripts/bot-gfi-assign-on-comment.js');
await script({ github, context });
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
## [Unreleased]

### Added
- Enable auto assignment to good first issues (#1312)
- Added unit test for 'endpoint.py' to increase coverage.
- Automated assignment guard for `advanced` issues; requires completion of at least one `good first issue` and one `intermediate` issue before assignment (exempts maintainers, committers, and triage members). (#1142)
- Added Hbar object support for TransferTransaction HBAR transfers:
Expand Down
Loading