Development¶
Everything you need to work on osw-python. Each step comes as a make
one-liner or as the underlying commands, pick your style with the tabs.
Setup¶
Requires uv and git.
make install
uv sync
uv run pre-commit install
pre-commit install wires both hook stages (pre-commit and commit-msg);
the latter enforces the commit message format below.
Quality checks¶
Lock consistency, linting and formatting (pre-commit incl. ruff), static type checking (ty) and dependency audit (deptry) in one go:
make check
uv lock --locked
uv run pre-commit run -a
uv run ty check
uv run deptry src
Testing¶
Add new tests as test_*.py under tests/. Integration tests are
excluded by default:
make test
uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=xml
Integration tests¶
Integration tests run against a live wiki and need credentials; tests
whose credentials are missing skip instead of fail. CI runs them on every
pull request into main (workflow integration.yml), so they gate the
release rather than run after it.
WIKI_DOMAIN="<domain>" WIKI_USERNAME="<login>" WIKI_PASSWORD="<password>" \
make test-integration
uv run pytest tests/integration -o addopts="" \
--wiki_domain "<domain>" \
--wiki_username "<login>" \
--wiki_password "<password>"
Credentials¶
Credentials are never written to disk automatically. For a single instance,
set OSW_USERNAME / OSW_PASSWORD (e.g. via a .env file) or answer the
interactive prompt; both are kept in memory only.
For transfers between several OpenSemanticLab instances, keep a hand-maintained
accounts.pwd.yaml at the project root (read only, gitignored by default), with
one entry per instance IRI:
https://wiki-a.example.org:
username: <login>
password: <password>
https://wiki-b.example.org:
username: <login>
password: <password>
OswExpress(domain=...) with no credential arguments reads this file if present;
each connection is matched to the longest IRI it contains.
Documentation¶
Serve locally with live reload at http://localhost:8000, or run the
strict build that fails on any warning:
make docs # serve with live reload
make docs-test # strict build
uv run zensical serve
uv run zensical build -s
Building¶
make build
uv build
Commit messages¶
Commits follow Conventional Commits:
type(scope): subject, scope optional. The local commit-msg hook (see
Setup) rejects malformed messages, because they drive the automated release
below.
| Type | Release effect |
|---|---|
feat |
minor release |
fix, perf |
patch release |
BREAKING CHANGE: footer, or ! after the type |
major release |
docs, chore, test, refactor, ci, style, build |
no release |
Releasing¶
There is no standing release branch: work goes feature branch -> main
directly. Every pull request into main runs main.yml (quality, tests,
docs), the integration suite, and a version-preview job that comments the
version a merge would release, computed with the same conventional commits.
Merging to main starts the release job
(on-release-main.yml), which pauses on the pypi GitHub environment for a
required reviewer to approve -- this is the deliberate-release control, in
place of a staging branch. Once approved,
python-semantic-release
bumps the static version in pyproject.toml and CITATION.cff (never edited
by hand), updates CHANGELOG.md, relocks uv.lock, commits, tags vX.Y.Z,
builds, publishes to PyPI via trusted publishing and deploys the versioned
docs. Reject the approval and nothing ships.
To preview what the next release would be locally:
uv run semantic-release --noop version