-
Notifications
You must be signed in to change notification settings - Fork 0
feat(stale): add stale action #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+235
−1
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| { | ||
| "actions/semconv/pull-request": "0.0.1", | ||
| "actions/release-please": "0.0.2" | ||
| "actions/release-please": "0.0.2", | ||
| "actions/stale": "0.0.1" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| # stale | ||
|
|
||
| Marks issues and pull requests that have gone quiet, then closes them if they | ||
| stay quiet. A thin, opinionated wrapper around | ||
| [`actions/stale`](https://github.com/actions/stale). | ||
|
|
||
| ## Usage | ||
|
|
||
| The caller owns the schedule. | ||
|
|
||
| ```yaml | ||
| name: Stale | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: '0 3 * * *' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| stale: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| actions: write | ||
| issues: write | ||
| pull-requests: write | ||
| steps: | ||
| - uses: TrogonStack/github-actions/actions/stale@<sha> # vX.Y.Z | ||
| ``` | ||
|
|
||
| `actions: write` is not optional. Upstream keeps its progress in the Actions | ||
| cache so a run capped by `operations-per-run` resumes where the last one | ||
| stopped, and managing that cache entry needs the permission. Without it the | ||
| cache delete fails with a 403, every run replays the same prefix of the | ||
| backlog, and anything past that prefix is never closed. | ||
|
|
||
| Run it once with `debug-only: true` before pointing it at a repository with | ||
| years of backlog, so the first real run is not a surprise. | ||
|
|
||
| ## Labels | ||
|
|
||
| | Label | Meaning | | ||
| | --- | --- | | ||
| | `stale:discard` | Applied by this action. Any activity removes it. | | ||
| | `stale:keep` | Applied by a human. Exempts the issue or pull request forever. | | ||
|
|
||
| Neither label needs to exist beforehand; `stale:discard` is created on first | ||
| use. Create `stale:keep` yourself so it is available in the label picker. | ||
|
|
||
| The names are not inputs. One vocabulary across every repository is the reason | ||
| this action exists, and a rename in one repository is the drift it was built to | ||
| remove. | ||
|
|
||
| ## Inputs | ||
|
|
||
| | Input | Default | Description | | ||
| | --- | --- | --- | | ||
| | `days-before-stale` | `60` | Days without activity before marking stale. | | ||
| | `days-before-close` | `7` | Days after marking before closing. `-1` marks but never closes. | | ||
| | `operations-per-run` | `100` | API operations budget for one run. A run that hits the cap resumes from where it stopped. | | ||
| | `debug-only` | `false` | Report what would happen and change nothing. | | ||
| | `token` | `github.token` | Needs write access to actions, issues, and pull requests. | | ||
|
|
||
| ## Fixed behaviour | ||
|
|
||
| These are not inputs, on purpose. | ||
|
|
||
| - The label names are `stale:discard` and `stale:keep` everywhere. | ||
| - Activity removes the stale label. Activity is the entire signal the action | ||
| runs on, so it has to be able to clear it. | ||
| - Issues close as `not_planned`, which avoids the completed badge on something | ||
| nobody did. | ||
| - Anything on a milestone is exempt. Work on a milestone is planned work, | ||
| however quiet it has gone. | ||
| - Oldest first, so a capped operations budget is spent on the worst offenders | ||
| rather than on whatever is newest. | ||
| - Branches are never deleted. Deleting someone else's branch on a timer is not | ||
| ours to do. | ||
|
|
||
| If you need one of these to differ, that is a conversation about the default | ||
| rather than an input to add. | ||
|
|
||
| ## Outputs | ||
|
|
||
| | Output | Description | | ||
| | --- | --- | | ||
| | `staled-issues-prs` | JSON array of what was marked stale this run. | | ||
| | `closed-issues-prs` | JSON array of what was closed this run. | | ||
|
|
||
| ## Messages | ||
|
|
||
| Closing is not a verdict, and the posted messages say so. What they ask for | ||
| differs by kind, on purpose. | ||
|
|
||
| An issue is closed because nobody is building it, so the message asks for a | ||
| pull request. It deliberately does not offer "leave a comment" as the way to | ||
| revive one: a comment clears the stale label without moving the issue any | ||
| closer to done, which is how a backlog gets kept alive without getting | ||
| shipped. | ||
|
|
||
| A pull request is already the contribution, so the message asks for a commit | ||
| instead, and points at `stale:keep` for the case where the hold-up is a review | ||
| on our side rather than the author. | ||
|
|
||
| Keep that split if you change the wording. | ||
|
|
||
| ## Bumping | ||
|
|
||
| A comment clears the stale label and buys another full cycle, on issues and on | ||
| pull requests alike. That is upstream behaviour and it is not configurable: | ||
|
|
||
| - `remove-stale-when-updated` controls whether an update removes the label, and | ||
| a comment counts as an update. | ||
| - Turning it off does not help. The close gate in `actions/stale` is | ||
| `if (!issueHasCommentsSinceStale && !issueHasUpdateInCloseWindow)`, so any | ||
| human comment after the label blocks closing whatever that option is set to. | ||
| - `ignore-pr-updates` measures from `created_at` instead of `updated_at`, which | ||
| would mark every long lived pull request stale no matter how much work it is | ||
| getting. | ||
|
|
||
| So a determined bump wins, and the messages say plainly that it is a limitation | ||
| rather than the intended path: on a pull request the thing that counts is a | ||
| commit, and a bump leaves the work exactly as unfinished as it was. | ||
|
|
||
| Making commits the real currency would mean taking the pull request lifecycle | ||
| off upstream and measuring it from the head commit date. That is a bigger | ||
| change than this action wants to be today. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| name: Stale | ||
| description: >- | ||
| Marks issues and pull requests that have gone quiet, then closes them if they | ||
| stay quiet. | ||
| author: TrogonStack | ||
|
|
||
| inputs: | ||
| days-before-stale: | ||
| description: Days without activity before an issue or pull request is marked stale. | ||
| required: false | ||
| default: '60' | ||
| days-before-close: | ||
| description: >- | ||
| Days to wait after marking stale before closing. Set to -1 to mark stale | ||
| but never close. | ||
| required: false | ||
| default: '7' | ||
| operations-per-run: | ||
| description: >- | ||
| API operations budget for a single run. Raise it for a busy repository, | ||
| lower it to stay well inside the rate limit. | ||
| required: false | ||
| default: '100' | ||
| debug-only: | ||
| description: >- | ||
| Report what would happen without commenting, labelling, or closing | ||
| anything. Worth one run before enabling this on an old repository. | ||
| required: false | ||
| default: 'false' | ||
| token: | ||
| description: >- | ||
| Token used to comment, label, and close. Needs write access to issues and | ||
| pull requests. | ||
| required: false | ||
| default: ${{ github.token }} | ||
|
|
||
| outputs: | ||
| staled-issues-prs: | ||
| description: JSON array of the issues and pull requests marked stale this run. | ||
| value: ${{ steps.stale.outputs.staled-issues-prs }} | ||
| closed-issues-prs: | ||
| description: JSON array of the issues and pull requests closed this run. | ||
| value: ${{ steps.stale.outputs.closed-issues-prs }} | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Mark and close stale issues and pull requests | ||
| id: stale | ||
| uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 | ||
| with: | ||
| repo-token: ${{ inputs.token }} | ||
|
|
||
| days-before-stale: ${{ inputs.days-before-stale }} | ||
| days-before-close: ${{ inputs.days-before-close }} | ||
|
|
||
| # The label names are deliberately not inputs: one vocabulary across | ||
| # every repository is the reason this action exists. | ||
| stale-issue-label: 'stale:discard' | ||
| stale-pr-label: 'stale:discard' | ||
| exempt-issue-labels: 'stale:keep' | ||
| exempt-pr-labels: 'stale:keep' | ||
|
|
||
| stale-issue-message: | | ||
| No activity for ${{ inputs.days-before-stale }} days. Labelled `stale:discard`, closes in ${{ inputs.days-before-close }} days. Closing is not a no. | ||
|
|
||
| - Do: send a pull request. Add `stale:keep` if you are working on it. | ||
| - Don't: comment to keep it alive. That resets the clock without getting it built. | ||
|
|
||
| stale-pr-message: | | ||
| No activity for ${{ inputs.days-before-stale }} days. Labelled `stale:discard`, closes in ${{ inputs.days-before-close }} days. | ||
|
|
||
| - Do: push a commit. It clears the label. If it is blocked on us, say what it is waiting on and add `stale:keep`. | ||
| - Don't: bump it. That clears the label too, but the work stays unfinished. Let it close and reopen when you can finish. | ||
|
|
||
| close-issue-message: | | ||
| Closed as inactive, not rejected. Still readable, still reopenable. | ||
|
|
||
| - Do: send a pull request and link it here. No need to reopen first. | ||
|
|
||
| close-pr-message: | | ||
| Closed as inactive. The branch is untouched, nothing is lost. | ||
|
|
||
| - Do: reopen it when you are ready to push, or open a fresh pull request from the same branch. | ||
| - Don't: reopen it to say you will get to it soon. That just restarts the countdown. | ||
|
|
||
| operations-per-run: ${{ inputs.operations-per-run }} | ||
| debug-only: ${{ inputs.debug-only }} | ||
|
|
||
| # Opinions this action does not hand back to the caller. | ||
| # Activity is the whole signal, so activity has to clear the label. | ||
| remove-stale-when-updated: true | ||
| # "not_planned" avoids the completed badge on something nobody did. | ||
| close-issue-reason: not_planned | ||
| # Work on a milestone is planned work, however quiet it has gone. | ||
| exempt-all-milestones: true | ||
| # Oldest first, so the operations budget is spent on the worst offenders. | ||
| ascending: true | ||
| # Deleting someone else's branch on a timer is not ours to do. | ||
| delete-branch: false |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.