-
Notifications
You must be signed in to change notification settings - Fork 5.5k
138 lines (121 loc) · 5.33 KB
/
Copy pathnotebook-quality.yml
File metadata and controls
138 lines (121 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
name: Notebook Quality Check
on:
pull_request:
paths:
- '**/*.ipynb'
- 'pyproject.toml'
- 'uv.lock'
push:
branches: [main]
paths:
- '**/*.ipynb'
permissions:
contents: read
pull-requests: write
id-token: write # Anthropic Workload Identity Federation
jobs:
validate-notebooks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0 (sha-pinned)
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python 3.11
run: uv python install 3.11
- name: Install dependencies
run: |
uv sync --frozen --all-extras
- name: Lint notebooks with Ruff
run: |
uv run ruff check **/*.ipynb --show-fixes || true
uv run ruff format **/*.ipynb --check || true
- name: Validate notebook structure
id: validate
run: |
uv run python scripts/validate_notebooks.py | tee validation_output.txt
# Check if validation found issues
if grep -q "❌" validation_output.txt; then
echo "has_issues=true" >> $GITHUB_OUTPUT
exit 1
else
echo "has_issues=false" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Summarize validation issues with Claude
if: github.event_name == 'pull_request' && steps.validate.outputs.has_issues == 'true'
uses: anthropics/claude-code-action@bbfaf8e1ffe3e688f7ab65ceee78de241e24a238 # v1.0.132 (>=v1.0.130 for WIF inputs)
with:
# Anthropic auth via Workload Identity Federation — the action
# exchanges this job's GitHub OIDC token (id-token: write above)
# for a short-lived access token instead of a static API key.
anthropic_federation_rule_id: fdrl_01SqmTwzmEE547mtaYN1mqHL
anthropic_organization_id: 1ec12c5c-6542-4da8-bf2f-c15919aef01c
anthropic_service_account_id: svac_01BHcCBa1UWFvNrHMqJjuaUZ
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: |
The notebook validation found these issues:
```
$(cat validation_output.txt)
```
Create a helpful PR comment that:
- Summarizes the validation issues found
- Groups similar issues together (e.g., "7 notebooks have empty cells")
- Explains why empty cells are problematic and how to fix them (delete them or add content)
- If there are error outputs, explain they should be cleared before committing
- Uses friendly, constructive language
- Includes specific notebook names and cell numbers for reference
Format as a nice GitHub comment with markdown. Use emoji sparingly for clarity.
Post using: gh pr comment $PR_NUMBER --body "your comment"
claude_args: |
--allowedTools "Bash(gh pr comment:*),Bash(cat:*),Read"
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
# Only run API tests on main branch or for maintainers (costs money)
# TODO: this step still reads the static ANTHROPIC_API_KEY secret. The
# claude-code-action steps above use Workload Identity Federation; this
# direct-API step needs a separate inline OIDC mint+exchange (or the
# anthropic SDK's WIF env-var trio). Non-fatal in the meantime — each
# notebook execution failure is caught by the `|| echo` below.
- name: Execute notebooks (API Testing)
if: |
github.event_name == 'push' ||
github.event.pull_request.author_association == 'MEMBER' ||
github.event.pull_request.author_association == 'OWNER'
env:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
mkdir -p test_outputs
for notebook in $(find . -name "*.ipynb" -not -path "*/.*" -not -path "*/test_outputs/*"); do
echo "📓 Testing: $notebook"
output_name=$(echo "$notebook" | sed 's|/|_|g' | sed 's|\.|_|g')
# Use nbconvert to execute notebooks and save outputs
uv run jupyter nbconvert --to notebook \
--execute "$notebook" \
--ExecutePreprocessor.kernel_name=python3 \
--ExecutePreprocessor.timeout=120 \
--output "test_outputs/${output_name}_executed.ipynb" \
--output-dir=. \
|| echo "⚠️ Failed: $notebook"
done
# Mock testing for external contributors
- name: Execute notebooks (Mock Testing)
if: |
github.event_name == 'pull_request' &&
github.event.pull_request.author_association != 'MEMBER' &&
github.event.pull_request.author_association != 'OWNER'
run: |
echo "🔒 Running in mock mode for external contributor"
for notebook in $(find . -name "*.ipynb" -not -path "*/.*"); do
echo "📓 Validating structure: $notebook"
uv run python -m nbformat.validator "$notebook"
done
- name: Upload test outputs
if: always()
uses: actions/upload-artifact@v6
with:
name: notebook-test-outputs
path: test_outputs/
retention-days: 7