Skip to content
Merged
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
57 changes: 57 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ name: Python Package
# Publishing uses PyPI trusted publishing (no token): the PyPI project must
# list this repository, this workflow file and the `pypi` environment as a
# trusted publisher.
#
# The `colab` job guards the README's Open-in-Colab badge (see below); the
# weekly run catches it breaking without a push here (a new najaeda or
# anywidget, naja's tutorial benchmarks moving).

on:
push:
branches: [ main ]
tags: [ "v*" ]
pull_request:
branches: [ main ]
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -122,3 +128,54 @@ jobs:
path: dist/

- uses: pypa/gh-action-pypi-publish@release/v1

colab:
# What the Open-in-Colab badge gives a user: the notebook on this branch,
# run as Colab runs it -- nothing preinstalled, its own
# `%pip install -U naja-schematic` fetching the release from PyPI. On a
# tag it runs after publishing and must get the version just released;
# otherwise it uses the current release, so a notebook edit that needs
# an unreleased API fails here rather than in Colab.
needs: publish
if: >-
!cancelled() && (needs.publish.result == 'success' ||
(needs.publish.result == 'skipped' && !startsWith(github.ref, 'refs/tags/v')))
runs-on: ubuntu-latest
env:
PIP_NO_CACHE_DIR: "1"
steps:
- name: Checkout code
uses: actions/checkout@v5

- uses: actions/setup-python@v5
with:
# Colab's runtime Python.
python-version: "3.12"

- name: Install the notebook runner only
run: python -m pip install pytest nbformat nbclient ipykernel

- name: Pick the release to expect
shell: bash
run: |
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
version=${GITHUB_REF_NAME#v}
# A fresh upload takes a moment to show up on the index.
for i in $(seq 30); do
pip download -q --no-deps -d "$RUNNER_TEMP/dl" \
"naja-schematic==$version" && break
[ "$i" = 30 ] && { echo "naja-schematic $version not on PyPI"; exit 1; }
sleep 20
done
else
version=latest
fi
echo "NAJA_SCHEMATIC_COLAB_CHECK=$version" >> "$GITHUB_ENV"

- name: Run the Colab notebook against PyPI
# From outside python/ and without conftest.py (which imports
# najaeda): the notebook installs everything itself.
working-directory: ${{ runner.temp }}
run: >-
python -m pytest -v --noconftest
${{ github.workspace }}/python/tests/test_notebook.py
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ widget against the released PyPI package. `tests/test_notebook.py` runs it
in a real kernel (nbclient) and splices in a cell that plays the viewer
against its `view`, so a `Schematic`/protocol change that breaks it fails
CI; its install cell skips `pip install` when `naja_schematic` is already
importable, so CI tests the fresh wheel, not PyPI's.
importable, so CI tests the fresh wheel, not PyPI's. The workflow's
`colab` job runs the same test the other way (`NAJA_SCHEMATIC_COLAB_CHECK`):
the branch's notebook installing from PyPI as Colab does -- the current
release on PRs/main/weekly, the just-published one after a tag -- so a
notebook edit needing an unreleased API, or a release that breaks it, fails CI.

## Architecture

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# naja-schematic

[![Native macOS Build](https://github.com/najaeda/naja-schematic/actions/workflows/native-macos.yml/badge.svg?branch=main)](https://github.com/najaeda/naja-schematic/actions/workflows/native-macos.yml)
[![Native Linux Build](https://github.com/najaeda/naja-schematic/actions/workflows/native-linux.yml/badge.svg?branch=main)](https://github.com/najaeda/naja-schematic/actions/workflows/native-linux.yml)
[![Emscripten Build](https://github.com/najaeda/naja-schematic/actions/workflows/emscripten.yml/badge.svg?branch=main)](https://github.com/najaeda/naja-schematic/actions/workflows/emscripten.yml)
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/najaeda/naja-schematic/blob/main/python/notebooks/colab_test.ipynb)
[![Native macOS Build](https://github.com/keplertech/naja-schematic/actions/workflows/native-macos.yml/badge.svg?branch=main)](https://github.com/keplertech/naja-schematic/actions/workflows/native-macos.yml)
[![Native Linux Build](https://github.com/keplertech/naja-schematic/actions/workflows/native-linux.yml/badge.svg?branch=main)](https://github.com/keplertech/naja-schematic/actions/workflows/native-linux.yml)
[![Emscripten Build](https://github.com/keplertech/naja-schematic/actions/workflows/emscripten.yml/badge.svg?branch=main)](https://github.com/keplertech/naja-schematic/actions/workflows/emscripten.yml)
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/keplertech/naja-schematic/blob/main/python/notebooks/colab_test.ipynb)


> **Note:** This is a proof of concept in beta. Expect rough edges, breaking
Expand Down Expand Up @@ -32,7 +32,7 @@ native desktop app and a WASM app that runs in a browser or a VSCode webview.
Clone with submodules:

```bash
git clone --recursive https://github.com/najaeda/naja-schematic.git
git clone --recursive https://github.com/keplertech/naja-schematic.git
# or, if already cloned without them:
git submodule update --init --recursive
```
Expand Down Expand Up @@ -134,7 +134,7 @@ RTL-diagnosis workflow. Interfaces (in particular the wire protocol and the
## Reporting Issues

This project is beta — if something breaks, crashes, or looks wrong, please
[file a GitHub issue](https://github.com/najaeda/naja-schematic/issues/new).
[file a GitHub issue](https://github.com/keplertech/naja-schematic/issues/new).
Before reporting, check for error output in the relevant places:

- **Native build**: the terminal you launched `naja-schematic-standalone`
Expand Down
2 changes: 1 addition & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version = 1
SPDX-PackageName = "naja-schematic"
SPDX-PackageSupplier = "najaeda"
SPDX-PackageDownloadLocation = "https://github.com/najaeda/naja-schematic"
SPDX-PackageDownloadLocation = "https://github.com/keplertech/naja-schematic"

# Project's own sources, build config, docs, and scripts.
# Listed explicitly (rather than "**") so the three exceptions below
Expand Down
6 changes: 3 additions & 3 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# naja-schematic (Python package)

Interactive schematic viewer for [najaeda](https://pypi.org/project/najaeda/)
netlists: the [naja-schematic](https://github.com/najaeda/naja-schematic)
netlists: the [naja-schematic](https://github.com/keplertech/naja-schematic)
WASM viewer, packaged with the Python backend that answers it from a live
najaeda netlist.

![naja-schematic demo: tracing an output port back to its drivers, then extending the schematic pin by pin](https://raw.githubusercontent.com/najaeda/naja-schematic/main/docs/demo.gif)
![naja-schematic demo: tracing an output port back to its drivers, then extending the schematic pin by pin](https://raw.githubusercontent.com/keplertech/naja-schematic/main/docs/demo.gif)

```bash
pip install naja-schematic
```

## In a notebook (Jupyter, Google Colab, VSCode)

[Try it in Colab](https://colab.research.google.com/github/najaeda/naja-schematic/blob/main/python/notebooks/colab_test.ipynb):
[Try it in Colab](https://colab.research.google.com/github/keplertech/naja-schematic/blob/main/python/notebooks/colab_test.ipynb):
a walkthrough of every widget feature below, runnable as is.

```python
Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test = ["pytest", "nbformat", "nbclient", "ipykernel"]
naja-schematic = "naja_schematic.server:main"

[project.urls]
Homepage = "https://github.com/najaeda/naja-schematic"
Homepage = "https://github.com/keplertech/naja-schematic"

[tool.hatch.version]
path = "naja_schematic/__init__.py"
Expand Down
51 changes: 44 additions & 7 deletions python/tests/test_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,32 @@
The kernel side is all that can run headless: there's no browser to render
the widget, so a cell spliced in mid-notebook plays the viewer against the
notebook's own `view` (requests in over the comm, replies captured).

By default it runs against the installed package (the wheel under test): the
notebook's install cell is skipped. With NAJA_SCHEMATIC_COLAB_CHECK set it
runs as Colab does instead: nothing preinstalled, the install cell fetches
the release from PyPI, which must be the version given (or any, for
"latest"). CI's `colab` job runs it that way, from outside python/ and with
--noconftest, since neither najaeda nor naja_schematic is installed yet.
"""
import json
import os
from pathlib import Path

import pytest

nbformat = pytest.importorskip("nbformat")
nbclient = pytest.importorskip("nbclient")
pytest.importorskip("ipykernel")
pytest.importorskip("anywidget")
COLAB_VERSION = os.environ.get("NAJA_SCHEMATIC_COLAB_CHECK")

from naja_schematic._bundle import bundle_path # noqa: E402
if COLAB_VERSION:
# Nothing may skip here: a skipped check would pass the job.
import nbclient
import nbformat
import ipykernel # noqa: F401
else:
nbformat = pytest.importorskip("nbformat")
nbclient = pytest.importorskip("nbclient")
pytest.importorskip("ipykernel")
pytest.importorskip("anywidget")

NOTEBOOK = Path(__file__).parents[1] / "notebooks" / "colab_test.ipynb"
WIDGET_MIME = "application/vnd.jupyter.widget-view+json"
Expand Down Expand Up @@ -49,8 +63,24 @@ def _ask(request):
'''


# Run right after the install cell when checking the PyPI release: what
# Colab got must be the expected version and carry the real viewer bundle.
RELEASE_CHECK = r'''
from naja_schematic._bundle import bundle_path
_expected = {expected!r}
assert _expected == "latest" or naja_schematic.__version__ == _expected, (
naja_schematic.__version__, _expected)
assert bundle_path() is not None and bundle_path().stat().st_size > 100_000, bundle_path()
'''


@pytest.fixture
def notebook_env(tmp_path, monkeypatch):
if COLAB_VERSION:
monkeypatch.delenv("NAJA_SCHEMATIC_NOTEBOOK_TEST", raising=False)
monkeypatch.delenv("NAJA_SCHEMATIC_BUNDLE", raising=False)
return tmp_path
from naja_schematic._bundle import bundle_path
# Keeps the install cell from upgrading over the wheel under test.
monkeypatch.setenv("NAJA_SCHEMATIC_NOTEBOOK_TEST", "1")
# Without a built bundle (a source checkout), give the widget a stub:
Expand All @@ -72,16 +102,23 @@ def splice_viewer_check(nb):
def test_colab_notebook_runs(notebook_env):
nb = nbformat.read(NOTEBOOK, as_version=4)
splice_viewer_check(nb)
if COLAB_VERSION:
install = next(i for i, cell in enumerate(nb.cells)
if cell.cell_type == "code")
nb.cells.insert(install + 1, nbformat.v4.new_code_cell(
RELEASE_CHECK.format(expected=COLAB_VERSION)))
client = nbclient.NotebookClient(
nb, kernel_name="python3", timeout=600,
resources={"metadata": {"path": str(notebook_env)}})
# Raises CellExecutionError, with the failing cell, on any exception.
client.execute()

code_cells = [c for c in nb.cells if c.cell_type == "code"]
# The install cell must not have reinstalled over the package under test.
first = "".join(o.get("text", "") for o in code_cells[0].outputs)
assert "naja-schematic" in first and "Successfully installed" not in first
assert "naja-schematic" in first
if not COLAB_VERSION:
# The install cell must not have reinstalled over the package under test.
assert "Successfully installed" not in first

views = [c for c in code_cells
if any(WIDGET_MIME in o.get("data", {}) for o in c.outputs)]
Expand Down
2 changes: 1 addition & 1 deletion src/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ bool appFrame(AppState& state) {
ImGui::Text("Version: %s", NAJA_SCHEMATIC_VERSION_STRING);
ImGui::Text("Commit: %s", NAJA_SCHEMATIC_GIT_HASH);
ImGui::Text("naja: %s", NAJA_VERSION_STRING);
ImGui::Text("Project: github.com/najaeda/naja-schematic");
ImGui::Text("Project: github.com/keplertech/naja-schematic");
ImGui::Spacing();

ImGui::SeparatorText("License");
Expand Down
Loading