Skip to content

Commit bd43e73

Browse files
authored
[chore] Mark issues as stale after 60 days (open-telemetry#14881)
This marks issues as stale after 60 days, exempting issues that are labeled with never stale. Upon being marked stale, code owners for any corresponding package labels are pinged. Issues are closed after 180 days (roughly 6 months) of total inactivity (4 months after the Stale label is applied), and are given the closed as inactive label so they can be easily found later.
1 parent 0dc3ab6 commit bd43e73

File tree

3 files changed

+125
-3
lines changed

3 files changed

+125
-3
lines changed
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "Close stale pull requests"
1+
name: "Close stale issues and pull requests"
22
on:
33
schedule:
44
- cron: "12 5 * * *" # arbitrary time not to DDOS GitHub
@@ -12,7 +12,11 @@ jobs:
1212
repo-token: ${{ secrets.GITHUB_TOKEN }}
1313
stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 14 days.'
1414
close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.'
15+
close-issue-message: 'This issue has been closed as inactive because it has been stale for 120 days with no activity.'
16+
close-issue-label: 'closed as inactive'
1517
days-before-pr-stale: 14
16-
days-before-issue-stale: 730
18+
days-before-issue-stale: -1 # Stale label is applied by mark-issues-as-stale.yml
1719
days-before-pr-close: 14
18-
days-before-issue-close: 30
20+
days-before-issue-close: 120
21+
exempt-issue-labels: 'never stale'
22+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: 'Mark issues as stale'
2+
on:
3+
schedule:
4+
- cron: "27 3 * * 1" # Run once a week to ease into marking issues as stale.
5+
6+
jobs:
7+
mark-issues-as-stale:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
12+
- name: Run mark-issues-as-stale.sh
13+
run: ./.github/workflows/scripts/mark-issues-as-stale.sh
14+
env:
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
DAYS_BEFORE_STALE: 60
17+
DAYS_BEFORE_CLOSE: 120 # Only used for the stale message.
18+
STALE_LABEL: 'Stale'
19+
EXEMPT_LABEL: 'never stale'
20+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright The OpenTelemetry Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# This script checks for issues that have been inactive for a certain number
18+
# of days. Any inactive issues have codeowners pinged for labels corresponding
19+
# to a component and are marked as stale. The stale bot will then handle
20+
# the rest of the lifecycle, including removing the stale label and closing
21+
# the issue.
22+
#
23+
# This script is necessary instead of just using the stale action because
24+
# the stale action does not support pinging code owners, and pinging
25+
# code owners after marking an issue as stale will cause the issue to
26+
# have the stale label removed according to all documented behavior
27+
# of the stale action.
28+
29+
set -euo pipefail
30+
31+
if [[ -z ${DAYS_BEFORE_STALE} || -z ${DAYS_BEFORE_CLOSE} || -z ${STALE_LABEL} || -z ${EXEMPT_LABEL} ]]; then
32+
echo "At least one of DAYS_BEFORE_STALE, DAYS_BEFORE_CLOSE, STALE_LABEL, or EXEMPT_LABEL has not been set, please ensure each is set."
33+
exit 0
34+
fi
35+
36+
STALE_MESSAGE="This issue has been inactive for ${DAYS_BEFORE_STALE} days. It will be closed in ${DAYS_BEFORE_CLOSE} days if there is no activity."
37+
38+
# Check for the least recently-updated issues that aren't currently stale.
39+
# If no issues in this list are stale, the repo has no stale issues.
40+
ISSUES=(`gh issue list --search "is:issue is:open -label:${STALE_LABEL} -label:\"${EXEMPT_LABEL}\" sort:updated-asc" --json number --jq '.[].number'`)
41+
42+
for ISSUE in "${ISSUES[@]}"; do
43+
OWNERS=''
44+
45+
UPDATED_AT=`gh issue view ${ISSUE} --json updatedAt --jq '.updatedAt'`
46+
UPDATED_UNIX=`date +%s --date="${UPDATED_AT}"`
47+
NOW=`date +%s`
48+
DIFF_DAYS=$(($((${NOW}-${UPDATED_UNIX}))/(3600*24)))
49+
50+
if [[ ${DIFF_DAYS} < ${DAYS_BEFORE_STALE} ]]; then
51+
# echo "Issue #${ISSUE} is not stale. Issues are sorted by updated date in ascending order, so all remaining issues must not be stale. Exiting."
52+
exit 0
53+
fi
54+
55+
LABELS=(`gh issue view ${ISSUE} --json labels --jq '.labels.[].name'`)
56+
57+
for LABEL in "${LABELS[@]}"; do
58+
if ! [[ ${LABEL} =~ ^cmd/ || ${LABEL} =~ ^confmap/ || ${LABEL} =~ ^exporter/ || ${LABEL} =~ ^extension/ || ${LABEL} =~ ^internal/ || ${LABEL} =~ ^pkg/ || ${LABEL} =~ ^processor/ || ${LABEL} =~ ^receiver/ ]]; then
59+
continue
60+
fi
61+
62+
COMPONENT=${LABEL}
63+
result=`grep -c ${LABEL} .github/CODEOWNERS`
64+
65+
# there may be more than 1 component matching a label
66+
# if so, try to narrow things down by appending the component
67+
# type to the label
68+
if [[ $result != 1 ]]; then
69+
COMPONENT_TYPE=`echo ${COMPONENT} | cut -f 1 -d '/'`
70+
COMPONENT="${COMPONENT}${COMPONENT_TYPE}"
71+
fi
72+
73+
OWNERS+="- ${COMPONENT}: `grep -m 1 ${COMPONENT} .github/CODEOWNERS | sed 's/ */ /g' | cut -f3- -d ' '`\n"
74+
done
75+
76+
if [[ -z "${OWNERS}" ]]; then
77+
echo "No code owners found. Marking issue as stale without pinging code owners."
78+
79+
gh issue comment ${ISSUE} -b "${STALE_MESSAGE}"
80+
else
81+
echo "Pinging code owners for issue #${ISSUE}."
82+
83+
# The GitHub CLI only offers multiline strings through file input.
84+
printf "${STALE_MESSAGE} Pinging code owners:\n${OWNERS}\nSee [Adding Labels via Comments](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#adding-labels-via-comments) if you do not have permissions to add labels yourself." \
85+
| gh issue comment ${ISSUE} -F -
86+
fi
87+
88+
# We want to add a label after making a comment for two reasons:
89+
# 1. If there is some error making a comment, a stale label should not be applied.
90+
# We want code owners to be pinged before closing an issue as stale.
91+
# 2. The stale bot (as of v6) uses the timestamp for when the stale label was
92+
# applied to determine when an issue was marked stale. We want to ensure that
93+
# was the last activity on the issue, or the stale bot will remove the stale
94+
# label if our comment to ping code owners comes too long after the stale
95+
# label is applied.
96+
gh issue edit ${ISSUE} --add-label "${STALE_LABEL}"
97+
done
98+

0 commit comments

Comments
 (0)