Skip to content

fix: derive sub-package __version__ from a single source of truth#182

Open
KomanRudden wants to merge 2 commits into
mainfrom
fix/sub-package-version-drift
Open

fix: derive sub-package __version__ from a single source of truth#182
KomanRudden wants to merge 2 commits into
mainfrom
fix/sub-package-version-drift

Conversation

@KomanRudden
Copy link
Copy Markdown
Contributor

@KomanRudden KomanRudden commented May 22, 2026

Makes kinde_sdk/_version.py the source of truth for the SDK version: the top-level package, both generated sub-packages, and pyproject.toml now all derive from it.
Generator scripts read the same value to set packageVersion, and bumps the SDK to 2.3.0.
Adds a regression test that fail if any of those four versions ever go out of sync.

Checklist

🛟 If you need help, consider asking for advice over in the Kinde community.

The OpenAPI-generated kinde_sdk.management and kinde_sdk.frontend
sub-packages have been emitting __version__ = "2.0.0" since the 2.x
line was cut, regardless of what the SDK is actually shipped as. The
2.3.0 wheel on PyPI demonstrates the drift: kinde_sdk.__version__ is
"2.3.0" but kinde_sdk.management.__version__ and
kinde_sdk.frontend.__version__ both report "2.0.0".

Root cause: packageVersion was hard-coded across both generator
scripts and their config files. Every regeneration wrote the stale
value back into the sub-package __init__.py files, and bumping the
top-level SDK didn't propagate.

This change introduces a single source of truth and keeps the
generated sub-packages dynamically in sync, so the literal version
no longer appears in any sub-package __init__.py at all.

Changes:
- New kinde_sdk/_version.py contains the only literal version string
  in the SDK. It has zero imports so it can be safely re-exported from
  any sub-package without risking a circular import.
- kinde_sdk/__init__.py re-exports __version__ from _version.
- kinde_sdk/management/__init__.py and kinde_sdk/frontend/__init__.py
  now do the same: `from kinde_sdk._version import __version__`.
  No literal version string in either file - cannot drift.
- generate_management_sdk.py and generate_frontend_sdk.py both gain a
  make_version_dynamic() post-generation step that rewrites the
  OpenAPI-emitted `__version__ = "X"` line back to the import on
  every regeneration. Idempotent: a no-op if already rewritten.
- Both generator scripts still derive packageVersion from
  kinde_sdk._version (via _read_sdk_version) so other generated
  artifacts that embed the version literally - notably user-agent
  headers in the generated configuration.py - also stay in lockstep.
- generate_frontend_sdk.py now (re)writes generator/frontend_config.yaml
  on every run rather than only when missing, so a stale local config
  can no longer silently override the SDK version.
- openapitools.json packageVersion bumped to 2.2.0 to match today's
  SDK version. This file is overwritten by generate_management_sdk.py
  on every run from kinde_sdk._version, so it stays in sync going
  forward; the bump just brings the checked-in config into agreement.

Going forward, bump kinde_sdk/_version.py and you're done -
kinde_sdk.__version__, kinde_sdk.management.__version__,
kinde_sdk.frontend.__version__, and importlib.metadata all report the
new value, with no need to touch any sub-package __init__.py.

Verified end-to-end in a clean venv (pip install -e .): all three
namespaces resolve to the same __version__ object, no circular import.

Made-with: Cursor
@KomanRudden KomanRudden requested a review from a team as a code owner May 22, 2026 03:54
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Review Change Stack

Walkthrough

This PR consolidates Python SDK version management to a single source of truth. It creates kinde_sdk/_version.py containing the canonical __version__ definition, updates all runtime packages to import from it, and modifies both code generators to write dynamically-imported version statements in generated sub-packages instead of embedding literal versions.

Changes

Version consolidation to single source of truth

Layer / File(s) Summary
Canonical version source
kinde_sdk/_version.py
Establishes a minimal module with no external imports defining __version__ = "2.2.0" as the authoritative version for the entire SDK.
Package version imports
kinde_sdk/__init__.py, kinde_sdk/management/__init__.py
Both main and management packages now import __version__ from kinde_sdk._version instead of defining it locally, eliminating duplicate version strings.
Frontend generator version sync
generate_frontend_sdk.py
Adds _read_sdk_version() to read from the canonical version file, replaces hardcoded 2.0.0 with dynamic SDK_VERSION in config generation, and introduces make_version_dynamic() to rewrite the generated frontend __init__.py to import __version__ instead of embedding a literal.
Management generator version sync
generate_management_sdk.py
Adds _read_sdk_version() and make_version_dynamic(), updates OpenAPI configuration and command-line packageVersion properties to use the dynamic SDK_VERSION, and rewrites the generated management __init__.py to import __version__ dynamically for consistency across regenerations.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: introducing a single source of truth for sub-package version to prevent drift.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains the problem (version drift between sub-packages and main SDK), the root cause, and the implemented solution with specific technical details about how the fix works.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sub-package-version-drift

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
generate_frontend_sdk.py (1)

241-254: 💤 Low value

Minor: Comment references wrong source file.

Line 243 states packageVersion is derived from kinde_sdk/__init__.py's __version__, but the generator actually reads from kinde_sdk/_version.py directly via _read_sdk_version(). Consider updating the comment for accuracy.

📝 Suggested fix
-# packageVersion is derived from kinde_sdk/__init__.py's __version__.
+# packageVersion is derived from kinde_sdk/_version.py's __version__.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@generate_frontend_sdk.py` around lines 241 - 254, Comment in
generate_frontend_sdk.py incorrectly states the packageVersion is derived from
kinde_sdk/__init__.py; update that comment to reference kinde_sdk/_version.py
(or the _read_sdk_version() helper) and/or say it is derived from SDK_VERSION
which is populated by _read_sdk_version(), so the config header using
CONFIG_FILE and packageVersion: {SDK_VERSION} accurately documents the source.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@generate_frontend_sdk.py`:
- Around line 241-254: Comment in generate_frontend_sdk.py incorrectly states
the packageVersion is derived from kinde_sdk/__init__.py; update that comment to
reference kinde_sdk/_version.py (or the _read_sdk_version() helper) and/or say
it is derived from SDK_VERSION which is populated by _read_sdk_version(), so the
config header using CONFIG_FILE and packageVersion: {SDK_VERSION} accurately
documents the source.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37baef7a-7643-463f-9f09-4b4e6142ec0f

📥 Commits

Reviewing files that changed from the base of the PR and between 05f4ce5 and 6f4e060.

⛔ Files ignored due to path filters (2)
  • kinde_sdk/frontend/__init__.py is excluded by !kinde_sdk/frontend/**
  • openapitools.json is excluded by !**/*.json
📒 Files selected for processing (5)
  • generate_frontend_sdk.py
  • generate_management_sdk.py
  • kinde_sdk/__init__.py
  • kinde_sdk/_version.py
  • kinde_sdk/management/__init__.py

@KomanRudden KomanRudden requested a review from a team as a code owner May 22, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant