<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46790 Example live run off this branch: https://github.com/fleetdm/fleet/actions/runs/27005120262 Example stale issue with comment: https://github.com/fleetdm/fleet/issues/18421 - Added `@author` mention when marking issue as stale - Refactored so that both Fleetie and eng-initiated stale issue bots use the same core JS code - Run Fleetie-initiated workflow on a schedule <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Automated stale-issue workflows for engineering-initiated and Fleetie issues with configurable dry-run, max-operations, manual triggers, and scheduled runs. * **Tests** * Added shared test helpers and expanded, tightened test suites covering staleness, closing, unstale, and error/boundary behaviors. * **Refactor** * Introduced a shared stale-issue engine used by thin, author/label-based wrappers for consistent behavior and messaging. * **Chores** * Updated workflow triggers, permissions, and CI test matrix to include the new core and wrappers. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
88 lines
3.8 KiB
YAML
88 lines
3.8 KiB
YAML
name: Close stale Fleetie-initiated issues
|
|
|
|
# Marks open issues authored by current or former Fleeties as stale after 2 years of no activity, then
|
|
# closes them after 14 more days of inactivity once labeled stale. Activity (any comment or update) bumps
|
|
# `updated_at` and resets both clocks. Issues with the `bug`, `:product`, or any `customer-*` label are
|
|
# exempt.
|
|
#
|
|
# Why this isn't just `actions/stale`: that action filters by labels, not by author. We can't pre-tag
|
|
# issues with a "fleetie-initiated" label and hand off to actions/stale either, because adding a label
|
|
# bumps `updated_at` and resets the staleness clock for the entire backlog. The closest upstream PR is
|
|
# https://github.com/actions/stale/pull/1181 (`anyOfAuthors` allowlist input). It has been open with no
|
|
# review since October 2024. When it merges, we should be able to replace this whole flow with a small
|
|
# `actions/stale` config that passes the handle list from `build-fleetie-handles.js` as `anyOfAuthors`
|
|
# and delete `stale-fleetie-issues.js` and its tests.
|
|
|
|
on:
|
|
schedule:
|
|
# Daily at 9:10pm CDT (2:10am UTC) -- off-hours to prevent hitting the GitHub API rate limit,
|
|
# and one hour after the eng-initiated closer so the two bots don't compete for the same budget.
|
|
- cron: "10 2 * * *"
|
|
workflow_dispatch: # Manual
|
|
inputs:
|
|
dry_run:
|
|
description: 'If true, log candidates without writing labels, comments, or closing issues.'
|
|
type: boolean
|
|
default: true
|
|
max_operations:
|
|
description: 'Maximum GitHub API write operations per run. Each modified issue costs 2 writes (comment + label, or comment + close).'
|
|
type: number
|
|
default: 400
|
|
|
|
concurrency:
|
|
# Scope by event_name + ref so a pull_request trigger doesn't preempt an in-flight
|
|
# workflow_dispatch run, and vice versa. Same-event same-ref runs still cancel as expected.
|
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
close-stale-fleetie-issues:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repo
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: '24'
|
|
|
|
- name: Build Fleetie handle list
|
|
env:
|
|
# Fine-scoped PAT with read:org on the fleetdm org. Provisioned by IT; without it the script
|
|
# falls back to handbook-only sources and emits a warning.
|
|
READ_ORG_TOKEN: ${{ secrets.FLEET_GITHUB_TOKEN_MEMBERS_READ }}
|
|
FLEETIE_HANDLES_OUT: ${{ runner.temp }}/fleeties.txt
|
|
run: node .github/scripts/build-fleetie-handles.js
|
|
|
|
- name: Stale and close Fleetie-authored issues
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
FLEETIE_HANDLES_FILE: ${{ runner.temp }}/fleeties.txt
|
|
# Schedule runs always run live. Manual runs honor the dry_run input (default true).
|
|
DRY_RUN: ${{ (github.event_name == 'workflow_dispatch' && inputs.dry_run == true) && 'true' || 'false' }}
|
|
# parseMaxOps in the script applies the 400 default when the value is empty.
|
|
MAX_OPERATIONS: ${{ inputs.max_operations }}
|
|
with:
|
|
script: |
|
|
const run = require('./.github/scripts/stale-fleetie-issues.js');
|
|
await run({ github, context, core });
|