diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index b5ffdf7..929bf67 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -84,6 +84,8 @@ jobs: - name: Build the container image if: fromJSON(steps.builder.outputs.run) uses: actions/buildah-build@v1 + env: + VERSION: ${{ steps.version.outputs.version }} with: image: treetrail-backend oci: true @@ -91,6 +93,8 @@ jobs: tags: ${{ steps.version.outputs.version }} containerfiles: | ./Containerfile + build-arg: | + "VERSION=$VERSION" - name: Push the image to the registry if: fromJSON(steps.builder.outputs.run) diff --git a/Containerfile b/Containerfile index 3273154..0351e3d 100644 --- a/Containerfile +++ b/Containerfile @@ -3,6 +3,7 @@ FROM tiptop:5000/treetrail-backend-deps ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages +ARG APP_VERSION=0.0.0 COPY . /src @@ -15,6 +16,8 @@ RUN uv pip install \ --no-deps \ /src +RUN echo $APP_VERSION > /app/version.txt + CMD [ \ "uvicorn", "treetrail.application:app", \ "--port", "8081", \ diff --git a/build.yaml b/build.yaml index 1f620f2..1f69cfb 100644 --- a/build.yaml +++ b/build.yaml @@ -1,8 +1,7 @@ -- name: Build containers +- name: Build containers images hosts: localhost gather_facts: false vars: - force: false force_rm: false cache: false repository: tiptop:5000 @@ -31,9 +30,15 @@ push_args: dest: "{{ repository }}/treetrail-backend-deps" + - name: Get the version from git + command: git describe --dirty --tags + register: version + args: + chdir: "{{ playbook_dir }}" + - name: Build the backend container image containers.podman.podman_image: - name: treetrail-backend + name: "treetrail-backend:{{ version.stdout }}" state: build force: true path: "{{ playbook_dir }}" @@ -42,6 +47,7 @@ force_rm: "{{ force_rm }}" cache: "{{ cache }}" file: Containerfile + extra_args: "--build-arg APP_VERSION={{ version.stdout }}" push: true push_args: - dest: "{{ repository }}/treetrail-backend" + dest: "{{ repository }}/treetrail-backend:{{ version.stdout }}" diff --git a/pyproject.toml b/pyproject.toml index fc26105..6cf4e5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [project] name = "treetrail-backend" -version = "0.3.0" -#dynamic = ["version"] +version = "0.0.0" #dynamic = ["version"] description = "A fun and pedagogic tool to discover the trails and trees around" authors = [ diff --git a/src/treetrail/__init__.py b/src/treetrail/__init__.py new file mode 100644 index 0000000..56ead07 --- /dev/null +++ b/src/treetrail/__init__.py @@ -0,0 +1,3 @@ +from treetrail.utils import get_version + +__version__ = get_version() \ No newline at end of file diff --git a/src/treetrail/__main__.py b/src/treetrail/__main__.py new file mode 100644 index 0000000..2c86e3f --- /dev/null +++ b/src/treetrail/__main__.py @@ -0,0 +1,3 @@ +from .application import _main + +_main() \ No newline at end of file diff --git a/src/treetrail/_version.py b/src/treetrail/_version.py deleted file mode 100644 index 0404d81..0000000 --- a/src/treetrail/_version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '0.3.0' diff --git a/src/treetrail/api_v1.py b/src/treetrail/api_v1.py index 41a1ce7..b1ba9d3 100644 --- a/src/treetrail/api_v1.py +++ b/src/treetrail/api_v1.py @@ -36,7 +36,8 @@ from treetrail.models import (BaseMapStyles, User, Role, Bootstrap, MapStyle, Tree, Trail, TreeTrail, POI, UserWithRoles, Zone, VersionedComponent) -from treetrail.config import conf, get_cache_dir, __version__ +from treetrail.config import conf, get_cache_dir +from treetrail import __version__ from treetrail.plantekey import get_local_details from treetrail.tiles import registry as tilesRegistry diff --git a/src/treetrail/application.py b/src/treetrail/application.py index afa8cd8..fab6476 100755 --- a/src/treetrail/application.py +++ b/src/treetrail/application.py @@ -51,22 +51,7 @@ app.mount( def _main(argv=None): from argparse import ArgumentParser arg_parser = ArgumentParser( - description="fastapi Application server", - prog="fastapi" - ) - arg_parser.add_argument( - '--path', - help='Path of socket file', - ) - arg_parser.add_argument( - "-H", "--hostname", - help="TCP/IP hostname to serve on (default: %(default)r)", - default="localhost" - ) - arg_parser.add_argument( - "-P", "--port", - help="TCP/IP port to serve on", - type=int, + description="Treetrail backend / server", ) arg_parser.add_argument( "-c", "--create-db", @@ -154,6 +139,11 @@ def _main(argv=None): help="Set debug logging", action="store_true" ) + arg_parser.add_argument( + "--version", + help="Print version and exit", + action="store_true" + ) args = arg_parser.parse_args() if args.debug: @@ -161,6 +151,11 @@ def _main(argv=None): ## For ipdb: logging.getLogger('parso').setLevel(logging.WARNING) + if args.version: + import treetrail + print(treetrail.__version__) + sys.exit(0) + if args.create_db: from treetrail.database import create_db import asyncio @@ -233,7 +228,8 @@ def _main(argv=None): sys.exit(0) print( - 'This application needs to be run with an asgi server like uvicorn.', + 'No CLI option was given, try --help', + 'To run the server, use an asgi server like uvicorn.', 'For example:', 'uvicorn application:app', 'or:', diff --git a/src/treetrail/config.py b/src/treetrail/config.py index e103a9e..2bdfa4e 100644 --- a/src/treetrail/config.py +++ b/src/treetrail/config.py @@ -12,8 +12,6 @@ from pydantic_settings import ( ) from pydantic.v1.utils import deep_update -from treetrail._version import __version__ - logger = logging.getLogger(__name__) ENV = environ.get("env", "prod") @@ -163,9 +161,9 @@ class Config(MyBaseSettings): tiles: Tiles = Tiles() security: Security = Security() geo: Geo = Geo() - version: str + version: str = '-' db: DB = DB() base_href: str = "/treetrail" -conf = Config(version=__version__) # type: ignore +conf = Config() diff --git a/src/treetrail/utils.py b/src/treetrail/utils.py index 52ee9d0..78dc42e 100644 --- a/src/treetrail/utils.py +++ b/src/treetrail/utils.py @@ -84,3 +84,28 @@ def mkdir(dir: Path | str) -> Path: logger.info(f'Create directory {path}') path.mkdir(parents=True, exist_ok=True) return path + +def get_version() -> str: + version_file_src = Path(__file__).parent / 'version.txt' + version_file_in_container = Path("/app") / 'version.txt' + if version_file_src.exists(): + with open(version_file_src) as version: + return version.read().strip() + if version_file_in_container.exists(): + with open(version_file_in_container) as version: + return version.read().strip() + else: + logger.debug('No version file, using git') + try: + from subprocess import run + git_version_cmd = run(['git', 'describe', '--broken', '--tags', '--always', '--dirty'], + capture_output=True) + if git_version_cmd.returncode == 0: + return git_version_cmd.stdout.strip().decode() + else: + logger.debug('git returns with the error below, version set as 0.0.0') + logger.debug(git_version_cmd.stderr.decode()) + return '0.0.0' + except FileNotFoundError as err: + logger.debug('git not found: version set as 0.0.0') + return '0.0.0' \ No newline at end of file