[WIP][do not review] fix compatibility with 26.1 & define proper compatibility boundaries for releases#512
[WIP][do not review] fix compatibility with 26.1 & define proper compatibility boundaries for releases#512
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #512 +/- ##
==========================================
+ Coverage 81.61% 81.95% +0.34%
==========================================
Files 28 30 +2
Lines 8166 8370 +204
Branches 1501 1534 +33
==========================================
+ Hits 6665 6860 +195
- Misses 1025 1031 +6
- Partials 476 479 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add a dedicated compatibility module that exposes bundled product release metadata, supported annual product lines, and helper conversions between public release labels like 27.1 and internal install versions like 271. Keep the historical package surface intact by deriving DEFAULT_ANSYS_VERSION, ansys_version, __ansys_version__, and __ansys_version_str__ from the new source of truth in __init__.py so existing imports continue to resolve. Wire warning-only compatibility checks into service and serverless install resolution without changing the existing install discovery paths or the three-digit runtime fallback used by current infrastructure. Update README, smoketest, and focused regression tests to cover the new metadata API, compatibility warnings, and the pre-existing install fallback behavior.
Separate the released client compatibility contract from the legacy install-facing version defaults without breaking existing imports. This commit keeps DEFAULT_ANSYS_VERSION, ansys_version, __ansys_version__, and __ansys_version_str__ on the historical install-facing 271 / 2027R1 values while moving the explicit compatibility metadata to the last shipped product line, 26.1 with support for annual lines 25 and 26. It also replaces the single-version install probe path with an ordered multi-candidate resolver that can search 271, then 261, then 251 while preserving the existing get_install_info() API. The new internal InstallResolution metadata is used only to distinguish implicit 271 dev fallback from explicit unsupported targets so warning behavior stays precise without changing user-facing method signatures. Additional comments were added around the compatibility split, probe ordering, and warning suppression rules so maintainers can understand the intent without re-deriving it from the surrounding code.
Document the new versioning split in the README and add focused regression coverage for the behavior introduced by the compatibility/install decoupling. The test updates verify that: - legacy exported constants remain backward compatible and keep their install-facing values - released compatibility metadata now reports the shipped 26.1 baseline and 25/26 support window - implicit install detection falls back from 271 to 261 and 251 in order - explicit ansys_version probing does not scan unrelated versions - implicit 271 discovery suppresses support warnings while explicit unsupported targets still warn Keeping these tests in the existing tests/ hierarchy preserves the separation between production code and test code while making the new behavior explicit and maintainable.
Define the public compatibility contract from the client major version instead of hardcoding a single shipped ADR line. This makes the package policy explicit: 0.x maps to the 26.* ADR epoch, 1.x maps to 27.*, 2.x maps to 28.*, and each major supports the current annual line plus the previous one. This commit updates the compatibility module to derive bundled product releases and supported annual lines from the installed client major, expands the compatibility regression tests to cover the derived mapping, and rewrites the README policy section so the major-to-product relationship is documented in one place. The legacy install-facing defaults remain unchanged in this commit. DEFAULT_ANSYS_VERSION and related shims still point at the existing 271 install baseline so runtime behavior is preserved while the new compatibility policy lands first.
Move the install-facing default off the unreleased 271 layout and back to the released 261 line. This changes the package default install release/version, updates implicit auto-detection to probe 261 first and 251 second before considering 271, and keeps 271 available for explicit requests and lower-priority fallback environments. The runtime compatibility-warning flow now tracks whether a resolved installation came from the package default rather than a hardcoded 271-specific fallback. That keeps service-mode and serverless warnings aligned with the new default-search behavior without breaking explicit unsupported-version reporting. The tests and README are updated to match the new default: legacy install-facing shims now resolve to 2026R1/261, implicit install probing prefers 261 over 271, and explicit 271 requests remain supported.
Reviewing the branch against main uncovered one concrete mismatch with the requested coding constraints: the new serverless settings compatibility shim imported packaging.version.Version, which introduces a third-party runtime dependency path that was never explicitly approved. This follow-up removes that dependency and replaces it with a small stdlib-only version normalizer based on importlib.metadata and regex parsing. The shim still performs the same floor-version checks, but now does so without relying on packaging. The new helper is documented so future readers can see exactly why only leading numeric components are compared. This commit also tightens install-candidate de-duplication in common_utils by pairing the ordered candidate list with a set of seen paths. Behavior stays the same, but duplicate checks become constant-time and the helper comment now explains that tradeoff explicitly. Verification after the change: - uv run pytest tests/test_compatibility.py tests/serverless/test_common_utils.py -q - make check - make smoketest
Add a focused serverless test module for the settings compatibility shim so its behavior is covered directly instead of only indirectly through broader ADR setup paths. The new tests cover: - guardian setting translation from GUARDIAN_MONKEY_PATCH to GUARDIAN_MONKEY_PATCH_USER - preservation of an explicitly supplied GUARDIAN_MONKEY_PATCH_USER value - migration from DEFAULT_FILE_STORAGE to STORAGES['default'] - the no-op path when installed package versions are below the shim thresholds - version normalization for installed package strings with suffixes Verification after adding the test module: - uv run pytest tests/serverless/test_compat.py tests/test_compatibility.py tests/serverless/test_common_utils.py -q - make check - make smoketest
Clarify two points that were still ambiguous in the release/versioning documentation. First, define exactly what 'supported' means for ADR product lines. The README now states that supported lines are the explicit compatibility contract, the scope for compatibility regressions and bug fixes, and the versions covered by the repository's targeted compatibility checks and release validation. Unsupported lines are now described explicitly as best-effort only, with runtime warnings rather than silent implied support. Second, document the policy transition point. The README now treats 0.x as the legacy transition line, calls out 0.10.x as the last legacy line tied to 26.1 behavior, and marks 1.0.0 as the first fully policy-driven release where the product-release-aligned major-version scheme begins. Verification after the documentation change: - make check - make smoketest
Promote the versioning and compatibility policy from README-only guidance into the public Sphinx landing page so users can see it in the hosted docs without reading the repository root. The index page now documents: - the SemVer-to-product compatibility model - the policy transition from the legacy 0.x line to the fully policy-driven 1.x line - what 'supported' means operationally - the default install detection order when ansys_version is omitted - the external-Python serverless guidance around release-specific constraints and the settings compatibility shim This keeps the landing page aligned with the compatibility metadata and install-detection behavior implemented in the code, while linking users to the deeper serverless caveats page for the full dependency-drift explanation. Verification after the doc update: - make check - make smoketest - make docs
Replace the user-facing 'Django dependency set' wording with the simpler 'dependency set' phrasing across the README and Sphinx docs. This keeps the documentation focused on the actual compatibility boundary users need to understand without over-emphasizing framework details in the high-level explanation. The deeper technical details such as django.setup() remain in place where they are operationally relevant. Verification after the terminology update: - make check - make smoketest - make docs
Restore the explicit-installation behavior that CI relies on when the installation path itself does not contain a v### segment. The default install search target remains 261, but explicit installation directories such as temporary Docker extraction paths can still contain the real ADR version inside their shipped nexus### tree. resolve_install_info() now inspects that layout before falling back to the package default, which keeps explicit installs authoritative without weakening the released default-search policy. A focused regression test covers the no-version-path case so future install-default changes do not silently break Docker-backed serverless fixtures again. Verification after the fix: - uv run pytest tests/serverless/test_common_utils.py tests/serverless/test_compat.py tests/test_compatibility.py -q - make check - make smoketest - make docs
There was a problem hiding this comment.
Pull request overview
This PR formalizes the client-to-ADR product compatibility contract (bundled release + supported annual lines), updates install discovery defaults for the released 26.1 line, and adds runtime warnings/shims to improve behavior when targeting unsupported installs or when serverless dependencies drift.
Changes:
- Introduce a public compatibility metadata module and expose it via
ansys.dynamicreporting.core(bundled release, supported lines, policy, helpers, warnings). - Refactor install discovery into
resolve_install_info()(with resolution metadata) and add compatibility warnings in both service-mode and serverless constructors. - Broaden serverless dependency ranges, add per-release constraints (
constraints/v261.txt), and add tests/docs for compatibility and serverless settings drift.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/ansys/dynamicreporting/core/compatibility.py |
New compatibility contract + helpers + warning message generation. |
src/ansys/dynamicreporting/core/__init__.py |
Re-exports compatibility metadata and redefines legacy install-facing constants. |
src/ansys/dynamicreporting/core/common_utils.py |
Install detection refactor + resolution metadata for warning behavior. |
src/ansys/dynamicreporting/core/adr_service.py |
Service-mode uses resolve_install_info() and emits compatibility warnings. |
src/ansys/dynamicreporting/core/serverless/adr.py |
Serverless install resolution warning + settings compatibility shim hook. |
src/ansys/dynamicreporting/core/serverless/_compat.py |
New serverless settings sanitizer for dependency drift scenarios. |
src/ansys/dynamicreporting/core/utils/report_download_html.py |
Default install version now sourced from compatibility defaults. |
src/ansys/dynamicreporting/core/utils/html_export_constants.py |
Default install version now sourced from compatibility defaults. |
pyproject.toml |
Broadens Django/guardian/DRF ranges for serverless “envelope” deps. |
constraints/v261.txt |
Adds per-release constraints profile for ADR v261. |
tests/test_compatibility.py |
New tests for compatibility parsing/mapping and warning behavior. |
tests/serverless/test_compat.py |
New tests for serverless settings sanitization logic. |
tests/serverless/test_common_utils.py |
Extends install-discovery tests for fallback and version inference behavior. |
tests/smoketest.py |
Prints compatibility metadata during smoke runs. |
doc/source/index.rst |
Documents compatibility policy + install-default behavior. |
doc/source/serverless/caveats.rst |
Adds external venv dependency drift explanation + mitigation guidance. |
README.rst |
Adds install/constraints guidance and documents compatibility policy. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| "ceidev", | ||
| "enve", | ||
| "pyadr_env", |
There was a problem hiding this comment.
implicit_default_install_used is set to true even when the install path comes from explicit override mechanisms like PYADR_ANSYS_INSTALLATION, enve.home(), or CEIDEVROOTDOS. Because Service/ADR suppress compatibility warnings when this flag is true, users who explicitly override the install target via env/dev roots may never see the "outside the supported window" warning. Consider restricting implicit_default_install_used to only true for the package's conventional default roots (e.g., default_root_<DEFAULT> / awp_root_<DEFAULT>), or alternatively treat these override sources as explicit so warnings still surface.
| "ceidev", | |
| "enve", | |
| "pyadr_env", |
| if old_key in overrides: | ||
| if new_key not in overrides: | ||
| overrides[new_key] = overrides[old_key] | ||
| logger.info( | ||
| f"Compat shim: Translated '{old_key}' -> '{new_key}' (value={overrides[old_key]})" | ||
| ) | ||
| del overrides[old_key] |
There was a problem hiding this comment.
The compat shim logs raw setting values (e.g., the value of GUARDIAN_MONKEY_PATCH and the DEFAULT_FILE_STORAGE backend). Settings dicts can contain environment-specific paths or secrets, so logging values here can leak sensitive information into application logs. Safer approach: log only that a translation occurred (old/new key names) without including the value/backend, or log at DEBUG with redaction.
| _CLIENT_MAJOR_BASE_PRODUCT_LINE = 26 | ||
| _CLIENT_MAJOR_BASE_BUNDLED_RELEASE = "26.1" |
There was a problem hiding this comment.
_CLIENT_MAJOR_BASE_BUNDLED_RELEASE is defined but never used, which adds noise and may trigger unused-variable linting. Either remove it or use it as the source of truth (e.g., to derive _CLIENT_MAJOR_BASE_PRODUCT_LINE/bundled release) so the base epoch is declared in one place.
| _CLIENT_MAJOR_BASE_PRODUCT_LINE = 26 | |
| _CLIENT_MAJOR_BASE_BUNDLED_RELEASE = "26.1" | |
| _CLIENT_MAJOR_BASE_BUNDLED_RELEASE = "26.1" | |
| _CLIENT_MAJOR_BASE_PRODUCT_LINE = int(_CLIENT_MAJOR_BASE_BUNDLED_RELEASE.split(".", maxsplit=1)[0]) |
Update the compatibility regression tests so they derive current-window expectations from the installed package major instead of assuming the repository is always on the 0.x line. Keep the explicit major-0 and major-1 policy tests unchanged so the fixed mapping remains covered, but make the tests that mean 'current public surface' or 'current unsupported version' compute those values from the actual installed version. This keeps the suite correct once the repo advances to 1.x and later while preserving the install-default assertions tied to the released 261 baseline. Validation: - uv run pytest tests/test_compatibility.py -q - uv run pytest tests/serverless/test_common_utils.py tests/serverless/test_compat.py -q - make check - make smoketest
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| """Extract the SemVer major component from a client version string.""" | ||
| # ``__version__`` may include dev/build suffixes, so only the leading | ||
| # numeric token is relevant for the compatibility epoch. | ||
| major_token = client_version.split(".", maxsplit=1)[0] |
| _PRODUCT_RELEASE_PATTERN = re.compile(r"^(?P<year_line>\d{2})\.(?P<release_index>\d+)$") | ||
| _CLIENT_MAJOR_BASE_PRODUCT_LINE = 26 | ||
| _CLIENT_MAJOR_BASE_BUNDLED_RELEASE = "26.1" | ||
|
|
Clarify the release workflow now that version numbers are tag-driven but older ADR product lines still need a maintained branch. Update the README to explain that main is for the next ADR product line, while long-lived maintenance branches use the stable/<product-line>.x convention. Also replace the outdated statement that release branches are no longer needed with guidance that tags should be created from the maintenance branch that owns the supported product line. Validation: - make check - make smoketest
No description provided.