Skip to content

Commit 81845e1

Browse files
committed
Run the issue-labeler over pull requests using polling
1 parent ada1700 commit 81845e1

1 file changed

Lines changed: 65 additions & 5 deletions

File tree

.github/workflows/labeler-predict-pulls.yml

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@ on:
2525
- 'main'
2626
- 'release/**'
2727

28+
# Poll for open pull requests that need labels every 5 minutes
29+
schedule:
30+
- cron: "*/5 * * * *"
31+
2832
# Allow dispatching the workflow via the Actions UI, specifying ranges of numbers
33+
# If no pull request numbers are provided, it behaves as a polling event
2934
workflow_dispatch:
3035
inputs:
3136
pulls:
32-
description: "Pull Request Numbers (comma-separated list of ranges)."
33-
required: true
37+
description: "Pull Request Numbers (comma-separated list of ranges). Leave empty to poll."
38+
required: false
3439
cache_key:
3540
description: "The cache key suffix to use for restoring the model. Defaults to 'ACTIVE'."
3641
required: true
@@ -45,15 +50,70 @@ env:
4550
DEFAULT_LABEL: "needs-area-label"
4651

4752
jobs:
53+
poll-pull-requests:
54+
# Run on schedule trigger or workflow_dispatch without PR numbers, within the 'dotnet' org
55+
if: ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.pulls == '')) && github.repository_owner == 'dotnet' }}
56+
runs-on: ubuntu-latest
57+
permissions:
58+
actions: read
59+
pull-requests: read
60+
outputs:
61+
pulls: ${{ steps.get-pulls.outputs.pulls }}
62+
steps:
63+
- name: "Get open pull requests needing labels"
64+
id: get-pulls
65+
env:
66+
GITHUB_TOKEN: ${{ github.token }}
67+
run: |
68+
# Get the last successful schedule run's timestamp (minus 5 minutes for overlap)
69+
last_run=$(gh run list --repo ${{ github.repository }} --workflow "${{ github.workflow }}" --event schedule --status success --limit 1 --json updatedAt --jq '.[0].updatedAt // empty')
70+
71+
if [ -n "$last_run" ]; then
72+
# Subtract 5 minutes from the last run timestamp for overlap
73+
since=$(date -u -d "$last_run - 5 minutes" +"%Y-%m-%dT%H:%M:%SZ")
74+
echo "Filtering PRs updated since: $since (last run: $last_run)"
75+
pulls=$(gh pr list --repo ${{ github.repository }} --state open --json number,labels,updatedAt --limit 1000 --search "updated:>=$since")
76+
else
77+
# No previous run found; get all open pull requests
78+
echo "No previous schedule run found. Getting all open pull requests."
79+
pulls=$(gh pr list --repo ${{ github.repository }} --state open --json number,labels --limit 1000)
80+
fi
81+
82+
# Filter to PRs that don't have a label starting with LABEL_PREFIX
83+
needs_label=$(echo "$pulls" | jq -r --arg prefix "${{ env.LABEL_PREFIX }}" '
84+
[.[] | select(
85+
(.labels | map(.name) | any(startswith($prefix)) | not)
86+
) | .number] | join(",")
87+
')
88+
89+
echo "Pull requests needing labels: $needs_label"
90+
echo "pulls=$needs_label" >> $GITHUB_OUTPUT
91+
4892
predict-pull-label:
93+
# The 'if' uses always() so this job runs even when poll-pull-requests is skipped
4994
# Do not automatically run the workflow on forks outside the 'dotnet' org
50-
if: ${{ github.event_name == 'workflow_dispatch' || github.repository_owner == 'dotnet' }}
95+
if: ${{ always() && (github.event_name == 'workflow_dispatch' || github.repository_owner == 'dotnet') }}
96+
needs: [poll-pull-requests]
5197
runs-on: ubuntu-latest
5298
permissions:
5399
pull-requests: write
54100
steps:
101+
- name: "Determine pull requests to process"
102+
id: determine-pulls
103+
run: |
104+
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "${{ inputs.pulls }}" ]; then
105+
pulls="${{ inputs.pulls }}"
106+
elif [ "${{ github.event_name }}" == "workflow_dispatch" ] || [ "${{ github.event_name }}" == "schedule" ]; then
107+
pulls="${{ needs.poll-pull-requests.outputs.pulls }}"
108+
else
109+
pulls="${{ github.event.number }}"
110+
fi
111+
echo "pulls=$pulls" >> $GITHUB_OUTPUT
112+
echo "Processing pull requests: $pulls"
113+
55114
- name: "Restore pulls model from cache"
56115
id: restore-model
116+
if: ${{ steps.determine-pulls.outputs.pulls != '' }}
57117
uses: dotnet/issue-labeler/restore@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0
58118
with:
59119
type: pulls
@@ -62,10 +122,10 @@ jobs:
62122

63123
- name: "Predict pull labels"
64124
id: prediction
65-
if: ${{ steps.restore-model.outputs.cache-hit == 'true' }}
125+
if: ${{ steps.determine-pulls.outputs.pulls != '' && steps.restore-model.outputs.cache-hit == 'true' }}
66126
uses: dotnet/issue-labeler/predict@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0
67127
with:
68-
pulls: ${{ inputs.pulls || github.event.number }}
128+
pulls: ${{ steps.determine-pulls.outputs.pulls }}
69129
label_prefix: ${{ env.LABEL_PREFIX }}
70130
threshold: ${{ env.THRESHOLD }}
71131
default_label: ${{ env.DEFAULT_LABEL }}

0 commit comments

Comments
 (0)