6
6
types : [opened, synchronize, reopened, ready_for_review, review_requested, review_request_removed]
7
7
push :
8
8
branches : [ main ] # Also run on direct pushes to main
9
+ concurrency :
10
+ group : ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11
+ cancel-in-progress : true
9
12
10
13
jobs :
11
- check-approval :
12
- name : Check if PR has contributor approval
13
- runs-on : ubuntu-latest
14
- permissions :
15
- pull-requests : read
16
- # Skip this check for direct pushes to main
17
- if : github.event_name == 'pull_request'
18
- outputs :
19
- approved : ${{ steps.check-approval.outputs.approved }}
20
- steps :
21
- - name : Check if PR has been approved by a contributor
22
- id : check-approval
23
- uses : actions/github-script@v7
24
- with :
25
- script : |
26
- const APPROVED_ASSOCIATION = ['COLLABORATOR', 'CONTRIBUTOR', 'MEMBER', 'OWNER']
27
- const PR_AUTHOR_ASSOCIATION = context.payload.pull_request.author_association;
28
- const { data: reviews } = await github.rest.pulls.listReviews({
29
- owner: context.repo.owner,
30
- repo: context.repo.repo,
31
- pull_number: context.issue.number,
32
- });
33
-
34
- const isApprovedContributor = APPROVED_ASSOCIATION.includes(PR_AUTHOR_ASSOCIATION);
35
-
36
- // Check if any contributor has approved
37
- const isApproved = reviews.some(review =>
38
- review.state === 'APPROVED' && APPROVED_ASSOCIATION.includes(review.author_association)
39
- ) || isApprovedContributor;
40
-
41
- core.setOutput('approved', isApproved);
42
-
43
- if (!isApproved) {
44
- core.notice('This PR does not have approval from a Contributor. Workflow will not run test jobs.');
45
- return false;
46
- }
47
-
48
- return true;
49
-
50
14
unit-test :
51
15
name : Unit Tests - Python ${{ matrix.python-version }} - ${{ matrix.os-name }}
52
- needs : check-approval
53
16
permissions :
54
17
contents : read
55
- # Only run if PR is approved or this is a direct push to main
56
- if : github.event_name == 'push' || needs.check-approval.outputs.approved == 'true'
57
18
strategy :
58
19
matrix :
59
20
include :
60
21
# Linux
61
22
- os : ubuntu-latest
62
- os-name : linux
23
+ os-name : ' linux'
63
24
python-version : " 3.10"
64
25
- os : ubuntu-latest
65
- os-name : linux
26
+ os-name : ' linux'
66
27
python-version : " 3.11"
67
28
- os : ubuntu-latest
68
- os-name : linux
29
+ os-name : ' linux'
69
30
python-version : " 3.12"
70
31
- os : ubuntu-latest
71
- os-name : linux
32
+ os-name : ' linux'
72
33
python-version : " 3.13"
73
34
# Windows
74
35
- os : windows-latest
75
- os-name : windows
36
+ os-name : ' windows'
76
37
python-version : " 3.10"
77
38
- os : windows-latest
78
- os-name : windows
39
+ os-name : ' windows'
79
40
python-version : " 3.11"
80
41
- os : windows-latest
81
- os-name : windows
42
+ os-name : ' windows'
82
43
python-version : " 3.12"
83
44
- os : windows-latest
84
- os-name : windows
45
+ os-name : ' windows'
85
46
python-version : " 3.13"
86
- # MacOS - latest only; not enough runners for MacOS
47
+ # MacOS - latest only; not enough runners for macOS
87
48
- os : macos-latest
88
- os-name : macos
89
- python-version : " 3.13"
90
- fail-fast : false
49
+ os-name : ' macOS '
50
+ python-version : " 3.13"
51
+ fail-fast : true
91
52
runs-on : ${{ matrix.os }}
92
53
env :
93
54
LOG_LEVEL : DEBUG
@@ -108,14 +69,11 @@ jobs:
108
69
id : tests
109
70
run : hatch test tests --cover
110
71
continue-on-error : false
111
-
112
72
lint :
113
73
name : Lint
114
74
runs-on : ubuntu-latest
115
- needs : check-approval
116
75
permissions :
117
76
contents : read
118
- if : github.event_name == 'push' || needs.check-approval.outputs.approved == 'true'
119
77
steps :
120
78
- name : Checkout code
121
79
uses : actions/checkout@v4
0 commit comments