From b3fbe00657c517cf4deedab6e20fd08020c8dc0a Mon Sep 17 00:00:00 2001 From: fawney19 Date: Sun, 14 Dec 2025 00:12:37 +0800 Subject: [PATCH] feat: add version management with setuptools-scm - Configure hatch-vcs for automatic version generation from git tags - Update pyproject.toml to use dynamic versioning - Add src/_version.py for runtime version access - Update src/__init__.py to import version from _version - Add __APP_VERSION__ to frontend vite config - Add version script to frontend package.json - Update CI workflows to trigger on version tags instead of branches --- .github/workflows/deploy-pages.yml | 2 +- .github/workflows/docker-publish.yml | 1 - frontend/package.json | 3 +- frontend/src/vite-env.d.ts | 2 + frontend/vite.config.ts | 12 +++++ pyproject.toml | 11 +++- src/__init__.py | 7 ++- src/_version.py | 34 ++++++++++++ uv.lock | 79 +++++++++++++++++++++++++++- 9 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 src/_version.py diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 06aac74..ea36df8 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -2,7 +2,7 @@ name: Deploy to GitHub Pages on: push: - branches: [master] + tags: ['v*'] workflow_dispatch: permissions: diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 3cd7bf3..11cc5b2 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,7 +2,6 @@ name: Build and Publish Docker Image on: push: - branches: [master, main] tags: ['v*'] workflow_dispatch: inputs: diff --git a/frontend/package.json b/frontend/package.json index bea325e..b6b0271 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,8 @@ "test:ui": "vitest --ui", "test:run": "vitest run", "lint": "eslint . --fix", - "type-check": "vue-tsc --noEmit" + "type-check": "vue-tsc --noEmit", + "version": "git describe --tags --always" }, "dependencies": { "@types/dompurify": "^3.0.5", diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 11f02fe..54eaa07 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -1 +1,3 @@ /// + +declare const __APP_VERSION__: string diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index eb0c207..2420983 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,12 +1,24 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' +import { execSync } from 'child_process' + +function getGitVersion(): string { + try { + return execSync('git describe --tags --always').toString().trim() + } catch { + return '0.0.0.dev0' + } +} // https://vite.dev/config/ export default defineConfig(({ mode }) => ({ // GitHub Pages 部署时使用仓库名作为 base base: process.env.GITHUB_PAGES === 'true' ? '/Aether/' : '/', plugins: [vue()], + define: { + __APP_VERSION__: JSON.stringify(getGitVersion()), + }, resolve: { alias: { '@': path.resolve(__dirname, './src'), diff --git a/pyproject.toml b/pyproject.toml index 864546f..88b02ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = ["hatchling"] +requires = ["hatchling", "hatch-vcs"] build-backend = "hatchling.build" [project] name = "aether" -version = "1.0.0" +dynamic = ["version"] description = "Proxy server enabling Claude Code to work with OpenAI-compatible API providers" readme = "README.md" authors = [ @@ -76,6 +76,7 @@ dev-dependencies = [ "isort>=5.12.0", "mypy>=1.0.0", "pyinstaller>=6.15.0", + "hatch-vcs>=0.5.0", ] [tool.black] @@ -89,6 +90,12 @@ line_length = 100 [tool.hatch.build.targets.wheel] packages = ["src"] +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.hooks.vcs] +version-file = "src/_version.py" + [tool.mypy] python_version = "3.9" warn_return_any = true diff --git a/src/__init__.py b/src/__init__.py index dfc766d..7abffa6 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -7,5 +7,10 @@ from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() -__version__ = "9.1.0" + +try: + from src._version import __version__ +except ImportError: + __version__ = "0.0.0.dev0" + __author__ = "AI Proxy" diff --git a/src/_version.py b/src/_version.py new file mode 100644 index 0000000..29ee8a6 --- /dev/null +++ b/src/_version.py @@ -0,0 +1,34 @@ +# file generated by setuptools-scm +# don't change, don't track in version control + +__all__ = [ + "__version__", + "__version_tuple__", + "version", + "version_tuple", + "__commit_id__", + "commit_id", +] + +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple + from typing import Union + + VERSION_TUPLE = Tuple[Union[int, str], ...] + COMMIT_ID = Union[str, None] +else: + VERSION_TUPLE = object + COMMIT_ID = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE +commit_id: COMMIT_ID +__commit_id__: COMMIT_ID + +__version__ = version = '0.1.1.dev0+g393d4d13f.d20251213' +__version_tuple__ = version_tuple = (0, 1, 1, 'dev0', 'g393d4d13f.d20251213') + +__commit_id__ = commit_id = None diff --git a/uv.lock b/uv.lock index c4d8402..a60672e 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,6 @@ resolution-markers = [ [[package]] name = "aether" -version = "1.0.0" source = { editable = "." } dependencies = [ { name = "aiofiles" }, @@ -49,6 +48,7 @@ dev = [ { name = "black" }, { name = "factory-boy" }, { name = "faker" }, + { name = "hatch-vcs" }, { name = "isort" }, { name = "mypy" }, { name = "pyinstaller" }, @@ -95,6 +95,7 @@ dev = [ { name = "black", specifier = ">=23.0.0" }, { name = "factory-boy", specifier = ">=3.2.0" }, { name = "faker", specifier = ">=18.0.0" }, + { name = "hatch-vcs", specifier = ">=0.5.0" }, { name = "isort", specifier = ">=5.12.0" }, { name = "mypy", specifier = ">=1.0.0" }, { name = "pyinstaller", specifier = ">=6.15.0" }, @@ -1180,6 +1181,58 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, ] +[[package]] +name = "hatch-vcs" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hatchling", version = "1.27.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "hatchling", version = "1.28.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "setuptools-scm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/b0/4cc743d38adbee9d57d786fa496ed1daadb17e48589b6da8fa55717a0746/hatch_vcs-0.5.0.tar.gz", hash = "sha256:0395fa126940340215090c344a2bf4e2a77bcbe7daab16f41b37b98c95809ff9", size = 11424 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/48/1f85cee4b7b4f40b9b814b1febbc661bda6ced9649e410a0b74f6e415dd0/hatch_vcs-0.5.0-py3-none-any.whl", hash = "sha256:b49677dbdc597460cc22d01b27ab3696f5e16a21ecf2700fb01bc28e1f2a04a7", size = 8507 }, +] + +[[package]] +name = "hatchling" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "packaging", marker = "python_full_version < '3.10'" }, + { name = "pathspec", marker = "python_full_version < '3.10'" }, + { name = "pluggy", marker = "python_full_version < '3.10'" }, + { name = "tomli", marker = "python_full_version < '3.10'" }, + { name = "trove-classifiers", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/8a/cc1debe3514da292094f1c3a700e4ca25442489731ef7c0814358816bb03/hatchling-1.27.0.tar.gz", hash = "sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6", size = 54983 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/e7/ae38d7a6dfba0533684e0b2136817d667588ae3ec984c1a4e5df5eb88482/hatchling-1.27.0-py3-none-any.whl", hash = "sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b", size = 75794 }, +] + +[[package]] +name = "hatchling" +version = "1.28.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", +] +dependencies = [ + { name = "packaging", marker = "python_full_version >= '3.10'" }, + { name = "pathspec", marker = "python_full_version >= '3.10'" }, + { name = "pluggy", marker = "python_full_version >= '3.10'" }, + { name = "tomli", marker = "python_full_version == '3.10.*'" }, + { name = "trove-classifiers", marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/8e/e480359492affde4119a131da729dd26da742c2c9b604dff74836e47eef9/hatchling-1.28.0.tar.gz", hash = "sha256:4d50b02aece6892b8cd0b3ce6c82cb218594d3ec5836dbde75bf41a21ab004c8", size = 55365 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/a5/48cb7efb8b4718b1a4c0c331e3364a3a33f614ff0d6afd2b93ee883d3c47/hatchling-1.28.0-py3-none-any.whl", hash = "sha256:dc48722b68b3f4bbfa3ff618ca07cdea6750e7d03481289ffa8be1521d18a961", size = 76075 }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -2453,6 +2506,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486 }, ] +[[package]] +name = "setuptools-scm" +version = "9.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/b1/19587742aad604f1988a8a362e660e8c3ac03adccdb71c96d86526e5eb62/setuptools_scm-9.2.2.tar.gz", hash = "sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57", size = 203385 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/ea/ac2bf868899d0d2e82ef72d350d97a846110c709bacf2d968431576ca915/setuptools_scm-9.2.2-py3-none-any.whl", hash = "sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7", size = 62975 }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -2639,6 +2707,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, ] +[[package]] +name = "trove-classifiers" +version = "2025.12.1.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/e1/000add3b3e0725ce7ee0ea6ea4543f1e1d9519742f3b2320de41eeefa7c7/trove_classifiers-2025.12.1.14.tar.gz", hash = "sha256:a74f0400524fc83620a9be74a07074b5cbe7594fd4d97fd4c2bfde625fdc1633", size = 16985 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/7e/bc19996fa86cad8801e8ffe6f1bba5836ca0160df76d0410d27432193712/trove_classifiers-2025.12.1.14-py3-none-any.whl", hash = "sha256:a8206978ede95937b9959c3aff3eb258bbf7b07dff391ddd4ea7e61f316635ab", size = 14184 }, +] + [[package]] name = "typer" version = "0.16.0"