Three methods to create, sync, and release projects:
Project.new()Create repo on GitHub + local clone. Ifnbdev: add theme toggle, set GH Pages branch.Project.sync()(opt.nbdev_prepare) →commit→pull --rebase→push.Project.ship()Version bump →tag→ GitHub release. IfPyPI=True: build → upload.
Works with any repo to handle lifecycle with
Git, GitHub, and
PyPI.
Notebook-friendly, whether Jupyter,1
nbdev, or SolveIT!
📚💙
Built with fastgit (git
operations), ghapi (GitHub
API), and fastcore
(utilities).
This has only been tested in SolveIT, with the nbs/00_core dialog. You
may either:
- clone this repo and open
nbs/00_core(or usepj/core.py) - download
nbs/00_coreor view the shared dialog, and import it to your SolveIT instance.
More coming very soon.
# [coming soon] pip install pj-pySelect Project > sync to commit+push > release.
Authenticate once. All Project instances share the connection.
# imports not required if you run it from the 00_core dialog in SolveIT.
# Otherwise:
#from pj import Project, set_api
#from ghapi.all import GhApi
set_api(GhApi())Check that it’s fine:
get_api()Create a new project (A), or select an existing repo (B).
p = Project.new("mylib")
# = Project.new("mylib", path=None, org=None, desc=None, private=True, nbdev=False, verbose=False)Creates a private GitHub repo under your user, clones it locally,
installs nbdev hooks. org takes the GH handle.
p = Project("path/to/repo")Auto-detects pj type and owner (settings.ini for nbdev, otherwise
pyproject.toml, or other if none).
p.sync()
# = p.sync(msg="sync")Stages all, commits with message “sync”, pulls with rebase, pushes.
p.ship()
# = p.ship(part=2, dry_run=False, force=False, pypi=False, quiet=False)Bumps patch version (0.0.X), tags, creates GitHub release. No PyPI upload by default.
Project. public methods:
ls()to list files in the project’s repo.setup_pages()configures GitHub Pages manually.dark_theme()applies dark mode to nbdev docs.- Any unknown method forwards to git.
Path errors
Reassign p = Project("correct/path") to fix the current working
directory (cwd).
Restart kernel first if it still fails.
Rebase conflicts
p.g('rebase', '--abort') to start over, or resolve and continue.
Create:
p = Project.new("mylib") # Private repop = Project.new(
"mylib",
org="myorg", # GH Organization
desc="Cool lib" # About
private=False, # Public repository
nbdev=True # nbdev/Quarto GH Pages w. light/dark toggle
)Existing:
p = Project('mylib') # [cwd/]'relative/path' or '/absolute/path'Sync:
p.sync() # Commit all, rebase, push
p.sync("Fix bug #42") # Commit message (default: 'sync')Release:
p.ship() # Bump patch, tag, GitHub release
p.ship(part=1) # Bump minor
p.ship(pypi=True) # Include PyPI upload
p.ship(dry_run=True) # Preview without doing anythingUtilities:
p.ls() # List files (takes regex str)
p.ls('nbs') # List notebooks ('py' for Python files)
p.setup_pages() # Configure GitHub Pages manually
p.dark_theme() # Enable Quarto dark mode w. toggle button (nbdev docs)
p.status() # Git methods forward to p.g (thus fastgit.Git)Footnotes
-
Jupyter+Quarto specific QoL to come soon™ ↩