plesty-sdk 0.4.0__tar.gz → 0.5.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/CHANGELOG.md +147 -1
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/PKG-INFO +1 -1
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/REUSE.toml +8 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/architecture.md +71 -41
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/check.md +6 -4
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/docs.md +5 -5
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/init.md +104 -42
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/update.md +11 -1
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/getting-started.md +8 -7
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/index.md +2 -2
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/gl-secret-detection-report.json +6 -6
- plesty_sdk-0.5.0.dev1/packaging/versioning.py +72 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/field-test.py.template +12 -1
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/next-steps.yaml +2 -1
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/extras/analyzer/analyzer.py +5 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/extras/device/base_device.py +3 -3
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/extras/device/preflight.py +389 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/extras/experiment/experiment.py +10 -8
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/template/packaging/versioning.py +72 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/{% if project_type in ['device', 'experiment'] %}__main__.py{% endif %}.jinja +98 -110
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/pyproject.toml.jinja +7 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/tests/test_{{module_name}}.py.jinja +23 -10
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/template/tests/{% if project_type == 'device' %}test_preflight.py{% endif %}.jinja +293 -0
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/template/{% if project_type == 'experiment' %}config{% endif %}/default.yaml +11 -0
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/template/{% if project_type == 'experiment' %}setup.yaml{% endif %} +24 -0
- plesty_sdk-0.5.0.dev1/plesty/sdk/assets/templates/template/{% if project_type in ['device', 'experiment'] %}.env.example{% endif %}.jinja +55 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/check.py +307 -3
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/field_test.py +69 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/init.py +16 -3
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/mock_test.py +33 -3
- plesty_sdk-0.5.0.dev1/plesty/sdk/commands/update.py +277 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/report.py +1 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/semver.py +60 -18
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/pyproject.toml +14 -1
- plesty_sdk-0.5.0.dev1/tests/test_check_experiment_manifest.py +360 -0
- plesty_sdk-0.5.0.dev1/tests/test_device_preflight_template.py +241 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_field_test_scaffold.py +31 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_init.py +144 -13
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_mock_test_scaffold.py +78 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_semver.py +80 -2
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_update.py +110 -0
- plesty_sdk-0.5.0.dev1/tests/test_versioning_rule.py +125 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/uv.lock +48 -12
- plesty_sdk-0.4.0/plesty/sdk/assets/templates/template/{% if project_type == 'experiment' %}config{% endif %}/default.yaml +0 -6
- plesty_sdk-0.4.0/plesty/sdk/assets/templates/template/{% if project_type in ['device', 'experiment'] %}.env.example{% endif %}.jinja +0 -38
- plesty_sdk-0.4.0/plesty/sdk/commands/update.py +0 -141
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/.coverage +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/.gitignore +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/.gitlab-ci.yml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/.mailmap +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/LICENSE +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/README.md +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/license.md +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/commands/manual.md +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/docs/toc.yaml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/__init__.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/check/guidance.yaml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/docs-build-gitlab-ci.yml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/hub-theme/plesty-hub.css +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/hub-theme/plesty-logo.svg +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/hub-theme/plesty-mark.svg +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/hub-theme/plesty-versions.css +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/hub-theme/plesty-versions.js +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/client-field-test.py.template +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/field-test-env.example +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/field-test-questions.yaml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/init/mock-test.py.template +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/manual/pdf-common.css +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/manual/pdf-page-landscape.css +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/manual/pdf-page-portrait.css +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/ruff.toml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/copier.yml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/extras/device/device.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/.gitignore +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/CHANGELOG.md.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/LICENSE +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/README.md.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/REUSE.toml.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/docs/index.md.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/docs/toc.yaml +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/__init__.py.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/config.yaml.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/assets/templates/template/tests/__init__.py.jinja +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/authorship.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/cache.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/cli.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/__init__.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/__init__.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/deploy.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/generate.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/picker.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/serve.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/docs/sphinx_builder.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/license.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/commands/manual.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/context.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/plesty/sdk/tui.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/__init__.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_authorship.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_cache.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_check.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_cli.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_context.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_docs_deploy.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_docs_generate.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_docs_picker.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_docs_serve.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_license.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_manual.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_report.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_sphinx_builder.py +0 -0
- {plesty_sdk-0.4.0 → plesty_sdk-0.5.0.dev1}/tests/test_tui.py +0 -0
|
@@ -2,7 +2,153 @@
|
|
|
2
2
|
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com).
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [0.5.0.dev1] — 2026-09-25
|
|
6
|
+
|
|
7
|
+
Development pre-release, the first of the 0.5 line: scaffolds generated against
|
|
8
|
+
plesty-lib 0.5 (`PLESTY_DATA`, `setup.yaml`, `ExperimentCLI`, device preflight) need an SDK that
|
|
9
|
+
writes them before 0.5.0 is ready to be called finished.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **A snapshot is named for the release its line is working towards.**
|
|
13
|
+
versioningit's default `next_version` bumps the minor, which is wrong on
|
|
14
|
+
both lines governance#20 runs: six commits after `v0.4.0`, `maintain/0.4`
|
|
15
|
+
built `0.5.0.dev6`, which sorts *above* the `0.4.1` the line exists to
|
|
16
|
+
produce, so a bench given that snapshot is never upgraded by the release;
|
|
17
|
+
and `exp` sitting on `v0.5.0.dev3` built `0.6.0.devN`, a minor nobody is
|
|
18
|
+
working towards.
|
|
19
|
+
|
|
20
|
+
`plesty init` now ships `packaging/versioning.py` and points
|
|
21
|
+
`[tool.hatch.version.next-version]` at it: `exp` and `main` take the next
|
|
22
|
+
minor, every other branch the release its last tag precedes — the next
|
|
23
|
+
patch on `maintain/0.N`. A branch that names no line, including the detached
|
|
24
|
+
HEAD CI checks out, takes the patch, which understates and so can never
|
|
25
|
+
shadow a release. A build at a tag is unaffected.
|
|
26
|
+
|
|
27
|
+
An existing module takes the same rule with `plesty update --versioning`,
|
|
28
|
+
which writes the file, adds the block, and annotates `packaging/**` in
|
|
29
|
+
`REUSE.toml` unless an annotation already covers it — versioningit imports
|
|
30
|
+
the rule at build time, and the `.pyc` Python writes beside it fails gate 9
|
|
31
|
+
otherwise. plesty-sdk itself now builds with the rule (plesty-sdk#41).
|
|
32
|
+
- **Every scaffolded device module ships a preflight.** A module installs,
|
|
33
|
+
configures and serves happily with no instrument behind it: the transport
|
|
34
|
+
logs that it found nothing, the server binds regardless, and a client can
|
|
35
|
+
hold a resource against a device that was never there. `plesty init device`
|
|
36
|
+
now generates `plesty/<module>/preflight.py`, and both entry points call it
|
|
37
|
+
before touching the instrument — `python -m plesty.<module>` before the
|
|
38
|
+
server binds, `tests/field_test.py` before a run. It refuses only an
|
|
39
|
+
instrument the transport looked for and did not find; a transport that
|
|
40
|
+
cannot tell without opening answers *unknown*, and unknown serves.
|
|
41
|
+
|
|
42
|
+
It answers the four questions that were being answered by hand in
|
|
43
|
+
plesty-k10cr1 and plesty-lightfield-spectrometer: whether the operating
|
|
44
|
+
system enumerated the instrument and bound a driver, what discovery resolved
|
|
45
|
+
and what it saw, which `.env` is in effect and whether its server port agrees
|
|
46
|
+
with the one the fleet handed over as `--tcp-port`, and which version of the
|
|
47
|
+
module is installed and whether it came from PyPI or a checkout. The
|
|
48
|
+
transport half is `TrafficManager.preflight()` (plesty-lib#50, >= 0.5.0.dev7);
|
|
49
|
+
the module reaches it through one author hook, `transport()`, filled in
|
|
50
|
+
beside `Device.connect()`. `--skip-preflight` serves anyway. The generated
|
|
51
|
+
`tests/test_preflight.py` mocks the transport, so the logic runs in CI with
|
|
52
|
+
nothing attached and the module stays over the coverage gate. `summary()` is
|
|
53
|
+
the only output that may name a serial number; what a report file gets is
|
|
54
|
+
`to_dict()`, which carries none (plesty-sdk#39).
|
|
55
|
+
|
|
56
|
+
`plesty init field-test` reads whether the module has a `preflight.py`: a
|
|
57
|
+
module scaffolded before this release gets a `preflight()` that says what is
|
|
58
|
+
missing and lets the run go on, so the generator keeps working on every
|
|
59
|
+
module the hub already has.
|
|
60
|
+
|
|
61
|
+
The `plesty-lib` floor rises to `0.5.0.dev7`, the first whose transports
|
|
62
|
+
answer `preflight()`.
|
|
63
|
+
- **Gate e3 — Experiment Manifest.** An experiment module now has a run
|
|
64
|
+
contract to declare (`plesty.lib.experiment.ExperimentCLI`, plesty-lib#54),
|
|
65
|
+
and nothing enforced it: a module could drift back to a hand-rolled
|
|
66
|
+
`argparse` and every console offering its settings would silently go empty.
|
|
67
|
+
|
|
68
|
+
For `module_type = "experiment"`, `python -m <module> --manifest` must print
|
|
69
|
+
the declaration as JSON; the gate checks that it names this module, that
|
|
70
|
+
every configuration parameter carries a `dtype` and a `description` — a
|
|
71
|
+
control rendered without them is a box with a name on it — and that a
|
|
72
|
+
bounded parameter carries a `unit`, or its bounds read as bare numbers.
|
|
73
|
+
|
|
74
|
+
It then compares the schema with the module's own `config/*.yaml`. A key the
|
|
75
|
+
configuration sets and the schema omits cannot be edited by anything reading
|
|
76
|
+
the manifest; a key the schema declares and no configuration sets renders as
|
|
77
|
+
a setting that does nothing. That drift is the reason the gate exists: a
|
|
78
|
+
schema nobody keeps current is worse than none, because a console renders it
|
|
79
|
+
as fact.
|
|
80
|
+
|
|
81
|
+
- **`plesty init` scaffolds an experiment onto `ExperimentCLI`.** The generated
|
|
82
|
+
`__main__.py` declares a `Manifest` and a `SCHEMA` matching the scaffolded
|
|
83
|
+
`config/default.yaml`, and registers a rig builder and an experiment builder
|
|
84
|
+
in place of its own `argparse` — so a new module passes e3 as scaffolded, and
|
|
85
|
+
gets `--config`, `--resume`, `--run-root`, `--dry-run` and `--manifest`
|
|
86
|
+
without writing them. The experiment entry point no longer calls
|
|
87
|
+
`run_server` itself: `ExperimentCLI.main` does, so the loop pyzmq needs is
|
|
88
|
+
the library's guarantee rather than something each scaffold must remember.
|
|
89
|
+
|
|
90
|
+
The `plesty-lib` floor rises to `0.5.0.dev4`, the first with `ExperimentCLI`.
|
|
91
|
+
- **Gate 8 baselines against the line being built.** It compared the working
|
|
92
|
+
tree against the newest release of the whole project, which is right only
|
|
93
|
+
while there is one line. A `maintain/x.y` branch takes fixes to its own
|
|
94
|
+
features and merges upward only, so it never gains what a later line added:
|
|
95
|
+
once that line publishes, every function it introduced would read as a
|
|
96
|
+
removal from the older tree, on every run, for as long as the line is
|
|
97
|
+
supported. The baseline is now the newest release at or below the tree's own
|
|
98
|
+
`major.minor`, taken from the line the checkout can reach by tag. Pre-release
|
|
99
|
+
and yanked files are skipped. Nothing changes on the newest line.
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
- **A scaffolded experiment ships the `setup.yaml` plesty-lib requires**
|
|
103
|
+
(plesty-sdk#43). plesty-lib 0.5.0.dev6 made every experiment module declare
|
|
104
|
+
its benches and devices in a committed `setup.yaml`; `plesty init experiment`
|
|
105
|
+
wrote none. It now writes one — `bench-local` with `data: ${LOCAL_DATA}`, a
|
|
106
|
+
commented remote-bench example, and a `device` entry for the scaffold's
|
|
107
|
+
`RIG` naming its bench — and `.env.example` suggests the variables it names:
|
|
108
|
+
`LOCAL_DATA`, empty, so the first real run stops and says to set it, with
|
|
109
|
+
`DEVICE_ADDRESS` and `PLESTY_DATA` kept as commented overrides for running
|
|
110
|
+
without a bench. The manifest declares `LOCAL_DATA`. A module scaffolded
|
|
111
|
+
earlier adds the two files by hand; `hub/experiments/plesty-pol-pl` has a
|
|
112
|
+
working pair.
|
|
113
|
+
- **A scaffolded experiment names the shared disk the way its library reads
|
|
114
|
+
it.** plesty-lib 0.5.0.dev6 replaced `PLESTY_DATA_DIR` and
|
|
115
|
+
`PLESTY_DATA_MOUNT` with one variable, `PLESTY_DATA` — the shared disk as
|
|
116
|
+
each machine sees it, with every path between machines relative to it — and
|
|
117
|
+
the scaffold, already pinned above that release, kept writing the two old
|
|
118
|
+
names into `.env.example` and the manifest. A module scaffolded from it set
|
|
119
|
+
variables nothing read, so its runs silently went to `./runs` instead of the
|
|
120
|
+
share. `.env.example`, the manifest and the next steps now carry
|
|
121
|
+
`PLESTY_DATA`, and the generated `experiment.py` routes a writing device with
|
|
122
|
+
`set_data_path(self.raw_dir, subdirs=True)` and records its files with
|
|
123
|
+
`raw_file()`. A module scaffolded earlier migrates by hand: set `PLESTY_DATA`
|
|
124
|
+
where `PLESTY_DATA_MOUNT` was and drop `PLESTY_DATA_DIR`.
|
|
125
|
+
- **A scaffolded experiment passes its own tests.** When the entry point moved
|
|
126
|
+
onto `ExperimentCLI`, the generated `tests/test_<module>.py` was not moved
|
|
127
|
+
with it: it still imported `load_config` and called `build_devices(address)`,
|
|
128
|
+
neither of which the new `__main__.py` has, so every experiment module failed
|
|
129
|
+
three of its tests — and gate 7 — as scaffolded. The tests now go through the
|
|
130
|
+
module's `cli`: `cli.load()` for `--config`, `build_devices(args, config,
|
|
131
|
+
skip)`, and a `--dry-run` of the shipped `config/default.yaml`. Every project
|
|
132
|
+
type's generated tests are now run in plesty-sdk's own suite, against the
|
|
133
|
+
plesty-lib its dev group now requires, the scaffold's own floor
|
|
134
|
+
(`>=0.5.0.dev7`, was `>=0.3.6`) — tested against an older library, generated
|
|
135
|
+
code can only fail to import, which is how this went unnoticed.
|
|
136
|
+
- **`plesty init mock-test` runs on a scaffolded device.** Every device module
|
|
137
|
+
exports `DocDevice = partial(Device, id=...)`, and when no simulator address
|
|
138
|
+
applies — a fresh scaffold has none — the generated test handed that partial
|
|
139
|
+
to `DevicePipeline`, which constructs from a class and names it by
|
|
140
|
+
`__name__`: the test crashed before any gate ran, so gate d1 could not pass.
|
|
141
|
+
The file now passes `Device` and forwards the partial's own arguments
|
|
142
|
+
(`DevicePipeline(Device, *DocDevice.args, **DocDevice.keywords)`), the same
|
|
143
|
+
construction read at run time. A `DocDevice` that is neither a class nor a
|
|
144
|
+
partial of `Device` is refused with that reason. The probe also rejects a
|
|
145
|
+
`check_errors()` that returns anything but a list, as gate 7 does, and the
|
|
146
|
+
device template's stub returns `[]` under the `list[str]` contract
|
|
147
|
+
plesty-lib declares instead of `None`.
|
|
148
|
+
- The scaffolded analyzer template carries its REUSE header. Every other
|
|
149
|
+
template declares copyright and licence inline; this one declared nothing, so
|
|
150
|
+
the file linted as uncovered and its author was credited nowhere — and every
|
|
151
|
+
project scaffolded from it inherited that gap.
|
|
6
152
|
|
|
7
153
|
## [0.4.0] — 2026-09-07
|
|
8
154
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: plesty-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0.dev1
|
|
4
4
|
Summary: Command-line application for developing Python modules compliant with the Plesty standard.
|
|
5
5
|
Author: Plesty Development Team, Yunshuang Yuan, Christopher Borchers, fvrehlinger, Maximilian Heller, Michael Zopf
|
|
6
6
|
License-Expression: LGPL-3.0-or-later
|
|
@@ -37,3 +37,11 @@ path = [
|
|
|
37
37
|
SPDX-FileCopyrightText = "2025-2026 Plesty Development Team"
|
|
38
38
|
SPDX-FileContributor = "Yunshuang Yuan"
|
|
39
39
|
SPDX-License-Identifier = "LGPL-3.0-or-later"
|
|
40
|
+
|
|
41
|
+
# versioningit imports `packaging/versioning.py` at build time, so Python
|
|
42
|
+
# writes a `.pyc` beside it that `reuse lint` sees even though `.gitignore`
|
|
43
|
+
# hides it from git.
|
|
44
|
+
[[annotations]]
|
|
45
|
+
path = ["packaging/**"]
|
|
46
|
+
SPDX-FileCopyrightText = "2026 Plesty Development Team"
|
|
47
|
+
SPDX-License-Identifier = "LGPL-3.0-or-later"
|
|
@@ -17,9 +17,9 @@ into five areas:
|
|
|
17
17
|
```{mermaid}
|
|
18
18
|
graph TD
|
|
19
19
|
CLI["CLI layer<br/>cli.py · context.py"]
|
|
20
|
-
CHECK["Check engine<br/>commands/check.py · authorship.py"]
|
|
20
|
+
CHECK["Check engine<br/>commands/check.py · authorship.py · semver.py · report.py"]
|
|
21
21
|
DOCS["Docs builder<br/>commands/docs/*"]
|
|
22
|
-
SCAFFOLD["Scaffolding<br/>commands/init.py ·
|
|
22
|
+
SCAFFOLD["Scaffolding<br/>commands/init.py · update.py · field_test.py · mock_test.py"]
|
|
23
23
|
LICENSE["Licensing<br/>commands/license.py"]
|
|
24
24
|
MANUAL["Manuals<br/>commands/manual.py"]
|
|
25
25
|
ASSETS["Packaged assets<br/>assets/*"]
|
|
@@ -39,9 +39,9 @@ graph TD
|
|
|
39
39
|
| Area | Modules | Responsibility |
|
|
40
40
|
|---|---|---|
|
|
41
41
|
| CLI layer | `cli.py`, `context.py` | Click command group; resolves `--project-dir` into an `ApplicationContext` that lazily parses `pyproject.toml` and derives `DocumentationSettings`. Every command receives this context — no command parses `pyproject.toml` itself. |
|
|
42
|
-
| Check engine | `commands/check.py`, `authorship.py` | The compliance gates behind `plesty check`. Each gate is a plain function raising `click.ClickException` (or exiting with the failing tool's code) on violation. `authorship.py` holds the git-history authorship analysis shared with `plesty license author
|
|
43
|
-
| Docs builder | `commands/docs/` (`serve.py`, `deploy.py`, `sphinx_builder.py`, `generate.py`) | Sphinx configuration and build (`sphinx_builder.py`), live-reload preview (`serve`), pages-branch deployment with versioned releases (`deploy`),
|
|
44
|
-
| Scaffolding | `commands/init.py`, `commands/update.py` | Project generation from the copier template (`plesty init`) and in-place maintenance of existing projects (`plesty update`). `update` reuses `init`'s CI-generation and hook-installation helpers so both commands emit identical artifacts. |
|
|
42
|
+
| Check engine | `commands/check.py`, `authorship.py`, `semver.py`, `report.py` | The compliance gates behind `plesty check`. Each gate is a plain function raising `click.ClickException` (or exiting with the failing tool's code) on violation. `authorship.py` holds the git-history authorship analysis shared with `plesty license author`; `semver.py` the public-API diff against the published release for gate 8; `report.py` the `reports/check.json` document every run writes. |
|
|
43
|
+
| Docs builder | `commands/docs/` (`serve.py`, `deploy.py`, `sphinx_builder.py`, `generate.py`, `picker.py`) | Sphinx configuration and build (`sphinx_builder.py`), live-reload preview (`serve`), pages-branch deployment with versioned releases (`deploy`), zero-effort device reference-page generation from a live `doc_model()` (`generate.py`), and stamping the version picker into release trees built before it existed (`picker.py`). `cache.py` maintains the git-ignored `.plesty/` build cache used by `serve`. |
|
|
44
|
+
| Scaffolding | `commands/init.py`, `commands/update.py`, `commands/field_test.py`, `commands/mock_test.py`, `tui.py` | Project generation from the copier template (`plesty init`) and in-place maintenance of existing projects (`plesty update`). `update` reuses `init`'s CI-generation and hook-installation helpers so both commands emit identical artifacts. `field_test.py` and `mock_test.py` generate a device module's field test and mock pipeline test (`plesty init field-test` / `mock-test`); `tui.py` is the dependency-free checkable list the field-test interview uses. |
|
|
45
45
|
| Licensing and manuals | `commands/license.py`, `commands/manual.py` | SPDX header maintenance via the REUSE tool, and Markdown/PDF manual generation for external (non-hub) device packages. |
|
|
46
46
|
| Packaged assets | `plesty/sdk/assets/` | Data shipped inside the wheel: the canonical `ruff.toml`, the copier scaffold under `templates/`, the shared Sphinx theme (`hub-theme/`), and the pages-branch CI file (`docs-build-gitlab-ci.yml`). Assets are always accessed through `importlib.resources`, never by path relative to the source tree. |
|
|
47
47
|
|
|
@@ -92,11 +92,11 @@ engine is re-run by CI (`hub-check` in the `plesty-standard-ci` component) as th
|
|
|
92
92
|
authoritative final gate. Gates carry a tier label:
|
|
93
93
|
|
|
94
94
|
- **`[SDK+CI]`** (gates 1–10) — enforced locally and repeated in CI.
|
|
95
|
-
- **`[SDK]`** (gate 11, docs build) —
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
variable.
|
|
99
|
-
- **`[Device]` / `[Analyzer]` / `[Experiment]`** (d1–d3, a1, e1–
|
|
95
|
+
- **`[SDK]`** (gate 11, docs build) — runs locally and in merge-request pipelines. In a
|
|
96
|
+
branch pipeline (`CI=true` without `CI_PIPELINE_SOURCE=merge_request_event`) gate 11
|
|
97
|
+
reports itself skipped, because the dedicated `hub-deploy-docs` CI job builds the docs
|
|
98
|
+
instead. Tests exercising the Sphinx path must therefore clear the `CI` variable.
|
|
99
|
+
- **`[Device]` / `[Analyzer]` / `[Experiment]`** (d1–d3, a1, e1–e3) — module-type gates,
|
|
100
100
|
active only when `[tool.plesty] module_type` is `"device"`, `"analyzer"`, or
|
|
101
101
|
`"experiment"` respectively; every other module type gets an explicit "N/A" line, so
|
|
102
102
|
the gate list is identical everywhere and activation is declarative, never heuristic.
|
|
@@ -104,7 +104,9 @@ authoritative final gate. Gates carry a tier label:
|
|
|
104
104
|
return-annotation contract, d3 that the device renders a populated `doc_model()`;
|
|
105
105
|
a1 verifies the five `AnalyzerPipeline` contract tests; e1 verifies the five
|
|
106
106
|
`ExperimentPipeline` contract tests, e2 that persistence goes through the unified
|
|
107
|
-
data layer
|
|
107
|
+
data layer, e3 that `python -m <module> --manifest` publishes the run contract and
|
|
108
|
+
that its configuration schema and the module's own `config/*.yaml` say the same
|
|
109
|
+
thing.
|
|
108
110
|
|
|
109
111
|
The standard selects how deep the run goes: `pixel` runs gates 1–2, `nebula` gates 1–6
|
|
110
112
|
(static, no network), `quantum` everything including the module-type gates. The full
|
|
@@ -161,14 +163,24 @@ tradeoff is losing pydata-specific features (notably its version switcher UI); v
|
|
|
161
163
|
now surfaced through Sphinx's plain `version`/`release` fields and the deploy-side
|
|
162
164
|
`versions.json`.
|
|
163
165
|
|
|
164
|
-
**Schema-usage enforcement inside the data-layer gate.**
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
no
|
|
170
|
-
|
|
171
|
-
|
|
166
|
+
**Schema-usage enforcement inside the data-layer gate.** plesty-lib defines the data every
|
|
167
|
+
module exchanges — a device's configuration and operations, its status and telemetry, an
|
|
168
|
+
experiment's plan and journal, a stored result — as a fixed set of classes (the *schema
|
|
169
|
+
models*). A module that wrote its own class of the same name — its own `DeviceStatus`, say —
|
|
170
|
+
would *shadow* the library's: code in that module would silently use the local copy, which
|
|
171
|
+
no other module, console or reader understands. Gate 4 therefore scans every Python file
|
|
172
|
+
under `plesty/<module>/` of **every** module type — device, analyzer, experiment and core
|
|
173
|
+
alike — and fails on a class definition whose name is one of plesty-lib's schema models
|
|
174
|
+
(`ConfigParameter`, `FuncMeta`, `DeviceStatus`, `TelemetryEvent`, `ResultDocument`, `Plan`,
|
|
175
|
+
`Journal`, … — the full list is `_PROTECTED_SCHEMA_NAMES` in `commands/check.py`), and on a
|
|
176
|
+
public function without a return type annotation. Two further checks apply to one module
|
|
177
|
+
type each: gate d2 (devices) requires `status()` to be annotated `DeviceStatus`, and gate e2
|
|
178
|
+
(experiments) requires results to be stored through `save_result` rather than written by
|
|
179
|
+
hand. The alternative — trusting convention and review — had already produced silent forks
|
|
180
|
+
of the data contract. Reading the source as a syntax tree, without importing it, is cheap,
|
|
181
|
+
runs offline in the pre-push hook, and cannot be fooled by a module that fails to import;
|
|
182
|
+
the tradeoff is that such a check sees only what is written literally (a file mode computed
|
|
183
|
+
at run time is deliberately left alone), so the gates are a floor, not a proof.
|
|
172
184
|
|
|
173
185
|
**Generated device documentation (gate d3) over hand-written reference pages.**
|
|
174
186
|
Hand-written parameter and operation tables drift the moment a schema changes. Rendering
|
|
@@ -187,20 +199,43 @@ have already diverged. The cost is a coupling to the component's ref and input c
|
|
|
187
199
|
a rename or ref change in plesty-ci breaks scaffolds (see technical debt below) — which we
|
|
188
200
|
accept because centralised evolution has proven far cheaper than fleet-wide file surgery.
|
|
189
201
|
|
|
190
|
-
**A generated device carries its own control panel, with Qt in an extra.**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
**A generated device carries its own control panel, with Qt in an extra.** The panel is
|
|
203
|
+
plesty-lib's `DevicePanel`, and it reaches a device only through a four-call interface,
|
|
204
|
+
`DeviceHandle` — `describe()`, `query()`, `write()`, `call()`. Where the device is decides
|
|
205
|
+
only which handle the panel is given: in the same process, the device object wrapped in a
|
|
206
|
+
`LocalHandle`; over the network, a TCP client (`DeviceTCPIPClient`) satisfies the same
|
|
207
|
+
interface; from a remote `plesty-bench`, the bench agent relays the same four calls. So
|
|
208
|
+
the one panel drives a device locally or remotely alike. What the scaffold generates is the
|
|
209
|
+
local case: `--gui` on the module's existing entry point opens the panel on the machine the
|
|
210
|
+
instrument is plugged into, rather than shipping a separate console or leaving each module
|
|
211
|
+
to hand-write one.
|
|
212
|
+
|
|
213
|
+
`--gui` and serving are alternatives *within one process*: both open the instrument, and
|
|
214
|
+
most instruments grant a single session, so `python -m plesty.<module>` does one or the
|
|
215
|
+
other. Both at once is the remote case — serve the device, and open the panel from a client
|
|
216
|
+
on the same or another machine.
|
|
217
|
+
|
|
218
|
+
The controls are built from `describe()`, the device's schema serialized as plain data, so
|
|
219
|
+
a module gets a usable window the moment its schema is right, and a hole in that payload
|
|
220
|
+
surfaces at the bench instead of only across a network. Operations are filtered by their
|
|
221
|
+
declared `kind`, which makes the schema the single place that decides what a panel offers,
|
|
222
|
+
local or remote.
|
|
223
|
+
|
|
224
|
+
A module with a GUI of its own is not overridden by anything: `--gui` is ordinary generated
|
|
225
|
+
code in the module's `__main__.py` (`open_panel()`), and the module replaces it — with its
|
|
226
|
+
own `Panel` subclass, several panels in one window, or no panel — by editing that function.
|
|
227
|
+
Nothing loads a module's panel code from elsewhere.
|
|
228
|
+
|
|
229
|
+
Qt lives in a generated `gui` extra rather than in the generated `dependencies` — a headless
|
|
230
|
+
bench serves the device and never opens a window — which is why `plesty.lib.ui` is imported
|
|
231
|
+
inside the panel path and not at module scope. How far Qt reaches is deliberately bounded:
|
|
232
|
+
the panel contract (`Panel`), the device handle, the worker thread that keeps device calls
|
|
233
|
+
off the window's thread, and the `describe()` payload import no toolkit; Qt is confined to
|
|
234
|
+
`plesty.lib.ui.qt` and to the widget each panel builds. Moving to another toolkit, or
|
|
235
|
+
offering a second kind of interface such as a web page, would therefore mean new widget
|
|
236
|
+
code and a new shell, while the data a panel renders and the way it reaches a device stay
|
|
237
|
+
as they are. The tradeoff is that this widget code is Qt today, and a second toolkit would
|
|
238
|
+
be a second implementation of it rather than a switch.
|
|
204
239
|
|
|
205
240
|
**`plesty update --install-hook` for cloned projects.** Git hooks live in `.git/` and are
|
|
206
241
|
never cloned, so `plesty init`'s pre-push hook silently vanishes for every contributor
|
|
@@ -231,6 +266,8 @@ The sanctioned runtime dependencies (from `[project] dependencies` in `pyproject
|
|
|
231
266
|
| `sphinxcontrib-mermaid` | Mermaid diagrams in docs (including this page). |
|
|
232
267
|
| `livereload` / `watchfiles` | Local preview server and rebuild-on-change for `plesty docs serve`. |
|
|
233
268
|
| `md2pdf` | PDF rendering for `plesty manual generate --with-pdf`. |
|
|
269
|
+
| `griffe` | Static public-API extraction for the gate 8 diff — the analyzed package is never imported. |
|
|
270
|
+
| `packaging` | Version and specifier parsing (gate 8 baselines, `--lib-version`, versioned docs deploy). |
|
|
234
271
|
| `pyside6-essentials` (extra: `gui`) | Optional GUI support; not installed by default. |
|
|
235
272
|
|
|
236
273
|
**Policy:** a new third-party library may only be added if it is actively maintained
|
|
@@ -246,11 +283,4 @@ as a GitLab issue labeled
|
|
|
246
283
|
[`type::debt`](https://gitlab.com/plesty/core/plesty-sdk/-/issues/?label_name%5B%5D=type%3A%3Adebt)
|
|
247
284
|
— per the
|
|
248
285
|
[governance DoD](https://gitlab.com/plesty/governance/-/blob/main/CONTRIBUTING.md),
|
|
249
|
-
permanent architectural debt is filed before the shortcut lands.
|
|
250
|
-
matter when reading the gate architecture above: gate 11 (docs build) never runs in
|
|
251
|
-
merge-request pipelines — the zero-warning build is enforced by the pre-push hook and,
|
|
252
|
-
post-merge, by `hub-deploy-docs`
|
|
253
|
-
([sdk#22](https://gitlab.com/plesty/core/plesty-sdk/-/issues/22)) — and the authoritative
|
|
254
|
-
CI-side semantic-versioning API diff that gate 8 defers to does not exist yet, so version
|
|
255
|
-
enforcement is advisory
|
|
256
|
-
([plesty-ci#10](https://gitlab.com/plesty/core/plesty-ci/-/issues/10)).
|
|
286
|
+
permanent architectural debt is filed before the shortcut lands.
|
|
@@ -39,8 +39,9 @@ Gates are divided into two tiers depending on where they are enforced:
|
|
|
39
39
|
|
|
40
40
|
- **`[SDK+CI]`** — enforced locally by `plesty check` and repeated by CI in a clean
|
|
41
41
|
environment as the authoritative final gate (gates 1–10).
|
|
42
|
-
- **`[SDK]`** — enforced locally
|
|
43
|
-
|
|
42
|
+
- **`[SDK]`** — enforced locally and in merge-request pipelines; skipped in branch
|
|
43
|
+
pipelines, where the dedicated `hub-deploy-docs` job builds the docs instead. Currently
|
|
44
|
+
just the Docs Build gate (11).
|
|
44
45
|
|
|
45
46
|
The pre-push git hook installed by `plesty init` runs `plesty check` before every push,
|
|
46
47
|
enforcing whichever standard resolves for the project (see Standard resolution above).
|
|
@@ -75,10 +76,10 @@ release. Required for every PyPI release, and the derived default from version `
|
|
|
75
76
|
| Gate | Tier | What is checked |
|
|
76
77
|
|---|---|---|
|
|
77
78
|
| Automated Test Coverage | `[SDK+CI]` | `pytest --cov` with a minimum threshold of **80%** |
|
|
78
|
-
| Semantic Versioning | `[SDK+CI]` |
|
|
79
|
+
| Semantic Versioning | `[SDK+CI]` | Diffs the public API against the newest PyPI release on the tree's own `major.minor` line (so a `maintain/0.N` branch is compared with `0.N`, not with a later line) and requires a version bump that matches: a minor bump for a breaking change before `1.0.0`, a major bump from then on. Advisory locally, fails in CI. When the package is unpublished or PyPI is unreachable, falls back to a reminder to tag a release when commits exist since the last tag |
|
|
79
80
|
| Licensing Compliance | `[SDK+CI]` | [REUSE](https://reuse.software/) compliance (`reuse lint`) and authorship currency of the SPDX headers; `license` field declared in `pyproject.toml` |
|
|
80
81
|
| Vulnerability Audit | `[SDK+CI]` | No known CVEs in declared dependencies; queries the OSV database via `pip-audit` |
|
|
81
|
-
| Docs Build | `[SDK]` | Full Sphinx build must complete with zero errors and zero warnings.
|
|
82
|
+
| Docs Build | `[SDK]` | Full Sphinx build must complete with zero errors and zero warnings. Runs locally and in merge-request pipelines, so a docs-breaking change fails before it merges; skipped in branch pipelines, where the dedicated `hub-deploy-docs` job builds the docs |
|
|
82
83
|
|
|
83
84
|
### Module-type gates
|
|
84
85
|
|
|
@@ -93,6 +94,7 @@ they report N/A for every other module type.
|
|
|
93
94
|
| a1 — Analyzer Contract | `module_type = "analyzer"` | The five `AnalyzerPipeline` contract gate tests (`plesty.lib.test.analyzer_pipeline`) are present in `tests/` and pass on schema-generated synthetic inputs: public `Analyzer` subclass, schema integrity, analyze-signature match, mock round-trip, provenance stamp |
|
|
94
95
|
| e1 — Experiment Contract | `module_type = "experiment"` | The five `ExperimentPipeline` contract gate tests (`plesty.lib.test.experiment_pipeline`) are present in `tests/` and pass: public `Experiment` subclass, deterministic `build_plan()`, resolvable step ops, JSON-serializable plan, async lifecycle hooks |
|
|
95
96
|
| e2 — Experiment Persistence | `module_type = "experiment"` | No ad-hoc persistence in the module package (`np.save`/`np.savez`, `pickle.dump`, `h5py.File`/`open` with write mode) — results are persisted via `plesty.lib.data.save_result`/`ResultDocument` |
|
|
97
|
+
| e3 — Experiment Manifest | `module_type = "experiment"` | `python -m <module> --manifest` prints the run contract (`plesty.lib.experiment.Manifest`): it names this module, every configuration parameter carries a `dtype` and a `description` (and a `unit` where it is bounded), and the schema and the module's own `config/*.yaml` declare the same keys — a key only one of them knows about is either uneditable or a setting that does nothing |
|
|
96
98
|
| f1 — Field Test Findings | any module with a published field test report | No `reports/<instrument>/field-test.json` holds an `error` finding — a parameter the instrument refuses or will not answer, which the module nonetheless declares |
|
|
97
99
|
|
|
98
100
|
## Report artifacts
|
|
@@ -46,7 +46,7 @@ whenever a `.md` or `.rst` file changes. Useful during active documentation writ
|
|
|
46
46
|
|
|
47
47
|
| Option | Default | Description |
|
|
48
48
|
|---|---|---|
|
|
49
|
-
| `--dev-addr` | `
|
|
49
|
+
| `--dev-addr` | `localhost:8000` | Host and port for the preview server |
|
|
50
50
|
|
|
51
51
|
### Example
|
|
52
52
|
|
|
@@ -84,19 +84,19 @@ yet exist.
|
|
|
84
84
|
```bash
|
|
85
85
|
# Deploy development snapshot (latest)
|
|
86
86
|
plesty docs deploy \
|
|
87
|
-
https://
|
|
87
|
+
https://oauth2:${CI_BOT_TOKEN}@gitlab.com/plesty/my-device.git \
|
|
88
88
|
docs-build \
|
|
89
89
|
--latest
|
|
90
90
|
|
|
91
91
|
# Deploy a versioned release
|
|
92
92
|
plesty docs deploy \
|
|
93
|
-
https://
|
|
93
|
+
https://oauth2:${CI_BOT_TOKEN}@gitlab.com/plesty/my-device.git \
|
|
94
94
|
docs-build \
|
|
95
95
|
--release
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
In practice this command is called by the `deploy-docs`
|
|
99
|
-
be run manually.
|
|
98
|
+
In practice this command is called by the `hub-deploy-docs` job of the `plesty-standard-ci`
|
|
99
|
+
component and does not need to be run manually.
|
|
100
100
|
|
|
101
101
|
---
|
|
102
102
|
|