diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f02c0a7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Lint (flake8) + run: | + flake8 . + + - name: Run unit tests (pytest) + run: | + pytest -q --maxfail=1 + + - name: Execute all notebooks (nbconvert) + run: | + python - <<'PY' + import glob, subprocess, sys + notebooks = glob.glob('**/*.ipynb', recursive=True) + if not notebooks: + print("No notebooks found.") + sys.exit(0) + for n in notebooks: + print("Executing", n) + subprocess.check_call([ + sys.executable, "-m", "jupyter", "nbconvert", + "--to", "notebook", "--execute", "--inplace", + "--ExecutePreprocessor.timeout=600", n + ]) + PY diff --git a/.github/workflows/deploy-notebooks-pages.yml b/.github/workflows/deploy-notebooks-pages.yml new file mode 100644 index 0000000..6e10c24 --- /dev/null +++ b/.github/workflows/deploy-notebooks-pages.yml @@ -0,0 +1,90 @@ +on: + push: + branches: + - '**' + +name: Build and deploy notebooks to GitHub Pages (per-branch) + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + permissions: + contents: write # needed to push gh-pages + steps: + - name: Checkout repository (current branch) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine branch name + id: branch + run: | + echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" > $GITHUB_ENV + echo "branch=${GITHUB_REF#refs/heads/}" > $GITHUB_OUTPUT + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; else pip install jupyter nbconvert nbformat; fi + + - name: Build notebooks to HTML for this branch + run: | + mkdir -p site/${{ env.BRANCH_NAME }} + python scripts/build_notebooks.py site/${{ env.BRANCH_NAME }} + + - name: Prepare gh-pages branch workspace + run: | + # If gh-pages exists, clone it, otherwise init an empty gh-pages branch + REPO_URL="https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" + if git ls-remote --exit-code origin gh-pages; then + git clone --depth 1 --branch gh-pages "$REPO_URL" gh-pages || git clone "$REPO_URL" gh-pages + else + # create temporary folder, init gh-pages and push + mkdir gh-pages + cd gh-pages + git init + git remote add origin "$REPO_URL" + git checkout -b gh-pages 2>/dev/null || git checkout gh-pages + touch .nojekyll + git add .nojekyll + git commit -m "Initialize gh-pages" + git push origin gh-pages + cd .. + git clone --depth 1 --branch gh-pages "$REPO_URL" gh-pages + fi + + - name: Copy built site into gh-pages under branch folder + run: | + set -e + rsync -a --delete site/${{ env.BRANCH_NAME }}/ gh-pages/${{ env.BRANCH_NAME }}/ + # ensure a top-level index exists listing branches (optional) + python3 - <<'PY' + import os, json + root='gh-pages' + items = sorted([d for d in os.listdir(root) if os.path.isdir(os.path.join(root,d))]) + index_path = os.path.join(root, 'index.html') + with open(index_path, 'w') as f: + f.write("
{e}")
+ results.append((nb, html_name, False, str(e)))
+
+ # Create index.html listing all notebooks
+ index_path = os.path.join(output_dir, 'index.html')
+ with open(index_path, 'w') as f:
+ f.write("