1
1
name : Code Quality & Auto-Format Checks
2
2
3
- # Trigger on push to main/master or PRs targeting these branches
4
3
on :
5
4
push :
6
5
branches : [ main, master ]
7
6
pull_request :
8
7
branches : [ main, master ]
9
8
10
- # Shared environment variables (avoid duplicate hardcoding)
11
9
env :
12
10
PYTHON_VERSION : ' 3.13.7'
13
11
14
12
jobs :
15
- # Phase 1: Auto-format with ruff (runs first, controls downstream jobs )
13
+ # Phase 1: Ruff Auto-Format (no dependency file references )
16
14
ruff-auto-format :
17
- name : " 📝 Ruff Auto-Format (With Auto-Commit) "
15
+ name : " 📝 Ruff Auto-Format"
18
16
runs-on : ubuntu-latest
19
- # Grant write permission for auto-commit (critical for push)
20
17
permissions :
21
- contents : write # Allows workflow to push formatting changes
22
- pull-requests : read # Optional: Reads PR info for branch targeting
18
+ contents : write # For auto-commit
19
+ pull-requests : read
23
20
outputs :
24
- changes_made : ${{ steps.format-check.outputs.changes_made }} # Track if formatting changes were applied
21
+ changes_made : ${{ steps.format-check.outputs.changes_made }}
25
22
steps :
26
- - name : Set up Python ${{ env.PYTHON_VERSION }}
23
+ - name : Checkout repository (critical for file access)
24
+ uses : actions/checkout@v4
25
+ with :
26
+ token : ${{ secrets.GITHUB_TOKEN }}
27
+ fetch-depth : 0
28
+ ref : ${{ github.head_ref || github.ref }}
29
+ path : . # Ensure repo is in default working dir
30
+
31
+ - name : Set up Python (no cache based on dependency files)
27
32
uses : actions/setup-python@v4
28
33
with :
29
34
python-version : ${{ env.PYTHON_VERSION }}
30
- cache : ' pip' # Cache dependencies to speed up installs
35
+ # Removed `cache-dependency-path` (no requirements/pyproject to reference)
36
+ cache : ' pip' # Still caches pip packages (e.g., ruff) for speed
31
37
32
- - name : Install ruff (code formatter )
38
+ - name : Install ruff (direct install, no dependency files )
33
39
run : pip install ruff
34
40
env :
35
- PIP_DISABLE_PIP_VERSION_CHECK : 1 # Skip pip version check for faster installs
41
+ PIP_DISABLE_PIP_VERSION_CHECK : 1
36
42
37
- - name : Run ruff format & detect changes
43
+ - name : Run ruff format & check changes
38
44
id : format-check
39
45
run : |
40
- echo "Running ruff format to fix code styling..."
41
- ruff format . # Apply formatting fixes
42
-
43
- # Check if any files were modified (avoids empty commits)
46
+ ruff format .
44
47
if git diff --quiet --exit-code; then
45
48
echo "changes_made=false" >> $GITHUB_OUTPUT
46
- echo "✅ No formatting issues found. No commit needed."
47
49
else
48
50
echo "changes_made=true" >> $GITHUB_OUTPUT
49
- echo "🔄 Formatting changes detected in these files:"
50
- git diff --name-only # List modified files for debugging
51
51
fi
52
52
53
53
- name : Auto-commit & push formatting changes
54
54
if : steps.format-check.outputs.changes_made == 'true'
55
55
run : |
56
- # Configure Git committer info (required for commits)
57
- git config --local user.name "GitHub Actions (Ruff Format)"
58
- git config --local user.email "[email protected] "
59
-
60
- # Commit and push changes
61
- git add .
62
- git commit -m "[auto] style: Fix code formatting with ruff" # Clear commit message
63
- git push
64
- echo "✅ Formatting changes pushed successfully."
65
-
66
- # Phase 2: Install check tools (runs only after valid ruff-format triggers)
56
+ git config --local user.name "GitHub Actions"
57
+ git config --local user.email "[email protected] "
58
+ git add . && git commit -m "[auto] Fix code format with ruff" && git push
59
+
60
+ # Phase 2: Setup Check Tools (no dependency file checks)
67
61
setup-check-tools :
68
- name : " ⚙️ Setup Code Check Tools"
69
- needs : ruff-auto-format # Depends on ruff-format completion
70
- # Trigger conditions:
71
- # - Run on direct pushes to main/master
72
- # - Run on PRs only if: 1) ruff made changes, OR 2) PR was merged
62
+ name : " ⚙️ Setup Check Tools"
63
+ needs : ruff-auto-format
73
64
if : >
74
65
(github.event_name == 'push') ||
75
- (github.event_name == ' pull_request' &&
66
+ (github.event. pull_request &&
76
67
(needs.ruff-auto-format.outputs.changes_made == 'true' ||
77
68
github.event.pull_request.merged == true))
78
69
runs-on : ubuntu-latest
79
70
steps :
80
- - name : Checkout repository code
71
+ - name : Checkout repository
81
72
uses : actions/checkout@v4
73
+ with :
74
+ path : .
75
+ fetch-depth : 1
82
76
83
- - name : Set up Python ${{ env.PYTHON_VERSION }}
77
+ - name : Set up Python (no dependency file cache)
84
78
uses : actions/setup-python@v4
85
79
with :
86
80
python-version : ${{ env.PYTHON_VERSION }}
87
- cache : ' pip' # Reuse cache from ruff-format job
81
+ cache : ' pip' # Caches tools (codespell/bandit) for downstream jobs
88
82
89
- - name : Install all code check tools
83
+ - name : Install check tools (direct install, no dependency files)
90
84
run : |
91
85
pip install codespell bandit mypy ruff pytest
92
86
env :
93
87
PIP_DISABLE_PIP_VERSION_CHECK : 1
94
88
95
- # Non-blocking check: Spell check (fails won't stop workflow)
89
+ # --- Non-blocking Checks (no dependency file references) ---
96
90
spell-check :
97
91
name : " 🔍 Spell Check (Non-Blocking)"
98
92
needs : setup-check-tools
99
93
runs-on : ubuntu-latest
100
94
steps :
101
- - name : Checkout repository code
95
+ - name : Checkout repository
102
96
uses : actions/checkout@v4
103
-
104
- - name : Set up Python ${{ env.PYTHON_VERSION }}
97
+ with :
98
+ path : .
99
+ - name : Set up Python
105
100
uses : actions/setup-python@v4
106
101
with :
107
102
python-version : ${{ env.PYTHON_VERSION }}
108
103
cache : ' pip'
104
+ - name : Run codespell
105
+ run : codespell --skip="*.json,*.lock,*.csv" --ignore-words-list="xxx,yyy,zzz" --quiet-level=2 || true
109
106
110
- - name : Run codespell (ignore common false positives)
111
- run : |
112
- codespell \
113
- --skip="*.json,*.lock,*.csv" \ # Skip non-code files
114
- --ignore-words-list="xxx,yyy,zzz" \ # Ignore custom false positives
115
- --quiet-level=2 || true # Non-blocking: continue if errors exist
116
-
117
- # Non-blocking check: Security scan (fails won't stop workflow)
118
107
security-scan :
119
108
name : " 🔒 Security Scan (Non-Blocking)"
120
109
needs : setup-check-tools
121
110
runs-on : ubuntu-latest
122
111
steps :
123
- - name : Checkout repository code
112
+ - name : Checkout repository
124
113
uses : actions/checkout@v4
125
-
126
- - name : Set up Python ${{ env.PYTHON_VERSION }}
114
+ with :
115
+ path : .
116
+ - name : Set up Python
127
117
uses : actions/setup-python@v4
128
118
with :
129
119
python-version : ${{ env.PYTHON_VERSION }}
130
120
cache : ' pip'
121
+ - name : Run bandit
122
+ run : bandit -r . -f human -o bandit-results.txt -f json -o bandit-results.json || true
131
123
132
- - name : Run bandit (security linter for Python)
133
- run : |
134
- bandit \
135
- -r . \ # Scan all Python files recursively
136
- -f human -o bandit-results.txt \ # Human-readable report
137
- -f json -o bandit-results.json || true # JSON report (for tools) + non-blocking
138
-
139
- # Non-blocking check: Type check (fails won't stop workflow)
140
124
type-check :
141
125
name : " 🎯 Type Check (Non-Blocking)"
142
126
needs : setup-check-tools
143
127
runs-on : ubuntu-latest
144
128
steps :
145
- - name : Checkout repository code
129
+ - name : Checkout repository
146
130
uses : actions/checkout@v4
147
-
148
- - name : Set up Python ${{ env.PYTHON_VERSION }}
131
+ with :
132
+ path : .
133
+ - name : Set up Python
149
134
uses : actions/setup-python@v4
150
135
with :
151
136
python-version : ${{ env.PYTHON_VERSION }}
152
137
cache : ' pip'
138
+ - name : Run mypy
139
+ run : mypy --ignore-missing-imports --show-error-codes . || true
153
140
154
- - name : Run mypy (static type checker)
155
- run : |
156
- mypy \
157
- --ignore-missing-imports \ # Ignore unresolved imports (e.g., third-party libs)
158
- --show-error-codes . || true # Show error codes for debugging + non-blocking
159
-
160
- # Blocking check: Lint check (fails stop workflow)
141
+ # --- Blocking Checks ---
161
142
lint-check :
162
143
name : " 🧹 Lint Check (Blocking)"
163
144
needs : setup-check-tools
164
145
runs-on : ubuntu-latest
165
146
steps :
166
- - name : Checkout repository code
147
+ - name : Checkout repository
167
148
uses : actions/checkout@v4
168
-
169
- - name : Set up Python ${{ env.PYTHON_VERSION }}
149
+ with :
150
+ path : .
151
+ - name : Set up Python
170
152
uses : actions/setup-python@v4
171
153
with :
172
154
python-version : ${{ env.PYTHON_VERSION }}
173
155
cache : ' pip'
156
+ - name : Run ruff check
157
+ run : ruff check --output-format=concise .
174
158
175
- - name : Run ruff check (code linter)
176
- run : ruff check --output-format=concise . # Blocking: fails on lint errors
177
-
178
- # Blocking check: Unit tests (fails stop workflow)
179
- unit-tests :
159
+ unit-tests :
180
160
name : " 🧪 Unit Tests (Blocking)"
181
161
needs : setup-check-tools
182
162
runs-on : ubuntu-latest
183
163
steps :
184
- - name : Checkout repository code
164
+ - name : Checkout repository
185
165
uses : actions/checkout@v4
186
-
187
- - name : Set up Python ${{ env.PYTHON_VERSION }}
166
+ with :
167
+ path : .
168
+ - name : Set up Python
188
169
uses : actions/setup-python@v4
189
170
with :
190
171
python-version : ${{ env.PYTHON_VERSION }}
191
172
cache : ' pip'
173
+ - name : Run pytest
174
+ run : pytest # Adjust test command if your tests are in a subfolder (e.g., pytest tests/)
192
175
193
- - name : Run pytest (unit test framework)
194
- run : pytest # Blocking: fails on test failures
195
-
196
- # Security analysis: CodeQL (for vulnerability detection)
176
+ # --- CodeQL Analysis ---
197
177
codeql-analysis :
198
178
name : " 🛡️ CodeQL Security Analysis"
199
- needs : setup-check-tools # Controlled by ruff-format pre-condition
179
+ needs : setup-check-tools
200
180
runs-on : ubuntu-latest
201
181
permissions :
202
182
actions : read
203
183
contents : read
204
- security-events : write # Required to upload CodeQL results
184
+ security-events : write
205
185
steps :
206
- - name : Checkout repository code
186
+ - name : Checkout repository
207
187
uses : actions/checkout@v4
208
-
188
+ with :
189
+ path : .
209
190
- name : Initialize CodeQL
210
191
uses : github/codeql-action/init@v2
211
192
with :
212
- languages : python # Analyze Python code
213
-
214
- - name : Autobuild (auto-configure build for CodeQL)
193
+ languages : python
194
+ - name : Autobuild
215
195
uses : github/codeql-action/autobuild@v2
216
-
217
- - name : Run CodeQL analysis
196
+ - name : Perform CodeQL Analysis
218
197
uses : github/codeql-action/analyze@v2
219
- with :
220
- output : sarif-results/ # Export results for debugging
221
198
222
- # Final summary: Verify all checks completed
199
+ # --- Final Summary ---
223
200
all-checks-summary :
224
201
name : " ✅ All Checks Summary"
225
202
needs : [spell-check, security-scan, type-check, lint-check, unit-tests, codeql-analysis]
226
- if : always() # Run even if some checks fail
203
+ if : always()
227
204
runs-on : ubuntu-latest
228
205
steps :
229
- - name : Print workflow summary
206
+ - name : Print summary
230
207
run : |
231
- echo "==================== Workflow Summary ===================="
232
- echo "Ruff auto-format made changes: ${{ needs.ruff-auto-format.outputs.changes_made }}"
233
- echo "---------------------------------------------------------"
234
-
235
- # Check for blocking failures (lint/tests/CodeQL)
236
- if [[ "${{ contains(needs.lint-check.result, 'failure') || contains(needs.unit-tests.result, 'failure') || contains(needs.codeql-analysis.result, 'failure') }}" == "true" ]]; then
237
- echo "❌ Critical failure detected (lint/tests/CodeQL). Fix required."
238
- exit 1 # Block workflow on critical failures
208
+ echo "Ruff auto-format changes: ${{ needs.ruff-auto-format.outputs.changes_made }}"
209
+ if [[ "${{ contains(needs.lint-check.result, 'failure') || contains(needs.unit-tests.result, 'failure') }}" == "true" ]]; then
210
+ echo "❌ Critical failure (lint/tests) - Fix required"
211
+ exit 1
239
212
else
240
- echo "✅ No critical failures. Non-blocking issues (spelling/type) may exist. "
213
+ echo "✅ No critical failures"
241
214
fi
242
-
0 commit comments