Skip to content

Commit a103971

Browse files
authored
fix python.yml
1 parent 6706dca commit a103971

File tree

1 file changed

+101
-107
lines changed

1 file changed

+101
-107
lines changed

.github/workflows/python.yml

Lines changed: 101 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,90 @@
1-
name: Code Quality (PR-Mandatory)
1+
name: Mandatory PR Code Quality Checks
22

3-
# Trigger explicitly for PRs + retain push events
3+
# Force trigger for ALL PR events + retain push (for post-merge validation)
44
on:
55
push:
6-
branches: [ main, master ]
6+
branches: [ main, master ] # Only for merged PR validation
77
pull_request:
88
branches: [ main, master ]
9-
types: [ opened, synchronize, reopened ] # Trigger on PR create/update/reopen
9+
types: [ opened, synchronize, reopened, edited ] # Trigger on ANY PR change
1010

1111
env:
1212
PYTHON_VERSION: '3.13.7'
1313

1414
jobs:
15-
# 1. PR-Adapted: Ruff Auto-Formatting (critical: commits to PR source branch)
16-
ruff-auto-format-pr:
17-
name: "📝 Ruff Format (PR-Safe)"
15+
# 1. Mandatory PR Step: Ruff Auto-Format (pushes back to PR source branch)
16+
pr-ruff-auto-format:
17+
name: "📝 PR: Ruff Auto-Format"
1818
runs-on: ubuntu-latest
1919
permissions:
20-
contents: write # Required for auto-commits to PRs
21-
pull-requests: read # Required to fetch PR branch info
20+
contents: write # Critical for pushing format fixes to PR
21+
pull-requests: write # Required to update PR status
2222
outputs:
2323
changes_made: ${{ steps.format-check.outputs.changes_made }}
2424
steps:
25-
- name: Checkout PR Source Branch
25+
- name: Checkout PR SOURCE BRANCH (MANDATORY FOR PR)
2626
uses: actions/checkout@v4
2727
with:
28-
token: ${{ secrets.GITHUB_TOKEN }} # Works for internal PRs; use PAT for forked PRs
28+
token: ${{ secrets.PR_ACCESS_PAT || secrets.GITHUB_TOKEN }} # Use PAT for forked PRs
2929
fetch-depth: 0
30-
ref: ${{ github.head_ref }} # Force checkout PR source branch (not target main)
30+
ref: ${{ github.head_ref }} # MUST target PR source (not main)
3131
path: .
3232

3333
- name: Set up Python
3434
uses: actions/setup-python@v4
3535
with:
3636
python-version: ${{ env.PYTHON_VERSION }}
37-
cache: 'pip' # Cache pip packages for faster installs
37+
cache: 'pip'
3838

3939
- name: Install ruff
4040
run: pip install ruff
4141
env:
42-
PIP_DISABLE_PIP_VERSION_CHECK: 1 # Skip pip version check to speed up installs
42+
PIP_DISABLE_PIP_VERSION_CHECK: 1
4343

44-
- name: Run ruff format & detect changes
44+
- name: Run format & detect changes
4545
id: format-check
4646
run: |
4747
ruff format .
4848
if git diff --quiet --exit-code; then
4949
echo "changes_made=false" >> $GITHUB_OUTPUT
5050
else
5151
echo "changes_made=true" >> $GITHUB_OUTPUT
52-
git diff --name-only # Show modified files in PR logs for review
52+
git diff --name-only >> pr_format_changes.txt # Log changes for PR review
5353
fi
5454
55-
- name: Auto-commit format changes to PR
55+
- name: Push fixes to PR source branch
5656
if: steps.format-check.outputs.changes_made == 'true'
5757
run: |
58-
git config --local user.name "GitHub Actions (PR Format)"
59-
git config --local user.email "pr-format@github.com"
58+
git config --local user.name "GitHub Actions (PR Bot)"
59+
git config --local user.email "pr-bot@github.com"
6060
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)
69-
if: >
70-
(github.event_name == 'push') ||
71-
(github.event_name == 'pull_request' &&
72-
(needs.ruff-auto-format-pr.outputs.changes_made == 'true' ||
73-
github.event.pull_request.merged == true))
61+
git commit -m "[PR AUTO-FIX] Code formatting via ruff"
62+
git push # Updates PR automatically—no manual push needed
63+
64+
- name: Comment format changes on PR (MANDATORY VISIBILITY)
65+
if: steps.format-check.outputs.changes_made == 'true' && github.event_name == 'pull_request'
66+
uses: actions/github-script@v7
67+
with:
68+
script: |
69+
const changes = require('fs').readFileSync('pr_format_changes.txt', 'utf8');
70+
github.rest.issues.createComment({
71+
owner: context.repo.owner,
72+
repo: context.repo.repo,
73+
issue_number: context.issue.number,
74+
body: `🔄 Auto-formatting changes applied to these files:\n\`\`\`\n${changes}\n\`\`\``
75+
});
76+
77+
# 2. Mandatory PR Step: Setup tools (ONLY runs for PRs)
78+
pr-setup-tools:
79+
name: "⚙️ PR: Setup Check Tools"
80+
needs: pr-ruff-auto-format
81+
if: github.event_name == 'pull_request' # MANDATORY: Only execute for PRs
7482
runs-on: ubuntu-latest
7583
steps:
76-
- name: Checkout PR Source Branch
84+
- name: Checkout PR source branch
7785
uses: actions/checkout@v4
7886
with:
79-
ref: ${{ github.head_ref || github.ref }} # Use PR source branch (or push branch)
87+
ref: ${{ github.head_ref }}
8088
path: .
8189

8290
- name: Set up Python
@@ -85,112 +93,100 @@ jobs:
8593
python-version: ${{ env.PYTHON_VERSION }}
8694
cache: 'pip'
8795

88-
- name: Install check tools directly (no dependency files)
96+
- name: Install PR check tools
8997
run: pip install codespell bandit mypy ruff pytest
9098
env:
9199
PIP_DISABLE_PIP_VERSION_CHECK: 1
92100

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
101+
# 3. Mandatory PR Checks (all sync to PR "Checks" tab)
102+
pr-spell-check:
103+
name: "🔍 PR: Spell Check (Non-Blocking)"
104+
needs: pr-setup-tools
97105
runs-on: ubuntu-latest
98106
steps:
99-
- name: Checkout PR Source Branch
107+
- name: Checkout PR source branch
100108
uses: actions/checkout@v4
101109
with:
102110
ref: ${{ github.head_ref }}
103111
path: .
104-
- name: Set up Python
105-
uses: actions/setup-python@v4
106-
with:
107-
python-version: ${{ env.PYTHON_VERSION }}
108-
cache: 'pip'
109-
- name: Run codespell (Non-Blocking in PR)
112+
- name: Run codespell
110113
run: codespell --skip="*.json,*.lock,*.csv" --ignore-words-list="xxx,yyy,zzz" --quiet-level=2 || true
111114

112-
security-check-pr:
113-
name: "🔒 Security Check (PR)"
114-
needs: setup-checks-pr
115+
pr-security-check:
116+
name: "🔒 PR: Security Check (Non-Blocking)"
117+
needs: pr-setup-tools
115118
runs-on: ubuntu-latest
116119
steps:
117-
- name: Checkout PR Source Branch
120+
- name: Checkout PR source branch
118121
uses: actions/checkout@v4
119122
with:
120123
ref: ${{ github.head_ref }}
121124
path: .
122-
- name: Set up Python
123-
uses: actions/setup-python@v4
125+
- name: Run bandit
126+
run: bandit -r . -f human -o pr_bandit_results.txt -f json -o pr_bandit_results.json || true
127+
pr-security-check:
128+
name: "🔒 PR: Security Check (Non-Blocking)"
129+
needs: pr-setup-tools
130+
runs-on: ubuntu-latest
131+
steps:
132+
- name: Checkout PR source branch
133+
uses: actions/checkout@v4
124134
with:
125-
python-version: ${{ env.PYTHON_VERSION }}
126-
cache: 'pip'
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
135+
ref: ${{ github.head_ref }}
136+
path: .
137+
- name: Run bandit
138+
run: bandit -r . -f human -o pr_bandit_results.txt -f json -o pr_bandit_results.json || true
129139

130-
type-check-pr:
131-
name: "🎯 Type Check (PR)"
132-
needs: setup-checks-pr
140+
pr-type-check:
141+
name: "🎯 PR: Type Check (Non-Blocking)"
142+
needs: pr-setup-tools
133143
runs-on: ubuntu-latest
134144
steps:
135-
- name: Checkout PR Source Branch
145+
- name: Checkout PR source branch
136146
uses: actions/checkout@v4
137147
with:
138148
ref: ${{ github.head_ref }}
139149
path: .
140-
- name: Set up Python
141-
uses: actions/setup-python@v4
142-
with:
143-
python-version: ${{ env.PYTHON_VERSION }}
144-
cache: 'pip'
145-
- name: Run mypy (Non-Blocking in PR)
150+
- name: Run mypy
146151
run: mypy --ignore-missing-imports --show-error-codes . || true
147-
lint-check-pr:
148-
name: "🧹 Lint Check (PR-Blocking)"
149-
needs: setup-checks-pr
152+
153+
pr-lint-check:
154+
name: "🧹 PR: Lint Check (BLOCKING)"
155+
needs: pr-setup-tools
150156
runs-on: ubuntu-latest
151157
steps:
152-
- name: Checkout PR Source Branch
158+
- name: Checkout PR source branch
153159
uses: actions/checkout@v4
154160
with:
155161
ref: ${{ github.head_ref }}
156162
path: .
157-
- name: Set up Python
158-
uses: actions/setup-python@v4
159-
with:
160-
python-version: ${{ env.PYTHON_VERSION }}
161-
cache: 'pip'
162-
- name: Run ruff check (Blocking in PR: Fix lint errors first)
163-
run: ruff check --output-format=concise .
163+
- name: Run ruff check
164+
run: ruff check --output-format=concise . # Fails PR if lint errors exist
164165

165-
test-pr:
166-
name: "🧪 Unit Tests (PR-Blocking)"
167-
needs: setup-checks-pr
166+
pr-unit-tests:
167+
name: "🧪 PR: Unit Tests (BLOCKING)"
168+
needs: pr-setup-tools
168169
runs-on: ubuntu-latest
169170
steps:
170-
- name: Checkout PR Source Branch
171+
- name: Checkout PR source branch
171172
uses: actions/checkout@v4
172173
with:
173174
ref: ${{ github.head_ref }}
174175
path: .
175-
- name: Set up Python
176-
uses: actions/setup-python@v4
177-
with:
178-
python-version: ${{ env.PYTHON_VERSION }}
179-
cache: 'pip'
180-
- name: Run pytest (Blocking in PR: Fix test failures first)
181-
run: pytest
176+
- name: Run pytest
177+
run: pytest # Fails PR if test failures exist
182178

183-
# 4. PR Security Analysis: CodeQL results synced to PR "Security" tab
184-
codeql-pr:
185-
name: "🛡️ CodeQL (PR)"
186-
needs: setup-checks-pr
179+
# 4. Mandatory PR Security: CodeQL (syncs to PR "Security" tab)
180+
pr-codeql:
181+
name: "🛡️ PR: CodeQL Analysis"
182+
needs: pr-setup-tools
187183
runs-on: ubuntu-latest
188184
permissions:
189185
actions: read
190186
contents: read
191-
security-events: write # Required to sync results to PR Security tab
187+
security-events: write # Mandatory for PR security alerts
192188
steps:
193-
- name: Checkout PR Source Branch
189+
- name: Checkout PR source branch
194190
uses: actions/checkout@v4
195191
with:
196192
ref: ${{ github.head_ref }}
@@ -201,24 +197,22 @@ lint-check-pr:
201197
languages: python
202198
- name: Autobuild
203199
uses: github/codeql-action/autobuild@v2
204-
- name: Perform CodeQL Analysis
200+
- name: Analyze
205201
uses: github/codeql-action/analyze@v2
206202

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]
211-
if: always()
203+
# 5. Mandatory PR Step: Block invalid merges
204+
pr-merge-gate:
205+
name: "🚫 PR: Merge Gate (MANDATORY)"
206+
needs: [pr-spell-check, pr-security-check, pr-type-check, pr-lint-check, pr-unit-tests, pr-codeql]
207+
if: github.event_name == 'pull_request'
212208
runs-on: ubuntu-latest
213209
steps:
214-
- name: Print PR Check Summary
210+
- name: Check PR validity
215211
run: |
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"
212+
# Block merge if ANY blocking check fails
213+
if [[ "${{ contains(needs.pr-lint-check.result, 'failure') || contains(needs.pr-unit-tests.result, 'failure') || contains(needs.pr-codeql.result, 'failure') }}" == "true" ]]; then
214+
echo "❌ PR CANNOT be merged: Blocking checks (lint/tests/CodeQL) failed."
221215
exit 1
222216
else
223-
echo "✅ Critical PR Checks Passed - Non-blocking issues (spelling/type) are optional to fix"
217+
echo "✅ PR is merge-ready: All blocking checks passed."
224218
fi

0 commit comments

Comments
 (0)