Skip to content

Commit 8a3720d

Browse files
chore(github): improve script to determine test scope (#2510)
* chore(github): add script to determine whether a PR was already approved This step results in a full test suite run if an already approved PR receives changes to prevent breaking the main branch. * cancel parallel triggers of the remote tests * fix group assignment * add python version to group assignment
1 parent c5188a6 commit 8a3720d

File tree

1 file changed

+38
-15
lines changed

1 file changed

+38
-15
lines changed

.github/workflows/run_tests.yml

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ on:
2424

2525
jobs:
2626
determine-test-scope:
27-
runs-on: [ inhouse ]
27+
runs-on: [ inhouse ]
2828
if: |
2929
github.event.pull_request.draft == false ||
3030
github.ref == 'refs/heads/develop' ||
@@ -33,6 +33,22 @@ jobs:
3333
local_tests: ${{ steps.determine-test-type.outputs.local_tests }}
3434
remote_tests: ${{ steps.determine-test-type.outputs.remote_tests }}
3535
steps:
36+
- name: check-current-approval-status
37+
id: approval
38+
if: github.event_name == 'pull_request'
39+
uses: actions/github-script@v7
40+
with:
41+
script: |
42+
const {owner, repo} = context.repo
43+
const number = context.payload.pull_request.number
44+
const reviews = await github.rest.pulls.listReviews({owner, repo, pull_number: number})
45+
46+
const latestByUser = {}
47+
reviews.data.forEach(r => latestByUser[r.user.id] = r)
48+
49+
const approved = Object.values(latestByUser)
50+
.some(r => r.state === 'APPROVED')
51+
core.setOutput('approved', approved ? 'true' : 'false')
3652
- name: determine-test-type
3753
id: determine-test-type
3854
env:
@@ -42,24 +58,26 @@ jobs:
4258
REF: ${{ github.ref }}
4359
INPUT_LOCAL: ${{ github.event.inputs.local_tests }}
4460
INPUT_REMOTE: ${{ github.event.inputs.remote_tests }}
61+
APPROVED: ${{ steps.approval.outputs.approved }}
4562
run: |
4663
echo "Event: $EVENT_NAME"
4764
echo "Draft: $DRAFT_STATE"
4865
echo "Review State: $REVIEW_STATE"
4966
echo "Git REF: $REF"
5067
echo "Input local: $INPUT_FAST"
5168
echo "Input remote: $INPUT_FULL"
69+
echo "Approved: $APPROVED"
5270
5371
remote_tests=false
5472
local_tests=false
5573
# Workflow_dispatch input override
5674
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
57-
75+
5876
# Each option is self contained
5977
if [[ "$INPUT_REMOTE" == "true" ]]; then
6078
remote_tests=true
6179
fi
62-
80+
6381
if [[ "$INPUT_LOCAL" == "true" ]]; then
6482
local_tests=true
6583
fi
@@ -76,11 +94,12 @@ jobs:
7694
fi
7795
fi
7896
79-
# All PRs that have been triggered need local tests
97+
# All PRs that have been triggered need local tests and approved ones need to re-run the remote tests
8098
if [[ "$EVENT_NAME" == "pull_request" ]]; then
8199
local_tests=true
100+
[[ "$APPROVED" == "true" ]] && remote_tests=true
82101
fi
83-
102+
84103
# If it's a push to develop
85104
if [[ "$EVENT_NAME" == "push" && "$REF" == "refs/heads/develop" ]]; then
86105
local_tests=true
@@ -91,12 +110,12 @@ jobs:
91110
echo "remote_tests=$remote_tests" >> $GITHUB_OUTPUT
92111
echo "local_tests=$local_tests"
93112
echo "remote_tests=$remote_tests"
94-
113+
95114
lint:
96115
needs: determine-test-scope
97116
if: ( needs.determine-test-scope.outputs.local_tests == 'true' ) || ( needs.determine-test-scope.outputs.remote_tests == 'true' )
98117
name: Run linting
99-
runs-on: [ inhouse ]
118+
runs-on: [ inhouse ]
100119
steps:
101120
- uses: actions/checkout@v4
102121
with:
@@ -111,10 +130,10 @@ jobs:
111130

112131
local-tests:
113132
# Run on open PRs OR when manually triggered with local_tests=true
114-
needs: determine-test-scope
133+
needs: determine-test-scope
115134
if: needs.determine-test-scope.outputs.local_tests == 'true'
116-
name: Python ${{ matrix.python-version }} - self-hosted-runner
117-
runs-on: [ inhouse ]
135+
name: Python ${{ matrix.python-version }} - self-hosted-runner
136+
runs-on: [ inhouse ]
118137
strategy:
119138
matrix:
120139
python-version: ['3.9', '3.13']
@@ -172,13 +191,13 @@ jobs:
172191
diff-storage: _xml_coverage_reports
173192
coverage-summary-title: "Code Coverage Summary"
174193
togglable-report: true
175-
194+
176195
- name: Changed files
177196
id: diff
178197
uses: step-security/changed-files@v46
179198
with:
180199
files: '**/*.py'
181-
200+
182201
- name: Slice report down to changed files
183202
if: ${{ steps.diff.outputs.all_changed_files != '' }}
184203
env:
@@ -188,7 +207,7 @@ jobs:
188207
source ${GITHUB_WORKSPACE}/.venv/bin/activate
189208
include=$(printf '%s\n' $CHANGED | sed 's|^|**/|' | paste -sd, -)
190209
coverage xml -i -o changed.xml --include="$include"
191-
210+
192211
- name: Produce the changed files coverage report
193212
uses: insightsengineering/coverage-action@v2
194213
if: ${{ steps.diff.outputs.all_changed_files != '' }}
@@ -201,7 +220,7 @@ jobs:
201220

202221
remote-tests:
203222
# Run tests on a push event OR a workflow dispatch with remote_tests
204-
needs: determine-test-scope
223+
needs: determine-test-scope
205224
if: needs.determine-test-scope.outputs.remote_tests == 'true'
206225
name: Python ${{ matrix.python-version }} - ${{ matrix.platform }}
207226
runs-on: ${{ matrix.platform }}
@@ -215,6 +234,10 @@ jobs:
215234
env: # Set environment variables for the whole job
216235
PIP_ONLY_BINARY: gdstk
217236
MPLBACKEND: agg
237+
238+
concurrency:
239+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}-${{ matrix.platform }}-${{ matrix.python-version }}-remote
240+
cancel-in-progress: true
218241

219242
steps:
220243
- uses: actions/checkout@v4
@@ -271,7 +294,7 @@ jobs:
271294
maxColorRange: 95
272295
valColorRange: ${{ env.total }}
273296
style: "for-the-badge"
274-
297+
275298
pr-requirements-pass:
276299
name: pr-requirements-pass
277300
if: ( needs.determine-test-scope.outputs.local_tests == 'true' ) || ( needs.determine-test-scope.outputs.remote_tests == 'true' )

0 commit comments

Comments
 (0)