From a5e97b5b6c98e66c862201e980051f479b04d230 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Thu, 12 Feb 2026 23:32:45 -0700 Subject: [PATCH 1/6] Migrate issue triage workflows to shared workflows --- .github/workflows/feature-request-comment.yml | 36 --------- .github/workflows/issueauto.yml | 25 ------- .../scripts/spam-detection/eval-prompts.yml | 2 +- .github/workflows/stale-issues.yml | 2 +- .github/workflows/triage-issues.yml | 61 +++++++++++++++ .github/workflows/triage-scheduled-tasks.yml | 13 ++++ .github/workflows/triage.yml | 74 +++---------------- docs/triage.md | 14 ++-- 8 files changed, 94 insertions(+), 133 deletions(-) delete mode 100644 .github/workflows/feature-request-comment.yml delete mode 100644 .github/workflows/issueauto.yml create mode 100644 .github/workflows/triage-issues.yml create mode 100644 .github/workflows/triage-scheduled-tasks.yml diff --git a/.github/workflows/feature-request-comment.yml b/.github/workflows/feature-request-comment.yml deleted file mode 100644 index 8426d7af2d9..00000000000 --- a/.github/workflows/feature-request-comment.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Add feature-request comment -on: - issues: - types: - - labeled - -permissions: - issues: write - -jobs: - add-comment-to-feature-request-issues: - if: github.event.label.name == 'enhancement' - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - NUMBER: ${{ github.event.issue.number }} - BODY: > - Thank you for your issue! We have categorized it as a feature request, - and it has been added to our backlog. In doing so, **we are not - committing to implementing this feature at this time**, but, we will - consider it for future releases based on community feedback and our own - product roadmap. - - - Unless you see the - https://github.com/cli/cli/labels/help%20wanted label, we are - not currently looking for external contributions for this feature. - - - **If you come across this issue and would like to see it implemented, - please add a thumbs up!** This will help us prioritize the feature. - Please only comment if you have additional information or viewpoints to - contribute. - steps: - - run: gh issue comment "$NUMBER" --body "$BODY" diff --git a/.github/workflows/issueauto.yml b/.github/workflows/issueauto.yml deleted file mode 100644 index cfdcff7644a..00000000000 --- a/.github/workflows/issueauto.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Issue Automation -on: - issues: - types: [opened] - -permissions: - contents: none - issues: write - -jobs: - issue-auto: - runs-on: ubuntu-latest - environment: cli-automation - steps: - - name: label incoming issue - env: - GH_REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.AUTOMATION_TOKEN }} - ISSUENUM: ${{ github.event.issue.number }} - ISSUEAUTHOR: ${{ github.event.issue.user.login }} - run: | - if ! gh api orgs/cli/public_members/$ISSUEAUTHOR --silent 2>/dev/null - then - gh issue edit $ISSUENUM --add-label "needs-triage" - fi \ No newline at end of file diff --git a/.github/workflows/scripts/spam-detection/eval-prompts.yml b/.github/workflows/scripts/spam-detection/eval-prompts.yml index 15c61ff76f3..6911013882f 100644 --- a/.github/workflows/scripts/spam-detection/eval-prompts.yml +++ b/.github/workflows/scripts/spam-detection/eval-prompts.yml @@ -918,7 +918,7 @@ testData: We have an automation to nudge on issues waiting for user info (like after one week), and close the issue if there's no further activity (like after one more week). - - Automatically add the stale label to issues labelled needs-user-input after 30 days of inactivity. When the stale label is added, also post a comment to the issue explaining what this means: the issue will close after 30 days of inactivity; contributors can comment on the issue to remove the stale label and keep it open. Maintainers can also add the keep label to make the stale automation ignore that issue. + - Automatically add the stale label to issues labelled more-info-needed after 30 days of inactivity. When the stale label is added, also post a comment to the issue explaining what this means: the issue will close after 30 days of inactivity; contributors can comment on the issue to remove the stale label and keep it open. Maintainers can also add the keep label to make the stale automation ignore that issue. - Automatically close issues labelled stale after they have been stale for 30 days. When the issue is closed, add a comment explaining why this happened. Encourage them to leave a comment if the close was done in error. - The above automation should only act on new issues after the date of the automation's implementation. diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml index 543a909c8a7..d4c5967aa43 100644 --- a/.github/workflows/stale-issues.yml +++ b/.github/workflows/stale-issues.yml @@ -15,7 +15,7 @@ jobs: start-date: "2025-07-10T00:00:00Z" # Skip for issues created before this date days-before-issue-stale: 30 only-issue-labels: - "needs-triage,needs-user-input" # Only issues with all of these labels can be marked as stale + "needs-triage,more-info-needed" # Only issues with all of these labels can be marked as stale exempt-issue-labels: "keep" # Issues marked with this label should not be marked as stale stale-issue-label: "stale" # Mark stale issues with this label stale-issue-message: | diff --git a/.github/workflows/triage-issues.yml b/.github/workflows/triage-issues.yml new file mode 100644 index 00000000000..199952ee2ff --- /dev/null +++ b/.github/workflows/triage-issues.yml @@ -0,0 +1,61 @@ +name: Issue Triaging +on: + issues: + types: [opened, reopened, labeled, unlabeled, closed] + +jobs: + label-incoming: + if: github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'unlabeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-label-incoming.yml@main + permissions: + issues: write + + close-invalid: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-close-invalid.yml@main + permissions: + contents: read + issues: write + pull-requests: write + + close-suspected-spam: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-close-suspected-spam.yml@main + permissions: + issues: write + + close-single-word: + if: github.event.action == 'opened' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-close-single-word-issues.yml@main + permissions: + issues: write + + close-off-topic: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-close-off-topic.yml@main + permissions: + issues: write + + enhancement-comment: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-enhancement-comment.yml@main + permissions: + issues: write + + unable-to-reproduce: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-unable-to-reproduce-comment.yml@main + permissions: + issues: write + + remove-needs-triage: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-remove-needs-triage.yml@main + permissions: + issues: write + + on-issue-close: + if: github.event.action == 'closed' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-on-issue-close.yml@main + permissions: + issues: write diff --git a/.github/workflows/triage-scheduled-tasks.yml b/.github/workflows/triage-scheduled-tasks.yml new file mode 100644 index 00000000000..721e899f364 --- /dev/null +++ b/.github/workflows/triage-scheduled-tasks.yml @@ -0,0 +1,13 @@ +name: Triage Scheduled Tasks +on: + workflow_dispatch: + issue_comment: + types: [created] + schedule: + - cron: '5 * * * *' # Hourly — no-response close + +jobs: + no-response: + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-no-response-close.yml@main + permissions: + issues: write diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index a2ca1716068..20eca49c8e5 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -5,70 +5,18 @@ on: issues: types: - labeled + # pull_request_target (not pull_request) to access secrets for fork PRs. + # Safe: no PR code is checked out or executed. pull_request_target: types: - labeled -env: - TARGET_REPO: github/cli -jobs: - issue: - environment: cli-discuss-automation - runs-on: ubuntu-latest - if: github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'discuss' - steps: - - name: Create issue based on source issue - env: - BODY: ${{ github.event.issue.body }} - CREATED: ${{ github.event.issue.created_at }} - GH_TOKEN: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }} - LINK: ${{ github.repository }}#${{ github.event.issue.number }} - TITLE: ${{ github.event.issue.title }} - TRIGGERED_BY: ${{ github.triggering_actor }} - run: | - # Markdown quote source body by replacing newlines for newlines and markdown quoting - BODY="${BODY//$'\n'/$'\n'> }" - - # Create issue using dynamically constructed body within heredoc - cat << EOF | gh issue create --title "Triage issue \"$TITLE\"" --body-file - --repo "$TARGET_REPO" --label triage - **Title:** $TITLE - **Issue:** $LINK - **Created:** $CREATED - **Triggered by:** @$TRIGGERED_BY - - --- - - cc: @github/cli - - > $BODY - EOF - pull_request: - runs-on: ubuntu-latest - environment: cli-discuss-automation - if: github.event_name == 'pull_request_target' && github.event.action == 'labeled' && github.event.label.name == 'discuss' - steps: - - name: Create issue based on source pull request - env: - BODY: ${{ github.event.pull_request.body }} - CREATED: ${{ github.event.pull_request.created_at }} - GH_TOKEN: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }} - LINK: ${{ github.repository }}#${{ github.event.pull_request.number }} - TITLE: ${{ github.event.pull_request.title }} - TRIGGERED_BY: ${{ github.triggering_actor }} - run: | - # Markdown quote source body by replacing newlines for newlines and markdown quoting - BODY="${BODY//$'\n'/$'\n'> }" - - # Create issue using dynamically constructed body within heredoc - cat << EOF | gh issue create --title "Triage PR \"$TITLE\"" --body-file - --repo "$TARGET_REPO" --label triage - **Title:** $TITLE - **Pull request:** $LINK - **Created:** $CREATED - **Triggered by:** @$TRIGGERED_BY - - --- - - cc: @github/cli - - > $BODY - EOF +jobs: + discuss: + if: github.event.action == 'labeled' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-discuss.yml@main + with: + target_repo: 'github/cli' + cc_team: '@github/cli' + secrets: + discussion_token: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }} diff --git a/docs/triage.md b/docs/triage.md index ea119994c40..54443345fd3 100644 --- a/docs/triage.md +++ b/docs/triage.md @@ -14,16 +14,16 @@ For bugs, the FR should engage with the issue and community with the goal to rem To be considered triaged, `bug` issues require the following: -- A severity label `p1`, `p2`, and `p3` +- A severity label `priority-1`, `priority-2`, and `priority-3` - Clearly defined Acceptance Criteria, added to the Issue as a standalone comment (see [example](https://github.com/cli/cli/issues/9469#issuecomment-2292315743)) #### Bug severities | Severity | Description | | - | - | -| `p1` | Affects a large population and inhibits work | -| `p2` | Affects more than a few users but doesn't prevent core functions | -| `p3` | Affects a small number of users or is largely cosmetic | +| `priority-1` | Affects a large population and inhibits work | +| `priority-2` | Affects more than a few users but doesn't prevent core functions | +| `priority-3` | Affects a small number of users or is largely cosmetic | ### Enhancements and Docs @@ -36,10 +36,10 @@ When a new issue is opened, the FR **should**: - Ensure there is enough information to understand the enhancement's scope and value - Ask the user for more information about value and use-case, if necessary - Leave the `needs-triage` label on the issue -- Add the `needs-user-input` and `needs-investigation` labels as needed +- Add the `more-info-needed` and `needs-investigation` labels as needed When the FR has enough information to be triaged, they should: -- Remove the `needs-user-input` and `needs-investigation` labels +- Remove the `more-info-needed` and `needs-investigation` labels - Remove their assignment from the issue The FR should **avoid**: @@ -57,7 +57,7 @@ The FR can consider adding any of the following labels below. | - | - | | `discuss` | Some issues require discussion with the internal team. Adding this label will automatically open up an internal discussion with the team to facilitate this discussion. | | `core` | Defines what we would like to do internally. We tend to lean towards `help wanted` by default, and adding `core` should be reserved for trickier issues or implementations we have strong opinions/preferences about. | -| `needs-user-input` | After asking any contributors for more information, add this label so it is clear that the issue has been responded to and we are waiting on the user. | +| `more-info-needed` | After asking any contributors for more information, add this label so it is clear that the issue has been responded to and we are waiting on the user. | | `needs-investigation` | Used when the issue requires further investigation before it can be reviewed and triaged. This is often used for issues that are not clearly bugs or enhancements, or when the FR needs to gather more information before proceeding. | | `invalid` | Added to spam and abusive issues. | From f1ebf6f8d99b2e84188b97062040a080a1cf471b Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:17:33 -0700 Subject: [PATCH 2/6] Migrate stale workflow to shared workflow --- .github/workflows/stale-issues.yml | 36 -------------------- .github/workflows/triage-scheduled-tasks.yml | 13 +++++++ 2 files changed, 13 insertions(+), 36 deletions(-) delete mode 100644 .github/workflows/stale-issues.yml diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml deleted file mode 100644 index d4c5967aa43..00000000000 --- a/.github/workflows/stale-issues.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Marks/closes stale issues -on: - schedule: - - cron: "0 3 * * *" # 3 AM UTC - -permissions: - issues: write - -jobs: - mark-stale-issues: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v10 - with: - start-date: "2025-07-10T00:00:00Z" # Skip for issues created before this date - days-before-issue-stale: 30 - only-issue-labels: - "needs-triage,more-info-needed" # Only issues with all of these labels can be marked as stale - exempt-issue-labels: "keep" # Issues marked with this label should not be marked as stale - stale-issue-label: "stale" # Mark stale issues with this label - stale-issue-message: | - This issue has been automatically marked as stale because it has not had any activity in the last 30 days, - and it will be closed in 30 days if no further activity occurs. - - If you think this is a mistake, please comment on this issue to keep it open. - - days-before-issue-close: 30 - close-issue-reason: "not_planned" - close-issue-message: | - This issue has been automatically closed due to inactivity. - - If you think this is a mistake, please comment on this issue. - - # Exclude PRs from closing or being marked as stale - days-before-pr-stale: -1 - days-before-pr-close: -1 diff --git a/.github/workflows/triage-scheduled-tasks.yml b/.github/workflows/triage-scheduled-tasks.yml index 721e899f364..8dd0793b209 100644 --- a/.github/workflows/triage-scheduled-tasks.yml +++ b/.github/workflows/triage-scheduled-tasks.yml @@ -5,9 +5,22 @@ on: types: [created] schedule: - cron: '5 * * * *' # Hourly — no-response close + - cron: '0 3 * * *' # Daily at 3 AM UTC — stale issues jobs: no-response: uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-no-response-close.yml@main permissions: issues: write + + stale: + if: github.event.schedule == '0 3 * * *' + uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-stale-issues.yml@main + with: + days_before_stale: 30 + days_before_close: -1 + start_date: '2025-07-10T00:00:00Z' + stale_issue_label: 'stale' + exempt_issue_labels: 'keep' + permissions: + issues: write From 772e677e735409e945b30533ac0d362b1986ebbd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:03:42 +0000 Subject: [PATCH 3/6] Initial plan From 8e6cdf7059b65d57acb8abf86c30ee40e63af618 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:05:39 +0000 Subject: [PATCH 4/6] Add missing environment and label check to triage workflow Co-authored-by: BagToad <47394200+BagToad@users.noreply.github.com> --- .github/workflows/triage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 20eca49c8e5..8a80efdf562 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -13,7 +13,8 @@ on: jobs: discuss: - if: github.event.action == 'labeled' + if: github.event.action == 'labeled' && github.event.label.name == 'discuss' + environment: cli-discuss-automation uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-discuss.yml@main with: target_repo: 'github/cli' From e861681139365fd0f31a4a96c915900df3d80e37 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Tue, 17 Feb 2026 07:27:01 -0700 Subject: [PATCH 5/6] Pass environment as input to shared triage workflow The `environment` property cannot be set at the job level when using `uses:` to call a reusable workflow. Pass it as a workflow input instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/triage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 8a80efdf562..84fd7652800 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -14,10 +14,10 @@ on: jobs: discuss: if: github.event.action == 'labeled' && github.event.label.name == 'discuss' - environment: cli-discuss-automation uses: desktop/gh-cli-and-desktop-shared-workflows/.github/workflows/triage-discuss.yml@main with: target_repo: 'github/cli' cc_team: '@github/cli' + environment: cli-discuss-automation secrets: discussion_token: ${{ secrets.CLI_DISCUSSION_TRIAGE_TOKEN }} From e1983ce4579888774d522ebc07753cad856d24f0 Mon Sep 17 00:00:00 2001 From: Kynan Ware <47394200+BagToad@users.noreply.github.com> Date: Tue, 17 Feb 2026 07:32:35 -0700 Subject: [PATCH 6/6] Rename triage workflow to triage-discussion-label Rename .github/workflows/triage.yml to .github/workflows/triage-discussion-label.yml and update the workflow name from "Discussion Triage" to "Process Discuss Label" to better reflect its intent. --- .github/workflows/{triage.yml => triage-discussion-label.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{triage.yml => triage-discussion-label.yml} (96%) diff --git a/.github/workflows/triage.yml b/.github/workflows/triage-discussion-label.yml similarity index 96% rename from .github/workflows/triage.yml rename to .github/workflows/triage-discussion-label.yml index 84fd7652800..e2e4ea5e58a 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage-discussion-label.yml @@ -1,4 +1,4 @@ -name: Discussion Triage +name: Process Discuss Label run-name: ${{ github.event_name == 'issues' && github.event.issue.title || github.event.pull_request.title }} permissions: {} on: