Skip to content

Commit df8d23d

Browse files
committed
add github workflow
1 parent 0fe3626 commit df8d23d

1 file changed

Lines changed: 153 additions & 0 deletions

File tree

.github/workflows/lint-format.yml

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
name: Lint and Format Check
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '**/*.py'
7+
- '**/*.ipynb'
8+
- 'pyproject.toml'
9+
- 'uv.lock'
10+
- 'Makefile'
11+
push:
12+
branches: [main]
13+
paths:
14+
- '**/*.py'
15+
- '**/*.ipynb'
16+
17+
permissions:
18+
contents: read
19+
pull-requests: write
20+
21+
jobs:
22+
lint-and-format:
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Install uv
29+
uses: astral-sh/setup-uv@v4
30+
with:
31+
enable-cache: true
32+
cache-dependency-glob: "uv.lock"
33+
34+
- name: Set up Python 3.11
35+
run: uv python install 3.11
36+
37+
- name: Install dependencies
38+
run: |
39+
uv sync --frozen --all-extras
40+
41+
- name: Get changed files
42+
id: changed-files
43+
run: |
44+
if [ "${{ github.event_name }}" = "pull_request" ]; then
45+
# For PRs, get files changed compared to base branch
46+
git fetch origin ${{ github.base_ref }}
47+
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(py|ipynb)$' || echo "")
48+
else
49+
# For push to main, check all files
50+
CHANGED_FILES=$(find . -type f \( -name "*.py" -o -name "*.ipynb" \) -not -path "./.venv/*" -not -path "./venv/*" -not -path "*/build/*" -not -path "*/dist/*")
51+
fi
52+
53+
if [ -z "$CHANGED_FILES" ]; then
54+
echo "No Python or notebook files changed"
55+
echo "has_files=false" >> $GITHUB_OUTPUT
56+
echo "" > changed_files.txt
57+
else
58+
echo "Changed files:"
59+
echo "$CHANGED_FILES"
60+
echo "$CHANGED_FILES" > changed_files.txt
61+
echo "has_files=true" >> $GITHUB_OUTPUT
62+
fi
63+
64+
- name: Check formatting with ruff
65+
id: format-check
66+
if: steps.changed-files.outputs.has_files == 'true'
67+
run: |
68+
echo "## Formatting Check Results" >> $GITHUB_STEP_SUMMARY
69+
CHANGED_FILES=$(cat changed_files.txt)
70+
71+
if [ -z "$CHANGED_FILES" ]; then
72+
echo "✅ No files to check" >> $GITHUB_STEP_SUMMARY
73+
echo "has_format_issues=false" >> $GITHUB_OUTPUT
74+
exit 0
75+
fi
76+
77+
if echo "$CHANGED_FILES" | xargs uv run ruff format --check; then
78+
echo "✅ All changed files are properly formatted" >> $GITHUB_STEP_SUMMARY
79+
echo "has_format_issues=false" >> $GITHUB_OUTPUT
80+
else
81+
echo "❌ Some changed files need formatting" >> $GITHUB_STEP_SUMMARY
82+
echo "has_format_issues=true" >> $GITHUB_OUTPUT
83+
exit 1
84+
fi
85+
continue-on-error: true
86+
87+
- name: Run ruff linting
88+
id: lint-check
89+
if: steps.changed-files.outputs.has_files == 'true'
90+
run: |
91+
echo "## Linting Check Results" >> $GITHUB_STEP_SUMMARY
92+
CHANGED_FILES=$(cat changed_files.txt)
93+
94+
if [ -z "$CHANGED_FILES" ]; then
95+
echo "✅ No files to check" >> $GITHUB_STEP_SUMMARY
96+
echo "has_lint_issues=false" >> $GITHUB_OUTPUT
97+
exit 0
98+
fi
99+
100+
if echo "$CHANGED_FILES" | xargs uv run ruff check; then
101+
echo "✅ No linting issues found in changed files" >> $GITHUB_STEP_SUMMARY
102+
echo "has_lint_issues=false" >> $GITHUB_OUTPUT
103+
else
104+
echo "❌ Linting issues found in changed files" >> $GITHUB_STEP_SUMMARY
105+
echo "has_lint_issues=true" >> $GITHUB_OUTPUT
106+
echo "$CHANGED_FILES" | xargs uv run ruff check 2>&1 | tee lint_output.txt || true
107+
exit 1
108+
fi
109+
continue-on-error: true
110+
111+
- name: Post lint/format issues to PR
112+
if: |
113+
github.event_name == 'pull_request' &&
114+
(steps.format-check.outputs.has_format_issues == 'true' ||
115+
steps.lint-check.outputs.has_lint_issues == 'true')
116+
uses: anthropics/claude-code-action@v1
117+
with:
118+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
119+
github_token: ${{ secrets.GITHUB_TOKEN }}
120+
prompt: |
121+
The linting and formatting checks found issues.
122+
123+
Format check status: ${{ steps.format-check.outputs.has_format_issues == 'true' && 'Failed' || 'Passed' }}
124+
Lint check status: ${{ steps.lint-check.outputs.has_lint_issues == 'true' && 'Failed' || 'Passed' }}
125+
126+
${{ steps.lint-check.outputs.has_lint_issues == 'true' && format('Linting issues:\n```\n{0}\n```', steps.lint-check.outputs.lint_output) || '' }}
127+
128+
Create a helpful PR comment that:
129+
- Summarizes the formatting and linting issues
130+
- Explains how to fix them locally using: `make fix`
131+
- Mentions they can check before pushing with: `make check`
132+
- Uses friendly, constructive language
133+
134+
Post using: gh pr comment $PR_NUMBER --body "your comment"
135+
claude_args: |
136+
--allowedTools "Bash(gh pr comment:*)"
137+
env:
138+
PR_NUMBER: ${{ github.event.pull_request.number }}
139+
140+
- name: Fail if issues found
141+
if: |
142+
steps.format-check.outputs.has_format_issues == 'true' ||
143+
steps.lint-check.outputs.has_lint_issues == 'true'
144+
run: |
145+
echo "❌ Linting or formatting issues found. Run 'make fix' locally to resolve."
146+
exit 1
147+
148+
- name: Success
149+
if: |
150+
steps.format-check.outputs.has_format_issues == 'false' &&
151+
steps.lint-check.outputs.has_lint_issues == 'false'
152+
run: |
153+
echo "✅ All linting and formatting checks passed!"

0 commit comments

Comments
 (0)