Improving stale issue workflow (#45767)

Refactor stale issue formatting to use HTML lists for improved rendering
in GitHub Actions summary; update workflow dependencies to latest
versions.

Example run (see summary):
https://github.com/fleetdm/fleet/actions/runs/26101161627

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #45700 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated GitHub Actions and automation dependencies to latest versions
  * Improved stale issue management workflow formatting and logic

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45767?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2026-05-20 16:19:39 -05:00
committed by GitHub
parent bc72cc105b
commit ed5f0c135f
3 changed files with 26 additions and 35 deletions
+19 -28
View File
@@ -314,23 +314,17 @@ async function run({ github, context, core }) {
}
}
const fmt = (list) =>
list.length
? list
.map(
(e) =>
`- [#${e.number}](${e.url}) by @${
e.author
} (idle ${e.idleDays.toFixed(1)}d)`
)
.join("\n")
: "_none_";
const fmtErrors = (list) =>
list.length
? list.map((e) => `- #${e.number} (${e.phase}): ${e.message}`).join("\n")
: "_none_";
// Each entry is an HTML <li> so it renders correctly inside <ul>. We use raw <a> tags rather
// than markdown links because GitHub Actions summary surrounds list content with HTML blocks
// (from addHeading / addList), which suspends markdown parsing for child content — markdown
// bullets via addRaw collapse onto one line in that context.
const fmtItem = (e) =>
`<a href="${e.url}">#${e.number}</a> by @${e.author} (idle ${e.idleDays.toFixed(1)}d)`;
const fmtErrorItem = (e) => `#${e.number} (${e.phase}): ${e.message}`;
const appendList = (s, items, fn) =>
items.length ? s.addList(items.map(fn)) : s.addRaw("_none_").addEOL();
await core.summary
let summary = core.summary
.addHeading("Fleetie stale-issue closer")
.addRaw(`Mode: **${dryRun ? "dry-run" : "live"}**`)
.addBreak()
@@ -347,18 +341,15 @@ async function run({ github, context, core }) {
`Un-staled this run (activity after label): ${unstaled.length}`,
`Errors: ${errored.length}`,
])
.addHeading("Marked stale", 3)
.addRaw(fmt(staled))
.addBreak()
.addHeading("Closed", 3)
.addRaw(fmt(closed))
.addBreak()
.addHeading("Un-staled (activity after label)", 3)
.addRaw(fmt(unstaled))
.addBreak()
.addHeading("Errors", 3)
.addRaw(fmtErrors(errored))
.write();
.addHeading("Marked stale", 3);
summary = appendList(summary, staled, fmtItem);
summary = summary.addHeading("Closed", 3);
summary = appendList(summary, closed, fmtItem);
summary = summary.addHeading("Un-staled (activity after label)", 3);
summary = appendList(summary, unstaled, fmtItem);
summary = summary.addHeading("Errors", 3);
summary = appendList(summary, errored, fmtErrorItem);
await summary.write();
// Returned for test assertions only. The production caller (the workflow) discards this and
// reads `core.summary` instead.
@@ -46,17 +46,17 @@ jobs:
issues: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
with:
egress-policy: audit
- name: Checkout repo
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'
@@ -69,7 +69,7 @@ jobs:
run: node .github/scripts/build-fleetie-handles.js
- name: Stale and close Fleetie-authored issues
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
FLEETIE_HANDLES_FILE: ${{ runner.temp }}/fleeties.txt
# Force dry-run for every event other than workflow_dispatch.
@@ -46,17 +46,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
with:
egress-policy: audit
- name: Checkout repo
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 4.4.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24'