1
- name : Code Quality & Auto-Format Checks
1
+ name : Code Quality (PR-Mandatory)
2
2
3
+ # Trigger explicitly for PRs + retain push events
3
4
on :
4
- pull_request :
5
- types : [opened, synchronize, reopened]
6
5
push :
7
6
branches : [ main, master ]
8
7
pull_request :
9
8
branches : [ main, master ]
9
+ types : [ opened, synchronize, reopened ] # Trigger on PR create/update/reopen
10
10
11
11
env :
12
12
PYTHON_VERSION : ' 3.13.7'
13
13
14
14
jobs :
15
- # Phase 1 : Ruff Auto-Format (no dependency file references )
16
- ruff-auto-format :
17
- name : " 📝 Ruff Auto- Format"
15
+ # 1. PR-Adapted : Ruff Auto-Formatting (critical: commits to PR source branch )
16
+ ruff-auto-format-pr :
17
+ name : " 📝 Ruff Format (PR-Safe) "
18
18
runs-on : ubuntu-latest
19
19
permissions :
20
- contents : write # For auto-commit
21
- pull-requests : read
20
+ contents : write # Required for auto-commits to PRs
21
+ pull-requests : read # Required to fetch PR branch info
22
22
outputs :
23
23
changes_made : ${{ steps.format-check.outputs.changes_made }}
24
24
steps :
25
- - name : Checkout repository (critical for file access)
25
+ - name : Checkout PR Source Branch
26
26
uses : actions/checkout@v4
27
27
with :
28
- token : ${{ secrets.GITHUB_TOKEN }}
28
+ token : ${{ secrets.GITHUB_TOKEN }} # Works for internal PRs; use PAT for forked PRs
29
29
fetch-depth : 0
30
- ref : ${{ github.head_ref || github.ref }}
31
- path : . # Ensure repo is in default working dir
30
+ ref : ${{ github.head_ref }} # Force checkout PR source branch (not target main)
31
+ path : .
32
32
33
- - name : Set up Python (no cache based on dependency files)
33
+ - name : Set up Python
34
34
uses : actions/setup-python@v4
35
35
with :
36
36
python-version : ${{ env.PYTHON_VERSION }}
37
- # Removed `cache-dependency-path` (no requirements/pyproject to reference)
38
- cache : ' pip' # Still caches pip packages (e.g., ruff) for speed
37
+ cache : ' pip' # Cache pip packages for faster installs
39
38
40
- - name : Install ruff (direct install, no dependency files)
39
+ - name : Install ruff
41
40
run : pip install ruff
42
41
env :
43
- PIP_DISABLE_PIP_VERSION_CHECK : 1
42
+ PIP_DISABLE_PIP_VERSION_CHECK : 1 # Skip pip version check to speed up installs
44
43
45
- - name : Run ruff format & check changes
44
+ - name : Run ruff format & detect changes
46
45
id : format-check
47
46
run : |
48
47
ruff format .
49
48
if git diff --quiet --exit-code; then
50
49
echo "changes_made=false" >> $GITHUB_OUTPUT
51
50
else
52
51
echo "changes_made=true" >> $GITHUB_OUTPUT
52
+ git diff --name-only # Show modified files in PR logs for review
53
53
fi
54
54
55
- - name : Auto-commit & push formatting changes
55
+ - name : Auto-commit format changes to PR
56
56
if : steps.format-check.outputs.changes_made == 'true'
57
57
run : |
58
- git config --local user.name "GitHub Actions"
59
- git config --local user.email "[email protected] "
60
- git add . && git commit -m "[auto] Fix code format with ruff" && git push
61
-
62
- # Phase 2: Setup Check Tools (no dependency file checks)
63
- setup-check-tools :
64
- name : " ⚙️ Setup Check Tools"
65
- needs : ruff-auto-format
58
+ git config --local user.name "GitHub Actions (PR Format)"
59
+ git config --local user.email "[email protected] "
60
+ git add .
61
+ git commit -m "[PR-auto] Fix code formatting with ruff"
62
+ git push # Pushes to PR source branch; PR updates automatically
63
+
64
+ # 2. PR Control: Run checks only if PR has format changes or is merged
65
+ setup-checks-pr :
66
+ name : " ⚙️ Setup Tools (PR-Triggered)"
67
+ needs : ruff-auto-format-pr
68
+ # Condition: Run on push OR PR (with format changes OR merged status)
66
69
if : >
67
70
(github.event_name == 'push') ||
68
- (github.event. pull_request &&
69
- (needs.ruff-auto-format.outputs.changes_made == 'true' ||
71
+ (github.event_name == ' pull_request' &&
72
+ (needs.ruff-auto-format-pr .outputs.changes_made == 'true' ||
70
73
github.event.pull_request.merged == true))
71
74
runs-on : ubuntu-latest
72
75
steps :
73
- - name : Checkout repository
76
+ - name : Checkout PR Source Branch
74
77
uses : actions/checkout@v4
75
78
with :
79
+ ref : ${{ github.head_ref || github.ref }} # Use PR source branch (or push branch)
76
80
path : .
77
- fetch-depth : 1
78
81
79
- - name : Set up Python (no dependency file cache)
82
+ - name : Set up Python
80
83
uses : actions/setup-python@v4
81
84
with :
82
85
python-version : ${{ env.PYTHON_VERSION }}
83
- cache : ' pip' # Caches tools (codespell/bandit) for downstream jobs
86
+ cache : ' pip'
84
87
85
- - name : Install check tools (direct install, no dependency files)
86
- run : |
87
- pip install codespell bandit mypy ruff pytest
88
+ - name : Install check tools directly (no dependency files)
89
+ run : pip install codespell bandit mypy ruff pytest
88
90
env :
89
91
PIP_DISABLE_PIP_VERSION_CHECK : 1
90
92
91
- # --- Non-blocking Checks (no dependency file references) ---
92
- spell-check :
93
- name : " 🔍 Spell Check (Non-Blocking )"
94
- needs : setup-check-tools
93
+ # 3. PR Checks: All tools synced to PR "Checks" tab
94
+ spell-check-pr :
95
+ name : " 🔍 Spell Check (PR )"
96
+ needs : setup-checks-pr
95
97
runs-on : ubuntu-latest
96
98
steps :
97
- - name : Checkout repository
99
+ - name : Checkout PR Source Branch
98
100
uses : actions/checkout@v4
99
101
with :
102
+ ref : ${{ github.head_ref }}
100
103
path : .
101
104
- name : Set up Python
102
105
uses : actions/setup-python@v4
103
106
with :
104
107
python-version : ${{ env.PYTHON_VERSION }}
105
108
cache : ' pip'
106
- - name : Run codespell
109
+ - name : Run codespell (Non-Blocking in PR)
107
110
run : codespell --skip="*.json,*.lock,*.csv" --ignore-words-list="xxx,yyy,zzz" --quiet-level=2 || true
108
111
109
- security-scan :
110
- name : " 🔒 Security Scan (Non-Blocking )"
111
- needs : setup-check-tools
112
+ security-check-pr :
113
+ name : " 🔒 Security Check (PR )"
114
+ needs : setup-checks-pr
112
115
runs-on : ubuntu-latest
113
116
steps :
114
- - name : Checkout repository
117
+ - name : Checkout PR Source Branch
115
118
uses : actions/checkout@v4
116
119
with :
120
+ ref : ${{ github.head_ref }}
117
121
path : .
118
122
- name : Set up Python
119
123
uses : actions/setup-python@v4
120
124
with :
121
125
python-version : ${{ env.PYTHON_VERSION }}
122
126
cache : ' pip'
123
- - name : Run bandit
124
- run : bandit -r . -f human -o bandit-results.txt -f json -o bandit-results.json || true
127
+ - name : Run bandit (Non-Blocking in PR)
128
+ run : bandit -r . -f human -o bandit-pr- results.txt -f json -o bandit-pr -results.json || true
125
129
126
- type-check :
127
- name : " 🎯 Type Check (Non-Blocking )"
128
- needs : setup-check-tools
130
+ type-check-pr :
131
+ name : " 🎯 Type Check (PR )"
132
+ needs : setup-checks-pr
129
133
runs-on : ubuntu-latest
130
134
steps :
131
- - name : Checkout repository
135
+ - name : Checkout PR Source Branch
132
136
uses : actions/checkout@v4
133
137
with :
138
+ ref : ${{ github.head_ref }}
134
139
path : .
135
140
- name : Set up Python
136
141
uses : actions/setup-python@v4
137
142
with :
138
143
python-version : ${{ env.PYTHON_VERSION }}
139
144
cache : ' pip'
140
- - name : Run mypy
145
+ - name : Run mypy (Non-Blocking in PR)
141
146
run : mypy --ignore-missing-imports --show-error-codes . || true
142
-
143
- # --- Blocking Checks ---
144
- lint-check :
145
- name : " 🧹 Lint Check (Blocking)"
146
- needs : setup-check-tools
147
+ lint-check-pr :
148
+ name : " 🧹 Lint Check (PR-Blocking)"
149
+ needs : setup-checks-pr
147
150
runs-on : ubuntu-latest
148
151
steps :
149
- - name : Checkout repository
152
+ - name : Checkout PR Source Branch
150
153
uses : actions/checkout@v4
151
154
with :
155
+ ref : ${{ github.head_ref }}
152
156
path : .
153
157
- name : Set up Python
154
158
uses : actions/setup-python@v4
155
159
with :
156
160
python-version : ${{ env.PYTHON_VERSION }}
157
161
cache : ' pip'
158
- - name : Run ruff check
162
+ - name : Run ruff check (Blocking in PR: Fix lint errors first)
159
163
run : ruff check --output-format=concise .
160
164
161
- unit-tests :
162
- name : " 🧪 Unit Tests (Blocking)"
163
- needs : setup-check-tools
165
+ test-pr :
166
+ name : " 🧪 Unit Tests (PR- Blocking)"
167
+ needs : setup-checks-pr
164
168
runs-on : ubuntu-latest
165
169
steps :
166
- - name : Checkout repository
170
+ - name : Checkout PR Source Branch
167
171
uses : actions/checkout@v4
168
172
with :
173
+ ref : ${{ github.head_ref }}
169
174
path : .
170
175
- name : Set up Python
171
176
uses : actions/setup-python@v4
172
177
with :
173
178
python-version : ${{ env.PYTHON_VERSION }}
174
179
cache : ' pip'
175
- - name : Run pytest
176
- run : pytest # Adjust test command if your tests are in a subfolder (e.g., pytest tests/)
180
+ - name : Run pytest (Blocking in PR: Fix test failures first)
181
+ run : pytest
177
182
178
- # --- CodeQL Analysis ---
179
- codeql-analysis :
180
- name : " 🛡️ CodeQL Security Analysis "
181
- needs : setup-check-tools
183
+ # 4. PR Security Analysis: CodeQL results synced to PR "Security" tab
184
+ codeql-pr :
185
+ name : " 🛡️ CodeQL (PR) "
186
+ needs : setup-checks-pr
182
187
runs-on : ubuntu-latest
183
188
permissions :
184
189
actions : read
185
190
contents : read
186
- security-events : write
191
+ security-events : write # Required to sync results to PR Security tab
187
192
steps :
188
- - name : Checkout repository
193
+ - name : Checkout PR Source Branch
189
194
uses : actions/checkout@v4
190
195
with :
196
+ ref : ${{ github.head_ref }}
191
197
path : .
192
198
- name : Initialize CodeQL
193
199
uses : github/codeql-action/init@v2
@@ -198,19 +204,21 @@ jobs:
198
204
- name : Perform CodeQL Analysis
199
205
uses : github/codeql-action/analyze@v2
200
206
201
- # --- Final Summary ---
202
- all -checks-summary :
203
- name : " ✅ All Checks Summary"
204
- needs : [spell-check, security-scan , type-check, lint-check, unit-tests , codeql-analysis ]
207
+ # 5. PR Summary: Clear status in PR "Checks" tab
208
+ pr -checks-summary :
209
+ name : " ✅ PR All Checks Summary"
210
+ needs : [spell-check-pr , security-check-pr , type-check-pr , lint-check-pr, test-pr , codeql-pr ]
205
211
if : always()
206
212
runs-on : ubuntu-latest
207
213
steps :
208
- - name : Print summary
214
+ - name : Print PR Check Summary
209
215
run : |
210
- echo "Ruff auto-format changes: ${{ needs.ruff-auto-format.outputs.changes_made }}"
211
- if [[ "${{ contains(needs.lint-check.result, 'failure') || contains(needs.unit-tests.result, 'failure') }}" == "true" ]]; then
212
- echo "❌ Critical failure (lint/tests) - Fix required"
216
+ echo "PR Source Branch: ${{ github.head_ref }}"
217
+ echo "Formatting Changes Applied: ${{ needs.ruff-auto-format-pr.outputs.changes_made }}"
218
+ # Block PR merge if critical checks (lint/tests) fail
219
+ if [[ "${{ contains(needs.lint-check-pr.result, 'failure') || contains(needs.test-pr.result, 'failure') }}" == "true" ]]; then
220
+ echo "❌ Critical PR Checks Failed (lint/tests) - Fix Before Merging"
213
221
exit 1
214
222
else
215
- echo "✅ No critical failures "
223
+ echo "✅ Critical PR Checks Passed - Non-blocking issues (spelling/type) are optional to fix "
216
224
fi
0 commit comments