Skip to content

Set up uv for dependency management and add PR preview workflow #1

Set up uv for dependency management and add PR preview workflow

Set up uv for dependency management and add PR preview workflow #1

name: PR Preview (GitHub Pages)
# Build and deploy to GitHub Pages on pull requests
on:
pull_request:
branches:
- main
- master
jobs:
build-preview:
runs-on: ubuntu-latest
permissions:
contents: write # Allow pushing to gh-pages branch
pull-requests: write # Allow commenting on PRs
steps:
- uses: actions/checkout@v4
# Install uv for faster dependency management
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
# Set up Python using uv
- name: Set up Python
run: uv python install 3.11
# Install dependencies using uv
- name: Install dependencies
run: uv sync
# Cache executed notebooks between runs
- name: Cache executed notebooks
uses: actions/cache@v4
with:
path: _build/.jupyter_cache
key: jupyter-book-cache-${{ hashFiles('uv.lock') }}
# Build the book
- name: Build the book
run: |
uv run jupyter-book build .
# Deploy to GitHub Pages preview folder
- name: Deploy PR Preview
run: |
# Configure git
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
# Clone gh-pages branch
git clone --branch gh-pages --single-branch https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} gh-pages
# Create preview directory for this PR
PR_PREVIEW_DIR="gh-pages/preview/pr-${{ github.event.pull_request.number }}"
rm -rf "$PR_PREVIEW_DIR"
mkdir -p "$PR_PREVIEW_DIR"
# Copy built site to preview directory
cp -r _build/html/* "$PR_PREVIEW_DIR/"
# Add .nojekyll to ensure GitHub Pages processes the site correctly
touch "$PR_PREVIEW_DIR/.nojekyll"
# Commit and push
cd gh-pages
git add .
git commit -m "Deploy preview for PR #${{ github.event.pull_request.number }}" || echo "No changes to commit"
git push origin gh-pages
# Comment on PR with preview link
- name: Comment PR
uses: actions/github-script@v7
with:
script: |
const baseUrl = 'https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}';
const previewUrl = `${baseUrl}/preview/pr-${{ github.event.pull_request.number }}`;
const body = `🚀 **GitHub Pages Deploy Preview ready!**\n\n📖 Preview: ${previewUrl}\n\n_This preview will be updated on every commit to this PR._`;
// Find and update existing comment or create new one
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' && comment.body.includes('GitHub Pages Deploy Preview ready!')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}