Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
86 changes: 59 additions & 27 deletions .github/scripts/bot-pr-missing-linked-issue.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,77 @@
module.exports = async ({ github, context }) => {
const body = context.payload.pull_request.body || "";
const isDryRun = process.env.DRY_RUN === 'true';
const prNumber = parseInt(process.env.PR_NUMBER) || context.payload.pull_request.number;

console.log(`Processing PR #${prNumber} (Dry run: ${isDryRun})`);

// For workflow_dispatch, we need to fetch PR details
let prData;
if (context.payload.pull_request) {
prData = context.payload.pull_request;
} else {
// workflow_dispatch case - fetch PR data
const prResponse = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
});
prData = prResponse.data;
}

const body = prData.body || "";
const regex = /\bFixes\s*:?\s*(#\d+)(\s*,\s*#\d+)*/i;

const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});

const alreadyCommented = comments.data.some(comment =>
comment.body.includes("this is LinkBot")
);

if (alreadyCommented) {
console.log('LinkBot already commented on this PR');
return;
}

if (!regex.test(body)) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: [
`Hi @${context.payload.pull_request.user.login}, this is **LinkBot** 👋`,
``,
`Linking pull requests to issues helps us significantly with reviewing pull requests and keeping the repository healthy.`,
``,
`🚨 **This pull request does not have an issue linked.**`,
``,
`Please link an issue using the following format:`,
`- Fixes #123`,
``,
`📖 Guide:`,
`[docs/sdk_developers/training/workflow/how_to_link_issues.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/docs/sdk_developers/training/workflow/how_to_link_issues.md)`,
``,
`If no issue exists yet, please create one:`,
`[docs/sdk_developers/creating_issues.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/docs/sdk_developers/creating_issues.md)`,
``,
`Thanks!`
].join('\n')
});
const commentBody = [
`Hi @${prData.user.login}, this is **LinkBot** 👋`,
``,
`Linking pull requests to issues helps us significantly with reviewing pull requests and keeping the repository healthy.`,
``,
`🚨 **This pull request does not have an issue linked.**`,
``,
`Please link an issue using the following format:`,
`- Fixes #123`,
``,
`📖 Guide:`,
`[docs/sdk_developers/training/workflow/how_to_link_issues.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/docs/sdk_developers/training/workflow/how_to_link_issues.md)`,
``,
`If no issue exists yet, please create one:`,
`[docs/sdk_developers/creating_issues.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/docs/sdk_developers/creating_issues.md)`,
``,
`Thanks!`
].join('\n');

if (isDryRun) {
console.log('DRY RUN: Would post the following comment:');
console.log('---');
console.log(commentBody);
console.log('---');
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody,
});
console.log('LinkBot comment posted successfully');
}
} else {
console.log('PR has linked issue - no comment needed');
}
};

20 changes: 18 additions & 2 deletions .github/workflows/bot-pr-missing-linked-issue.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
name: PR Missing Linked Issue Reminder

on:
pull_request:
pull_request_target:
types: [opened, edited, reopened]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to check'
required: true
type: number
dry_run:
description: 'Dry run (only log, no comments)'
required: false
type: boolean
default: false

permissions:
pull-requests: write
contents: read
issues: write

jobs:
check-linked-issue:
runs-on: ubuntu-latest

concurrency:
group: bot-pr-missing-linked-issue-${{ github.event.pull_request.number }}
group: bot-pr-missing-linked-issue-${{ github.event.pull_request.number || github.event.inputs.pr_number }}
cancel-in-progress: true

steps:
Expand All @@ -24,10 +36,14 @@ jobs:

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

- name: Check PR body for linked issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DRY_RUN: ${{ github.event.inputs.dry_run || 'false' }}
PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- Workflow does not contain permissions for `pr-check-test-files` and `pr-check-codecov`
- Fixed `cron-check-broken-links.yml` string parsing issue in context input `dry_run` (#1235)
- Flaky tests by disabling TLS in mock Hedera nodes in `mock_server.py`
- Fixed LinkBot permission issue for fork PRs by changing trigger to pull_request_target and adding proper permissions.

### Breaking Change

Expand Down