Closes #22603: Add experimental Python packaging support for NetBox#22605
Conversation
|
@claude /review Only report on issues of potential concern; we don't need commentary on anything that doesn't require further consideration. |
|
Claude finished @pheus's task in 2m 27s —— View job Code Review
Issues of Concern1. Bug: Wrong command for docs build (
|
|
jeremystretch
left a comment
There was a problem hiding this comment.
Nice work @pheus! I think we should talk through the wheel vs. checkout layout considerations; I'm sure there's a good reason for the disparity but it seems very fragile IMO.
| # In a wheel install, package data is bundled under netbox/_data. In a checkout, | ||
| # the data directories remain siblings of the settings package's parent. |
There was a problem hiding this comment.
I'd like to dig into why this is. IMO it feels very fragile to accommodate two different file hierarchies.
There was a problem hiding this comment.
The split comes from the wheel layout: immutable application/package data lives in the installed Python package, while mutable instance-local files need to live outside the wheel under the instance root. For checkout installs, the existing source tree layout remains unchanged.
I can try to reduce the fragility here by centralizing the install-mode/path decisions more clearly instead of spreading wheel-vs-checkout checks through settings.
| return candidate if os.path.isfile(os.path.join(candidate, 'mkdocs.yml')) else None | ||
|
|
||
|
|
||
| def run_upgrade_tasks(command, *, no_input=False, readonly=False, |
There was a problem hiding this comment.
This seems largely redundant to upgrade.sh, which is retained in its original form. Should we update upgrade.sh to wrap the new manage.py upgrade command? I'd like to avoid having to maintain both avenues in parallel.
There was a problem hiding this comment.
Good point. My intention is not to alter upgrade.sh during the NetBox v4.6.x release series, and instead switch the script to manage.py upgrade in NetBox v4.7.0.
That keeps the existing source/archive upgrade path unchanged for now, while still allowing us to test the management command and adopt it later.
|
Thank you for the thoughtful review! I appreciate you taking the time to go through the packaging approach in detail. Wheel vs. checkout layoutThe main reason for the split is that a wheel installs NetBox’s application code and bundled package data into the Python environment, while instance-local files like There is also an import-path issue with the current configuration loading model. Today, NetBox loads its default configuration as the Python module That is why the wheel install uses an instance-local I did keep a fallback for the legacy source-style path for a grace period, but making that the default for wheel installs would require users to create a mostly empty My goal was to keep the current checkout/archive layout unchanged and only introduce the separate instance root for wheel installs. Changing the configuration path for all installation methods could be discussed separately, but I think that would be better handled as a breaking-change release rather than as part of this packaging PR. |
|
@claude /review Only report on issues of potential concern; we don't need commentary on anything that doesn't require further consideration. |
|
Claude finished @pheus's task in 4m 7s —— View job Code Review
Issues of Concern1. Built docs write into site-packages — will break in restricted venvs and is clobbered by upgrade (unresolved maintainer concern)
In wheel mode, Two concrete problems:
The 2. CodeQL false positive still firing — no suppression added after author agreed to add onePrior review identified print(generate_secret_key()) # line 89 — no suppression
3.
|
29cdd15 to
f91ec71
Compare
|
@claude /review Only report on issues of potential concern; we don't need commentary on anything that doesn't require further consideration.
|
|
Claude finished @pheus's task in 4m 14s —— View job Code Review
All four stated resolutions are verified in the code. 1 — Docs bundled in wheel (resolved): 2 — CodeQL (informational): There are no inline suppression comments on 3 — 4 — One process note: jeremystretch's CHANGES_REQUESTED review is still open. His individual comments on the dual-hierarchy layout fragility and the |
f91ec71 to
015c39c
Compare
jeremystretch
left a comment
There was a problem hiding this comment.
Just one more minor note.
|
|
||
| # Static files (CSS, JavaScript, Images) | ||
| STATIC_ROOT = BASE_DIR + '/static' | ||
| STATIC_ROOT = getattr(configuration, 'STATIC_ROOT', os.path.join(NETBOX_ROOT, 'static')).rstrip('/') |
There was a problem hiding this comment.
Is there a need to expose STATIC_ROOT as a configuration parameter? If so, it needs to be documented in docs/configuration/system.md. Would prefer to keep this fixed if we can, as allowing administrators to change the path feels like it's inviting breakage.
There was a problem hiding this comment.
You're right, there is no need to expose this as a configuration parameter. I've removed it and kept STATIC_ROOT fixed. Thanks for the pushback.
Add GitHub Actions workflow for building and publishing NetBox to PyPI. Include verification jobs for dependency pins, sdist contents, wheel metadata, and smoke tests.
Address the first round of maintainer review on the pip install support, together with a follow-up simplification pass over the whole branch. The wheel now ships the documentation sources (docs/ and mkdocs.yml), so `netbox upgrade --build-docs` works on pip installs with the already pinned toolchain. DOCS_ROOT always resolves, and the docs static entry is unconditional again in both install modes. All remaining wheel-vs-checkout path decisions live in a single tested resolve_install_paths() helper that settings.py merely consumes. `netbox setup` is scaled back to honest bootstrapping: it scaffolds the conf/ package and local_requirements.txt, and copies the bundled contrib deployment examples byte-verbatim into <target>/contrib/. The unit rendering and adaptation logic is gone, along with --force and --systemd-dir; adapting and installing services remains the administrator's responsibility. The console script is now argparse-driven, the upgrade helpers moved into the management command itself, configuration_dir() became get_configuration_dir(), and the configuration loader removes only the sys.path entry it inserted. A few genuine bugs surfaced while reworking this: `netbox setup` crashed on wheel installs once pip byte-compiled the bundled gunicorn.py example (a stray __pycache__ broke the copy loop), the SECRET_KEY error hint pointed wheel users at a script that is not packaged (it now recommends `netbox secret-key` in wheel mode), and read-only upgrades silently omitted the skipped steps that have no dedicated flag. On the CI side, the publish job enforces the release tag format up front, a new cli-smoke-test job exercises the wheel CLI on every pull request, the full smoke test builds and collects the documentation, and the wheel content verifier cross-checks its expectations against pyproject's force-include table so the two cannot drift apart silently.
015c39c to
e5cc434
Compare
Remove on-instance documentation builds from wheels. Render docs with `zensical build -c -s` before packaging; the wheel bundles the rendered site under `_data/docs`. Update smoke tests to verify collected docs and use `$RUNNER_TEMP` instead of `/tmp` for portability.
e5cc434 to
6e1e17f
Compare
Closes: #22603
This PR adds the code and release infrastructure needed to build and test NetBox as an official Python package.
The packaged install path is experimental during the TestPyPI validation phase. Existing archive and git-clone workflows remain unchanged and continue to be the supported production installation methods until the packaged workflow is promoted.
This PR targets TestPyPI only. Production PyPI publishing is intentionally deferred until the packaged installation workflow is documented and promoted.
This PR covers:
netboxcommand;netbox upgrade;This PR does not:
netbox installcommand;The goal is to make the package artifacts buildable, testable, and safe to iterate on before the packaged install workflow is documented and promoted.