plesty-sdk 0.3.5.dev1__tar.gz → 0.3.6__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.3.5.dev1 → plesty_sdk-0.3.6}/CHANGELOG.md +102 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/PKG-INFO +1 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/check.md +1 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/gl-secret-detection-report.json +7 -7
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/check/guidance.yaml +3 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/docs-build-gitlab-ci.yml +6 -2
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/hub-theme/plesty-hub.css +2 -0
- plesty_sdk-0.3.6/plesty/sdk/assets/hub-theme/plesty-versions.css +49 -0
- plesty_sdk-0.3.6/plesty/sdk/assets/hub-theme/plesty-versions.js +110 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/{% if project_type in ['device', 'experiment'] %}__main__.py{% endif %}.jinja +11 -5
- plesty_sdk-0.3.6/plesty/sdk/commands/docs/deploy.py +288 -0
- plesty_sdk-0.3.6/plesty/sdk/commands/docs/picker.py +141 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/docs/sphinx_builder.py +19 -3
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/field_test.py +5 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/init.py +2 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/pyproject.toml +11 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_docs_deploy.py +135 -32
- plesty_sdk-0.3.6/tests/test_docs_picker.py +148 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_field_test_scaffold.py +87 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_init.py +21 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_sphinx_builder.py +1 -1
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/uv.lock +189 -13
- plesty_sdk-0.3.5.dev1/plesty/sdk/commands/docs/deploy.py +0 -198
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/.coverage +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/.gitignore +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/.gitlab-ci.yml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/.mailmap +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/LICENSE +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/README.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/REUSE.toml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/architecture.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/docs.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/init.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/license.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/manual.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/commands/update.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/getting-started.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/index.md +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/docs/toc.yaml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/__init__.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/hub-theme/plesty-logo.svg +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/hub-theme/plesty-mark.svg +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/client-field-test.py.template +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/field-test-env.example +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/field-test-questions.yaml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/field-test.py.template +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/mock-test.py.template +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/init/next-steps.yaml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/manual/pdf-common.css +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/manual/pdf-page-landscape.css +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/manual/pdf-page-portrait.css +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/ruff.toml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/copier.yml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/extras/analyzer/analyzer.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/extras/device/base_device.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/extras/device/device.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/extras/experiment/experiment.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/.gitignore +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/CHANGELOG.md.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/LICENSE +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/README.md.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/REUSE.toml.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/docs/index.md.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/docs/toc.yaml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/__init__.py.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/plesty/{{module_name}}/config.yaml.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/pyproject.toml.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/tests/__init__.py.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/tests/test_{{module_name}}.py.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/{% if project_type == 'experiment' %}config{% endif %}/default.yaml +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/assets/templates/template/{% if project_type in ['device', 'experiment'] %}.env.example{% endif %}.jinja +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/authorship.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/cache.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/cli.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/__init__.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/check.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/docs/__init__.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/docs/generate.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/docs/serve.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/license.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/manual.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/mock_test.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/commands/update.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/context.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/report.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/semver.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/plesty/sdk/tui.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/__init__.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_authorship.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_cache.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_check.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_cli.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_context.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_docs_generate.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_docs_serve.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_license.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_manual.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_mock_test_scaffold.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_report.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_semver.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_tui.py +0 -0
- {plesty_sdk-0.3.5.dev1 → plesty_sdk-0.3.6}/tests/test_update.py +0 -0
|
@@ -2,6 +2,108 @@
|
|
|
2
2
|
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com).
|
|
4
4
|
|
|
5
|
+
## [0.3.6] — 2026-09-03
|
|
6
|
+
|
|
7
|
+
Everything the scaffolds generate now passes the gates the scaffolds ask for.
|
|
8
|
+
Two generated files failed a check the SDK itself enforces — a field-test
|
|
9
|
+
client with an import nothing used, and entry points on an event loop that
|
|
10
|
+
Python 3.16 will not give them — and the version picker no longer strands a
|
|
11
|
+
reader on a release it cannot leave. Generated projects pin `plesty-lib>=0.3.6`.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Generated device and experiment entry points start through
|
|
15
|
+
`plesty.lib.service.run_server` instead of a bare `asyncio.run`. The bare
|
|
16
|
+
call worked on Windows only because importing `plesty.lib.service` installed
|
|
17
|
+
a global event-loop policy — deprecated in Python 3.14 (two warnings per
|
|
18
|
+
server start on benches already there) and removed in 3.16, where the entry
|
|
19
|
+
point would get a `ProactorEventLoop` and fail inside pyzmq for want of
|
|
20
|
+
`add_reader`. The `plesty-lib` pin floor moves to 0.3.6, the first release
|
|
21
|
+
carrying `run_server`. Existing modules keep working on 3.14 and 3.15 and
|
|
22
|
+
pick the swap up when they regenerate.
|
|
23
|
+
- `plesty init field-test` no longer writes a client whose imports fail the
|
|
24
|
+
module's own lint gate. A module reached through its `DocDevice` — or through
|
|
25
|
+
any construction taking no arguments — gets a bare factory, and the generated
|
|
26
|
+
`tests/field_test_client.py` imported `functools.partial` anyway: F401, so
|
|
27
|
+
`plesty check` could not pass on a module that had just been field-tested.
|
|
28
|
+
The import is now emitted only in the branch that calls `partial`. Both
|
|
29
|
+
branches are linted in the tests; neither was before, because every fixture
|
|
30
|
+
probed into the "no hardware-free construction" path.
|
|
31
|
+
Generating against released 0.3.3 has a worse form of the same block — it
|
|
32
|
+
emits the `partial` import but not the device import, leaving `SPAWN_FACTORY`
|
|
33
|
+
an undefined name (F821). Add the `from plesty.<module> import <factory>`
|
|
34
|
+
line by hand, or regenerate once this ships.
|
|
35
|
+
- The version picker no longer offers a version the reader cannot switch back
|
|
36
|
+
out of. A release built before the Read-the-Docs theme has no sidebar for the
|
|
37
|
+
picker to mount on and cannot be stamped, yet the manifest still listed it —
|
|
38
|
+
on the SDK's own docs, selecting 0.1 stranded the reader. The manifest now
|
|
39
|
+
advertises only releases that carry the picker; such a release stays
|
|
40
|
+
published and reachable at its own URL, and `/releases/` still redirects to
|
|
41
|
+
the newest one that exists. Stamping consequently runs before the manifest is
|
|
42
|
+
written, so the manifest sees the final state of every tree.
|
|
43
|
+
- A module with no releases rendered a dropdown holding a single entry. The
|
|
44
|
+
picker now appears only when there is something to pick between.
|
|
45
|
+
|
|
46
|
+
## [0.3.5] — 2026-08-24
|
|
47
|
+
|
|
48
|
+
Documentation gains a version picker, and the two things standing between it
|
|
49
|
+
and the published sites are fixed: the docs-deploy gate had been skipped since
|
|
50
|
+
2026-08-21 behind a failing test collection, and releases built before the
|
|
51
|
+
picker existed had no way back to the current docs.
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
- Every module's documentation carries a **version picker** in the sidebar.
|
|
55
|
+
Each module already deployed `latest/` from its default branch and
|
|
56
|
+
`releases/<major>.<minor>/` from each tag, but nothing linked them: a reader
|
|
57
|
+
on the release docs could not reach any other version. The picker is fed by
|
|
58
|
+
`versions.json`, fetched at page load rather than baked in — a page built
|
|
59
|
+
months ago cannot know which versions exist today. Switching versions keeps
|
|
60
|
+
the current page when the target has it, and falls back to that version's
|
|
61
|
+
index when it does not (pages come and go between releases). A deployment
|
|
62
|
+
without a manifest — a local `plesty docs serve` preview — renders no picker
|
|
63
|
+
at all.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
- The version picker is no longer a one-way trip. Releases published before it
|
|
67
|
+
existed are never rebuilt, so switching to one landed the reader on pages
|
|
68
|
+
with no picker and no way back. Each deploy now stamps the picker's two
|
|
69
|
+
assets and the tags referencing them into any release tree that lacks them.
|
|
70
|
+
Only the `<head>` gains anything — the prose, the API reference and the
|
|
71
|
+
stylesheets a historical release was built with are untouched, which is why
|
|
72
|
+
the picker's styling moved out of `plesty-hub.css` into its own
|
|
73
|
+
`plesty-versions.css`. Idempotent, so re-running over a stamped tree does
|
|
74
|
+
nothing. A release predating the Read-the-Docs theme (plesty-sdk 0.1) has no
|
|
75
|
+
sidebar to mount on and is skipped.
|
|
76
|
+
- The test suite no longer fails to collect in CI. `plesty-lib` is declared in
|
|
77
|
+
a `dev` dependency group: `tests/test_mock_test_scaffold.py` drives the
|
|
78
|
+
mock-test scaffold against a real `plesty.lib.sim.demo_device.DemoDevice`,
|
|
79
|
+
which it subclasses and runs, but nothing installed the library on a runner —
|
|
80
|
+
so `hub-check` had been failing with `ModuleNotFoundError: No module named
|
|
81
|
+
'plesty.lib'`, which in turn skipped `hub-deploy-docs` and froze the
|
|
82
|
+
published documentation. It is a group rather than a runtime dependency:
|
|
83
|
+
installing plesty-sdk must not pull the library it scaffolds modules for.
|
|
84
|
+
- `versions.json` entries were origin-absolute (`"/0.3/"`), so they resolved
|
|
85
|
+
against the host rather than the module root, and the `releases/` redirect
|
|
86
|
+
stub built from them has been broken since it was written — on
|
|
87
|
+
docs.plesty.net it pointed at `docs.plesty.net/0.3/`. The manifest moves to
|
|
88
|
+
the module root, lists `latest` alongside the releases, and its URLs are
|
|
89
|
+
relative to that root, which is `/<slug>/` on docs.plesty.net and
|
|
90
|
+
`/<group>/<project>/` on GitLab Pages.
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
- Both deploy modes rewrite the manifest, not only `--release`. This is what
|
|
94
|
+
gives a module that has never been tagged a picker, and what migrates
|
|
95
|
+
branches deployed by an older SDK — including their `.gitlab-ci.yml`, which
|
|
96
|
+
was previously written once at branch creation and never updated again.
|
|
97
|
+
- The Pages job publishes the whole `html/` tree instead of `html/latest`, so
|
|
98
|
+
the releases the picker lists are reachable there too, and `html/index.html`
|
|
99
|
+
redirects the Pages root to `latest/`. The layout now matches what
|
|
100
|
+
docs.plesty.net already serves, so one picker runs unchanged on both.
|
|
101
|
+
**Deep links to `plesty.gitlab.io/<group>/<project>/<page>.html` move under
|
|
102
|
+
`/latest/`**; docs.plesty.net URLs are unaffected. The reference link
|
|
103
|
+
`plesty check` prints on a failing gate followed that move, so it now points
|
|
104
|
+
at docs.plesty.net — the site readers are sent to, and the one whose path is
|
|
105
|
+
independent of how Pages lays the tree out.
|
|
106
|
+
|
|
5
107
|
## [0.3.5.dev1] — 2026-08-21
|
|
6
108
|
|
|
7
109
|
Development pre-release: the tutorial needs the pin option before 0.3.5 is
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: plesty-sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
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
|
|
@@ -146,7 +146,7 @@ failures and their guidance always print:
|
|
|
146
146
|
Error: [Coverage] total coverage 62% below threshold
|
|
147
147
|
This gate verifies: the pytest suite passes with at least 80% line coverage.
|
|
148
148
|
How to fix: Reproduce with 'uv run pytest --cov=plesty' and add tests ...
|
|
149
|
-
Reference: https://plesty.
|
|
149
|
+
Reference: https://docs.plesty.net/plesty-sdk/latest/commands/check.html
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
## Examples
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"vendor": {
|
|
8
8
|
"name": "GitLab"
|
|
9
9
|
},
|
|
10
|
-
"version": "7.
|
|
10
|
+
"version": "7.39.0"
|
|
11
11
|
},
|
|
12
12
|
"scanner": {
|
|
13
13
|
"id": "gitleaks",
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"version": "8.30.1"
|
|
20
20
|
},
|
|
21
21
|
"type": "secret_detection",
|
|
22
|
-
"start_time": "2026-
|
|
23
|
-
"end_time": "2026-
|
|
22
|
+
"start_time": "2026-09-03T08:02:36",
|
|
23
|
+
"end_time": "2026-09-03T08:02:36",
|
|
24
24
|
"status": "success",
|
|
25
25
|
"observability": {
|
|
26
26
|
"events": [
|
|
27
27
|
{
|
|
28
28
|
"event": "collect_secrets_analyzer_scan_metrics_from_pipeline",
|
|
29
|
-
"time_s": 0.
|
|
29
|
+
"time_s": 0.448937143,
|
|
30
30
|
"exit_code": 0,
|
|
31
31
|
"git_strategy": "FetchShallow",
|
|
32
|
-
"repo_size_kb":
|
|
32
|
+
"repo_size_kb": 503,
|
|
33
33
|
"commit_count": 1,
|
|
34
|
-
"bytes_scanned":
|
|
34
|
+
"bytes_scanned": 415,
|
|
35
35
|
"pipeline_type": "Tag"
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"passthrough_types": null,
|
|
41
41
|
"passthrough_count": 0,
|
|
42
42
|
"passthrough_auth_used": false,
|
|
43
|
-
"rules_version": "0.25.
|
|
43
|
+
"rules_version": "0.25.1"
|
|
44
44
|
}
|
|
45
45
|
]
|
|
46
46
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Per-gate failure guidance echoed by `plesty check` (issue sdk#26).
|
|
2
2
|
# Keys match the gate keys used in check_command; text is plain CLI prose.
|
|
3
|
-
|
|
3
|
+
# docs.plesty.net, not the Pages mirror: it is the site readers are sent to,
|
|
4
|
+
# and its /<slug>/latest/ path is unaffected by how Pages lays the tree out.
|
|
5
|
+
docs_url: https://docs.plesty.net/plesty-sdk/latest/commands/check.html
|
|
4
6
|
|
|
5
7
|
gates:
|
|
6
8
|
metadata:
|
|
@@ -4,7 +4,7 @@ pages:
|
|
|
4
4
|
stage: deploy
|
|
5
5
|
rules:
|
|
6
6
|
# The gate for creating the job, not a selector of what is published —
|
|
7
|
-
# `publish: html
|
|
7
|
+
# `publish: html` below uploads the whole directory. exists
|
|
8
8
|
# matches FILE globs: the bare directory path "html/latest/" stopped
|
|
9
9
|
# matching on gitlab.com between 2026-07-21 and 2026-08-10, every
|
|
10
10
|
# docs-build pipeline failed with "no jobs", and Pages froze while the
|
|
@@ -14,4 +14,8 @@ pages:
|
|
|
14
14
|
script:
|
|
15
15
|
- echo "Serving documentation on GitLab pages..."
|
|
16
16
|
pages:
|
|
17
|
-
|
|
17
|
+
# The whole tree, not just html/latest: the sidebar version picker needs
|
|
18
|
+
# versions.json and the releases/ it lists to be reachable from the same
|
|
19
|
+
# site. html/index.html forwards the Pages root to latest/, and the layout
|
|
20
|
+
# then matches docs.plesty.net, where the same picker runs unchanged.
|
|
21
|
+
publish: html
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Plesty Development Team
|
|
3
|
+
* SPDX-FileContributor: Yunshuang Yuan
|
|
4
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
5
|
+
*
|
|
6
|
+
* Styling for the sidebar version picker (plesty-versions.js).
|
|
7
|
+
*
|
|
8
|
+
* Separate from plesty-hub.css because it is also stamped into release docs
|
|
9
|
+
* built before the picker existed. Those trees carry their own copy of
|
|
10
|
+
* plesty-hub.css, and replacing it would change how a historical page looks
|
|
11
|
+
* beyond adding the dropdown; dropping one more file in beside it does not.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/* Sits at the foot of the sidebar header, under the search box. Added by the
|
|
15
|
+
* script, so a deployment without a versions.json shows no empty slot. */
|
|
16
|
+
.wy-side-nav-search .plesty-versions {
|
|
17
|
+
margin: 0.75rem 0 0;
|
|
18
|
+
text-align: left;
|
|
19
|
+
}
|
|
20
|
+
.wy-side-nav-search .plesty-versions label {
|
|
21
|
+
display: block;
|
|
22
|
+
margin-bottom: 0.3rem;
|
|
23
|
+
color: #d9d9d9;
|
|
24
|
+
font-size: 80%;
|
|
25
|
+
text-transform: uppercase;
|
|
26
|
+
letter-spacing: 0.06em;
|
|
27
|
+
}
|
|
28
|
+
.wy-side-nav-search .plesty-versions select {
|
|
29
|
+
width: 100%;
|
|
30
|
+
padding: 0.3rem 0.5rem;
|
|
31
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
background: rgba(0, 0, 0, 0.2);
|
|
34
|
+
color: #fff;
|
|
35
|
+
font-size: 90%;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
.wy-side-nav-search .plesty-versions select:focus {
|
|
39
|
+
/* Plesty cyan, spelled out: the historical trees this file is stamped into
|
|
40
|
+
carry a plesty-hub.css from before the custom property existed. */
|
|
41
|
+
border-color: #0891b2;
|
|
42
|
+
outline: none;
|
|
43
|
+
}
|
|
44
|
+
/* The dropdown list itself renders in the OS palette, not the sidebar's —
|
|
45
|
+
without this the options are white-on-white on most platforms. */
|
|
46
|
+
.wy-side-nav-search .plesty-versions option {
|
|
47
|
+
color: #404040;
|
|
48
|
+
background: #fff;
|
|
49
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Plesty Development Team
|
|
3
|
+
* SPDX-FileContributor: Yunshuang Yuan
|
|
4
|
+
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
5
|
+
*
|
|
6
|
+
* Version picker for the Read-the-Docs sidebar.
|
|
7
|
+
*
|
|
8
|
+
* Every module is deployed as a tree of independently built docs — `latest/`
|
|
9
|
+
* from the default branch, `releases/<major>.<minor>/` from each tag — under
|
|
10
|
+
* one module root, and `versions.json` at that root lists them. A page built
|
|
11
|
+
* months ago cannot know which versions exist today, so the list is read at
|
|
12
|
+
* page load rather than baked in at build time.
|
|
13
|
+
*
|
|
14
|
+
* The module root is not derivable from the URL: docs.plesty.net serves the
|
|
15
|
+
* tree at /<slug>/ and GitLab Pages at /<group>/<project>/. It is derived
|
|
16
|
+
* from this script's own location instead — the file is always at
|
|
17
|
+
* <docs-root>/_static/plesty-versions.js, and `data-root-prefix` (set by
|
|
18
|
+
* sphinx_builder) is the hop from the docs root up to the module root.
|
|
19
|
+
*/
|
|
20
|
+
(() => {
|
|
21
|
+
// Read synchronously: document.currentScript is null once the DOM is ready.
|
|
22
|
+
const script = document.currentScript;
|
|
23
|
+
if (!script) return;
|
|
24
|
+
const rootPrefix = script.dataset.rootPrefix;
|
|
25
|
+
const current = script.dataset.version || "latest";
|
|
26
|
+
if (!rootPrefix) return;
|
|
27
|
+
|
|
28
|
+
const docsRoot = new URL("../", script.src);
|
|
29
|
+
const moduleRoot = new URL(rootPrefix, docsRoot);
|
|
30
|
+
// Page path within this version's docs, carried across when the target
|
|
31
|
+
// version has the same page.
|
|
32
|
+
const pagePath = decodeURIComponent(location.href.slice(docsRoot.href.length));
|
|
33
|
+
|
|
34
|
+
const label = (version) =>
|
|
35
|
+
version === "latest" ? "latest (development)" : version;
|
|
36
|
+
|
|
37
|
+
/* Navigate to `path` under `target`, falling back to the target's index
|
|
38
|
+
when the page does not exist there — pages come and go between versions,
|
|
39
|
+
and a picker that lands on a 404 is worse than one that lands on a
|
|
40
|
+
landing page. A HEAD request that cannot run at all (file:// origin)
|
|
41
|
+
falls back the same way. */
|
|
42
|
+
const goTo = async (target, path) => {
|
|
43
|
+
const home = new URL(target, moduleRoot);
|
|
44
|
+
if (!path) {
|
|
45
|
+
location.assign(home);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const exact = new URL(path, home);
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(exact, { method: "HEAD" });
|
|
51
|
+
location.assign(response.ok ? exact : home);
|
|
52
|
+
} catch {
|
|
53
|
+
location.assign(home);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const render = (versions) => {
|
|
58
|
+
const container = document.querySelector(".wy-side-nav-search");
|
|
59
|
+
if (!container) return;
|
|
60
|
+
|
|
61
|
+
const picker = document.createElement("div");
|
|
62
|
+
picker.className = "plesty-versions";
|
|
63
|
+
|
|
64
|
+
const caption = document.createElement("label");
|
|
65
|
+
caption.textContent = "Version";
|
|
66
|
+
caption.htmlFor = "plesty-version-select";
|
|
67
|
+
picker.appendChild(caption);
|
|
68
|
+
|
|
69
|
+
const select = document.createElement("select");
|
|
70
|
+
select.id = "plesty-version-select";
|
|
71
|
+
for (const entry of versions) {
|
|
72
|
+
const option = document.createElement("option");
|
|
73
|
+
option.value = entry.url;
|
|
74
|
+
option.textContent = label(entry.version);
|
|
75
|
+
option.selected = entry.version === current;
|
|
76
|
+
select.appendChild(option);
|
|
77
|
+
}
|
|
78
|
+
// The running version is missing from versions.json when this build has
|
|
79
|
+
// not been indexed yet (a local preview, a tag mid-deploy). Show it so the
|
|
80
|
+
// picker never reads as if the reader were somewhere else.
|
|
81
|
+
if (!versions.some((entry) => entry.version === current)) {
|
|
82
|
+
const option = document.createElement("option");
|
|
83
|
+
option.textContent = label(current);
|
|
84
|
+
option.selected = true;
|
|
85
|
+
option.disabled = true;
|
|
86
|
+
select.insertBefore(option, select.firstChild);
|
|
87
|
+
}
|
|
88
|
+
select.addEventListener("change", () => goTo(select.value, pagePath));
|
|
89
|
+
picker.appendChild(select);
|
|
90
|
+
|
|
91
|
+
// Below the search box, so the picker does not push the search field out
|
|
92
|
+
// of its usual place under the logo.
|
|
93
|
+
container.appendChild(picker);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const ready = (run) =>
|
|
97
|
+
document.readyState === "loading"
|
|
98
|
+
? document.addEventListener("DOMContentLoaded", run)
|
|
99
|
+
: run();
|
|
100
|
+
|
|
101
|
+
fetch(new URL("versions.json", moduleRoot))
|
|
102
|
+
.then((response) => (response.ok ? response.json() : null))
|
|
103
|
+
.then((versions) => {
|
|
104
|
+
// Nothing to pick between — no manifest (a local `plesty docs serve`
|
|
105
|
+
// preview), or a module with no releases yet, whose manifest holds only
|
|
106
|
+
// `latest`. A dropdown with one entry is furniture, not navigation.
|
|
107
|
+
if (Array.isArray(versions) && versions.length > 1) ready(() => render(versions));
|
|
108
|
+
})
|
|
109
|
+
.catch(() => {});
|
|
110
|
+
})();
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
"""Entry point for running the {{ module_name | replace('_', ' ') }} {{ project_type }} as a standalone process."""
|
|
5
5
|
{% if project_type == 'device' %}
|
|
6
6
|
import argparse
|
|
7
|
-
import asyncio
|
|
8
7
|
|
|
9
|
-
from plesty.lib.service import build_server
|
|
8
|
+
from plesty.lib.service import build_server, run_server
|
|
10
9
|
from plesty.lib.utils import EnvSettings
|
|
11
10
|
|
|
12
11
|
from .device import Device
|
|
@@ -64,17 +63,21 @@ async def main() -> None: # pragma: no cover
|
|
|
64
63
|
|
|
65
64
|
if __name__ == "__main__": # pragma: no cover
|
|
66
65
|
try:
|
|
67
|
-
asyncio.run
|
|
66
|
+
# Not a bare asyncio.run: pyzmq needs a loop with add_reader, which on
|
|
67
|
+
# Windows is the selector loop and not the default one. run_server asks
|
|
68
|
+
# for it explicitly — the loop policy that used to arrange it process-wide
|
|
69
|
+
# is deprecated in Python 3.14 and gone in 3.16.
|
|
70
|
+
run_server(main())
|
|
68
71
|
except KeyboardInterrupt:
|
|
69
72
|
print("Server stopped by user.")
|
|
70
73
|
{% elif project_type == 'experiment' %}
|
|
71
74
|
import argparse
|
|
72
|
-
import asyncio
|
|
73
75
|
from pathlib import Path
|
|
74
76
|
from typing import Optional
|
|
75
77
|
|
|
76
78
|
from plesty.lib.device.composite_device import CompositeDevice
|
|
77
79
|
from plesty.lib.experiment import RigNotReadyError, connect_rig
|
|
80
|
+
from plesty.lib.service import run_server
|
|
78
81
|
from plesty.lib.utils.config import load_yaml
|
|
79
82
|
|
|
80
83
|
from .experiment import Experiment
|
|
@@ -200,7 +203,10 @@ async def main() -> None: # pragma: no cover
|
|
|
200
203
|
|
|
201
204
|
if __name__ == "__main__": # pragma: no cover
|
|
202
205
|
try:
|
|
203
|
-
|
|
206
|
+
# The rig's clients are pyzmq sockets, so this run needs the same loop
|
|
207
|
+
# a device server does — see run_server. A bare asyncio.run gets the
|
|
208
|
+
# Windows default one, which has no add_reader, from Python 3.16 on.
|
|
209
|
+
run_server(main())
|
|
204
210
|
except RigNotReadyError as error:
|
|
205
211
|
# The diagnosis is already out (connect_rig printed and logged it);
|
|
206
212
|
# this only says how the process ended, and with a non-zero status.
|