Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/pr-comment-notebook-format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: PR Comment on Notebook Format Check

on:
workflow_run:
workflows: ["Test Notebook Format"]
types: [completed]

# Write permissions for commenting
permissions:
pull-requests: write

jobs:
comment:
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure'

steps:
- name: Download PR comment data
uses: actions/download-artifact@v4
with:
name: pr-comment-data
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- name: Post comment on PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');

// Read PR number from artifact
const prNumber = parseInt(fs.readFileSync('pr_number', 'utf8').trim());

if (!prNumber || isNaN(prNumber)) {
console.log('No valid PR number found, skipping comment.');
return;
}

const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${{ github.event.workflow_run.id }}`;

const commentBody = `## ❌ Notebook Format Check Failed

**One or more Jupyter notebooks have format or metadata issues.**

Please check the [workflow run logs](${runUrl}) for details on which notebooks have issues.

### What is checked:

1. **Schema integrity** — notebooks must be valid according to the Jupyter notebook JSON schema
2. **Metadata conformance** — notebooks must have the standard metadata block (accelerator, colab, kernelspec, language_info)
3. **Clean outputs** — non-SOLUTION notebooks must have outputs, execution counts, and execution timing metadata cleared

### How to fix:

\`\`\`bash
# Check all tutorials
python3 brev/test-notebook-format.py

# Check a specific tutorial
python3 brev/test-notebook-format.py <tutorial-name>

# Auto-fix all issues
python3 brev/test-notebook-format.py --fix

# Auto-fix a specific tutorial
python3 brev/test-notebook-format.py <tutorial-name> --fix
\`\`\`
`;

// Check if we already commented on this PR to avoid spam
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Notebook Format Check Failed')
);

if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
console.log(`Updated existing comment on PR #${prNumber}`);
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log(`Created comment on PR #${prNumber}`);
}
47 changes: 47 additions & 0 deletions .github/workflows/test-notebook-format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Test Notebook Format

on:
push:
branches:
- '**'
pull_request:
types: [opened, reopened, synchronize]

# Minimal permissions - only read access needed for checks
permissions:
contents: read

jobs:
test-notebook-format:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install nbformat
run: pip install nbformat

- name: Check notebook format
id: notebook-format-check
run: python3 brev/test-notebook-format.py

- name: Save PR number and result
if: always() && github.event_name == 'pull_request'
run: |
mkdir -p ./pr-comment-data
echo '${{ github.event.pull_request.number }}' > ./pr-comment-data/pr_number
echo '${{ steps.notebook-format-check.outcome }}' > ./pr-comment-data/outcome

- name: Upload PR comment data
if: always() && github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: pr-comment-data
path: pr-comment-data/
retention-days: 1
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,14 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": ".venv",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -507,7 +513,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.11.7"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand All @@ -614,5 +620,5 @@
}
},
"nbformat": 4,
"nbformat_minor": 4
"nbformat_minor": 5
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,10 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "629cb5c6-3c72-4658-b3cb-ea9352c89ee6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"init step...\n",
"sort step...\n",
"dot step...\n",
"done\n"
]
}
],
"outputs": [],
"source": [
"import sys\n",
"import cupy as cp\n",
Expand Down Expand Up @@ -766,6 +755,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,12 @@
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand All @@ -1531,7 +1537,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
"version": "3.11.7"
}
},
"nbformat": 4,
Expand Down
Loading
Loading