diff --git a/.github/workflows/inactive-issues.yml b/.github/workflows/inactive-issues.yml new file mode 100644 index 0000000000..6f1b64d47a --- /dev/null +++ b/.github/workflows/inactive-issues.yml @@ -0,0 +1,35 @@ +on: + issues: + types: labeled + workflow_dispatch: + schedule: + - cron: '*/5 * * * *' + +permissions: + issues: write + contents: read + +name: Label and close issues with no recent activity + +env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEEDS_ATTENTION_LABEL: "Needs attention" + NEEDS_AUTHOR_FEEDBACK_LABEL: "Needs author feedback" + NO_RECENT_ACTIVITY_LABEL: "No recent activity" + NO_RECENT_ACTIVITY_DURATION_IN_DAYS: 7 + NO_RECENT_ACTIVITY_DURATION_CLOSE_IN_DAYS: 28 + ORG_NAME: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + NO_RECENT_ACTIVITY_COMMENT: "This issue has been labeled with `No recent activity` because there has been no recent activity. It will be closed if no further activity occurs within 28 days. Please re-open this issue or open a new one after this delay if you need to." + + +jobs: + run: + runs-on: ubuntu-latest + name: Label issues with no recent activity + steps: + - uses: actions/checkout@v4 + - run: scripts/label-no-recent.ps1 + shell: pwsh + - run: scripts/close-no-recent.ps1 + shell: pwsh diff --git a/scripts/close-no-recent.ps1 b/scripts/close-no-recent.ps1 new file mode 100644 index 0000000000..4923e5a7d5 --- /dev/null +++ b/scripts/close-no-recent.ps1 @@ -0,0 +1,18 @@ +$inactivityDelay = [timespan]::FromDays([int]::Parse($Env:NO_RECENT_ACTIVITY_DURATION_CLOSE_IN_DAYS)) +$oldIssues = gh issue list --label "$Env:NO_RECENT_ACTIVITY_LABEL" --state open --limit 100 --json number,author,createdAt | ConvertFrom-Json +foreach($oldIssue in $oldIssues) { + $lastComment = gh issue view $oldIssue.number --json comments | ConvertFrom-Json | Select-Object -ExpandProperty comments | Where-Object {$_.author.login -eq $oldIssue.author.login} | Select-Object -Last 1 + if($null -eq $lastComment) { + $lastCommentDate = [datetime]::Parse($oldIssue.createdAt) + + } else { + $lastCommentDate = [datetime]::Parse($lastComment.createdAt) + } + $lastLabelEvent = gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "/repos/$($Env:ORG_NAME)/$($Env:REPO_NAME)/issues/$($oldIssue.number)/events?per_page=100" | ConvertFrom-Json | Where-Object {$_.event -eq "labeled" -and $_.label.name -eq "$Env:NO_RECENT_ACTIVITY_LABEL"} | Select-Object -Last 1 + $lastLabelEventDate = [datetime]::Parse($lastLabelEvent.created_at) + if ($lastCommentDate -gt $lastLabelEventDate) { + gh issue edit $oldIssue.number --remove-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --add-label "$Env:NEEDS_ATTENTION_LABEL" + } elseif (($lastCommentDate - $lastLabelEventDate) -le $inactivityDelay) { + gh issue close $oldIssue.number -r "not planned" + } +} \ No newline at end of file diff --git a/scripts/label-no-recent.ps1 b/scripts/label-no-recent.ps1 new file mode 100644 index 0000000000..3cb696060c --- /dev/null +++ b/scripts/label-no-recent.ps1 @@ -0,0 +1,19 @@ +$inactivityDelay = [timespan]::FromDays([int]::Parse($Env:NO_RECENT_ACTIVITY_DURATION_IN_DAYS)) +$oldIssues = gh issue list --label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --state open --limit 100 --json number,author,createdAt | ConvertFrom-Json +foreach($oldIssue in $oldIssues) { + $lastComment = gh issue view $oldIssue.number --json comments | ConvertFrom-Json | Select-Object -ExpandProperty comments | Where-Object {$_.author.login -eq $oldIssue.author.login} | Select-Object -Last 1 + if($null -eq $lastComment) { + $lastCommentDate = [datetime]::Parse($oldIssue.createdAt) + + } else { + $lastCommentDate = [datetime]::Parse($lastComment.createdAt) + } + $lastLabelEvent = gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "/repos/$($Env:ORG_NAME)/$($Env:REPO_NAME)/issues/$($oldIssue.number)/events?per_page=100" | ConvertFrom-Json | Where-Object {$_.event -eq "labeled" -and $_.label.name -eq "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL"} | Select-Object -Last 1 + $lastLabelEventDate = [datetime]::Parse($lastLabelEvent.created_at) + if ($lastCommentDate -gt $lastLabelEventDate) { + gh issue edit $oldIssue.number --remove-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --add-label "$Env:NEEDS_ATTENTION_LABEL" + } elseif (($lastCommentDate - $lastLabelEventDate) -le $inactivityDelay) { + gh issue edit $oldIssue.number --add-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_ATTENTION_LABEL" + gh issue comment $oldIssue.number -b "$Env:NO_RECENT_ACTIVITY_COMMENT" + } +} \ No newline at end of file