Skip to main content

Development

This page is for contributors to the cs-jupyter repository. Read Architecture first. Tests run against fakes; only serving the site for manual use needs a real Airavata session server.

Prerequisites​

ToolFor
BunJavaScript dependencies and scripts
uv, Python 3.11 or newerJupyterLab and JupyterLite build tooling
Chromium (bunx playwright install --with-deps chromium)test:browser only
Go, the version in tools/go.modbun run types only
An Airavata session server to callServing the site; a local one listens on http://127.0.0.1:8045 by default. Airavata development covers building one

Setup​

Install the dependencies:

bun install --frozen-lockfile
uv sync --frozen
lefthook install # optional pre-commit checks

The repository ships cybershuttlePlaneApiUrl empty, and the client refuses to start without a valid one. Set it before serving, for example to http://127.0.0.1:8045/api/v1. It must be absolute HTTPS, or HTTP on loopback, with no credentials, query or fragment. Set it in one of two places:

FileTrade-off
Root jupyter-lite.jsonSurvives bun run dev, but test:dist fails while it is set, because the shipped value must be empty; never commit it
dist/jupyter-lite.json after bun run buildWhat a deployment does; serve dist/ with any static server instead of bun run dev

Then serve the site:

bun run dev

It prints the address. Add that origin to the session server's --allowed-origin; without it the browser blocks sign-in and every Airavata request. To confirm the setup, open the address, sign in, and check that the Sessions section lists the account's sessions.

Scripts​

ScriptDoes
buildclean, build:lib, build:lite
build:libtsc -b into lib/
build:extensionjupyter-builder build into labextension/
build:litebuild:extension, then jupyter lite build into dist/
cleanRemoves lib, labextension, dist and build caches
devbuild:lib, build:extension, jupyter lite serve
linttypecheck and prettier --check .
typechecktsc -b and the tests' tsconfig
typesRegenerates src/api/*.ts from Airavata with tygo
testVitest (jsdom) over tests/**/*.test.ts
test:distChecks the built dist/
test:browserPlaywright Chromium against dist/ with a fake Airavata, OAuth issuer and Jupyter Server
test:alltest, test:dist, test:browser

test:dist, test:browser and test:all read the built site; after changing src/, run bun run build:lib && bun run build:lite first.

Tests​

Logic in one module is a Vitest unit. Anything in the Launcher, a dialog or the page load needs test:browser, the only suite that runs the real JupyterLab.

SuiteCovers
VitestUnits, one file per topic named in its top comment
test:distFederated extension, empty cybershuttlePlaneApiUrl, plugin enable and disable lists, deferred terminal plugin, no in-browser kernel
test:browserPKCE sign-in, Start, the GitHub Dev Tunnels device flow, Add Session to Connect, Launcher re-mounting, SSH authentication, sign-out

tests/session-contract.test.ts pins the Airavata wire contract; change it together with PlaneClient.ts. tests/setup.ts sets cybershuttlePlaneApiUrl and supplies the storage and <dialog> APIs jsdom lacks.

Generated types​

tygo generates src/api/*.ts from Airavata's wire.go files (tools/tygo.yaml), mapping time.Time to string; do not edit them by hand. When the client needs a route or field from a newer Airavata release, move the pin in tools/go.mod:

cd tools
go get github.com/cyber-shuttle/cs-plane@<commit>
cd ..
bun run types

Then update the validators in PlaneClient.ts and tests/session-contract.test.ts for any changed field; a mismatch fails typecheck.

Checks and releases​

WhereRuns
lefthook pre-commitIn parallel: typecheck, prettier --check on staged files, bun run test
CI testbun install --frozen-lockfile, bun run lint, bun run test
CI typesbun run types, then git diff --exit-code src/api, new files included
CI e2ebun run build, test:dist, Playwright Chromium, test:browser

CI runs on pull requests and on pushes to main.

Nothing is published; deployments rebuild dist/ from main. Record user-visible changes under ## [Unreleased] in CHANGELOG.md (Keep a Changelog) in the same pull request.