From 67197b3ab6222bd430c71294a72d97f179934d1f Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 2 Sep 2026 14:21:20 -0700 Subject: [PATCH] ci(github): add stale issue workflow (dry-run) Nightly actions/stale run that labels issues untouched for 90 days as stale and closes them 30 days later. Feature requests are processed in a separate job so they get their own close message. Milestoned issues and Priority: Critical are exempt; pull requests are not touched. Ships with debug-only enabled so the first runs only log what would be labeled/closed. A follow-up removes debug-only once the dry-run output has been reviewed. --- .github/ci-overview.md | 1 + .github/workflows/stale.yml | 93 +++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/ci-overview.md b/.github/ci-overview.md index 22a5d46ca2b..12cf3237567 100644 --- a/.github/ci-overview.md +++ b/.github/ci-overview.md @@ -57,6 +57,7 @@ via composite actions and reusable workflows. Python helpers in `scripts/` are i | `crowdin.yml`, `lupdate.yml` | Translation workflows | | `dependency-review.yml` | Dependency security review | | `scorecard.yml` | OpenSSF Scorecard | +| `stale.yml` | Nightly stale-issue labeling and closing (feature requests get their own close message) | | `flatpak.yml` | Flatpak builds | | `mirror-gstreamer.yml` | Mirror upstream GStreamer releases to the QGC S3 bucket | | `px4-metadata.yml` | PX4 metadata sync | diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000000..4772e4d2699 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,93 @@ +name: Stale Issues + +on: + schedule: + - cron: '30 1 * * *' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +permissions: {} + +jobs: + stale-issues: + name: Stale Issues (non-feature) + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + issues: write + # Required to reset the Actions cache entry that persists resume state between capped runs. + actions: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + + - name: Mark and close stale issues + uses: actions/stale@v11 + with: + # Remove debug-only once the dry-run output has been reviewed. + debug-only: true + days-before-issue-stale: 90 + days-before-issue-close: 30 + days-before-pr-stale: -1 + days-before-pr-close: -1 + remove-pr-stale-when-updated: false + stale-issue-label: stale + exempt-issue-labels: 'Priority: Critical,Feature Request' + exempt-all-issue-milestones: true + remove-issue-stale-when-updated: true + ascending: true + # Dry run: state is not persisted in debug mode, so the cap must cover the whole backlog. + # Lower to 400 when going live: two jobs share the 1000 req/hr GITHUB_TOKEN budget. + operations-per-run: 1500 + # Empty message labels silently to avoid a notification flood on the initial backlog sweep. + stale-issue-message: '' + close-issue-message: > + This issue was automatically closed after 120 days of inactivity. It most likely refers + to a version of QGroundControl that is no longer current. If it is still relevant on the + latest Stable or Daily build, please reopen or file a new issue including the QGC version, + firmware (PX4/ArduPilot) and version, platform, and steps to reproduce. + + stale-features: + name: Stale Feature Requests + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: stale-issues + permissions: + issues: write + actions: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + + - name: Mark and close stale feature requests + uses: actions/stale@v11 + with: + # Remove debug-only once the dry-run output has been reviewed. + debug-only: true + days-before-issue-stale: 90 + days-before-issue-close: 30 + days-before-pr-stale: -1 + days-before-pr-close: -1 + remove-pr-stale-when-updated: false + stale-issue-label: stale + any-of-issue-labels: 'Feature Request' + exempt-issue-labels: 'Priority: Critical' + exempt-all-issue-milestones: true + remove-issue-stale-when-updated: true + ascending: true + # Lower to 400 when going live (see stale-issues). + operations-per-run: 1500 + # Empty message labels silently to avoid a notification flood on the initial backlog sweep. + stale-issue-message: '' + close-issue-message: > + This feature request was automatically closed after 120 days of inactivity. If there is + still interest, please reopen or start a GitHub Discussion so it can be reconsidered.