From 6e5711bfd15de101f1a3cba4eaeac87c7cb86bc3 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 04:51:32 +0100 Subject: [PATCH 01/34] CI: fix build 4 --- .forgejo/workflows/build.yaml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 9febfea..c113f44 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -11,11 +11,11 @@ on: jobs: build: runs-on: container - container: - image: tiptop:5000/treetrail-backend-ci - volumes: - - "uv_cache:/root/.cache/uv" - - "ca-cert:/etc/containers/certs.d" + #container: + # image: tiptop:5000/treetrail-backend-ci + # volumes: + # - "uv_cache:/root/.cache/uv" + # - "ca-cert:/etc/containers/certs.d" steps: - uses: actions/checkout@v4 @@ -26,9 +26,6 @@ jobs: id: version run: echo "version=$(git describe --dirty --tags)" >> $GITHUB_OUTPUT - - name: Install app with 'uv pip install' - run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - - name: Workaround for bug of podman-login run: | mkdir -p $HOME/.docker From cc4584ae973b764fe93d259400532a742ce16fec Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 04:57:44 +0100 Subject: [PATCH 02/34] CI: build container image on request only --- .forgejo/workflows/build.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index c113f44..28fdb2d 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -1,21 +1,9 @@ on: - push: workflow_dispatch: - inputs: - verbose: - description: "Verbose" - required: false - default: false - type: boolean jobs: build: runs-on: container - #container: - # image: tiptop:5000/treetrail-backend-ci - # volumes: - # - "uv_cache:/root/.cache/uv" - # - "ca-cert:/etc/containers/certs.d" steps: - uses: actions/checkout@v4 From b523ead55ff124acb8856b785af0cc0517cdabc4 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 19:12:28 +0100 Subject: [PATCH 03/34] CI: build container when the version is a clean tag --- .forgejo/workflows/build.yaml | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 28fdb2d..6605e1a 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -1,25 +1,49 @@ on: + push: workflow_dispatch: + inputs: + build: + description: "Build container" + required: true + default: true + type: boolean jobs: build: runs-on: container steps: - uses: actions/checkout@v4 - - - name: Git unshallow - get all history from Git to get the tag for the computation of the version - run: git pull --unshallow + with: + fetch-depth: 0 - name: Get the version from git id: version run: echo "version=$(git describe --dirty --tags)" >> $GITHUB_OUTPUT + - name: Check if the container should be built + id: builder + env: + RUN: ${{ toJSON(inputs.build || !contains(steps.version.outputs.version, '-')) }} + run: | + echo "run=$RUN" >> $GITHUB_OUTPUT + echo "Run build: $RUN" + + - name: Info - version and if the image container should be built + env: + VERSION: ${{ steps.version.outputs.version }} + RUN: ${{ steps.builder.outputs.run }} + FORCE: ${{ toJSON(inputs.build) }} + run: | + echo "Version $VERSION, force (manual input): $FORCE, run the build: $RUN" + - name: Workaround for bug of podman-login + if: fromJSON(steps.builder.outputs.run) run: | mkdir -p $HOME/.docker echo "{ \"auths\": {} }" > $HOME/.docker/config.json - name: Log in to the container registry (with another workaround) + if: fromJSON(steps.builder.outputs.run) uses: actions/podman-login@v1 with: registry: ${{ vars.REGISTRY }} @@ -28,6 +52,7 @@ jobs: auth_file_path: /tmp/auth.json - name: Build the container image + if: fromJSON(steps.builder.outputs.run) uses: actions/buildah-build@v1 with: image: treetrail-backend @@ -38,6 +63,7 @@ jobs: ./Containerfile - name: Push the image to the registry + if: fromJSON(steps.builder.outputs.run) uses: actions/push-to-registry@v2 with: registry: "docker://${{ vars.REGISTRY }}" From 93d414673c890279f3429af0fb59963b63d61286 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 19:26:43 +0100 Subject: [PATCH 04/34] CI: build only if the test pass --- .forgejo/workflows/test.yaml | 34 ------------------- .../{build.yaml => test_and_build.yalm} | 30 ++++++++++++++++ 2 files changed, 30 insertions(+), 34 deletions(-) delete mode 100644 .forgejo/workflows/test.yaml rename .forgejo/workflows/{build.yaml => test_and_build.yalm} (74%) diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml deleted file mode 100644 index a3831c1..0000000 --- a/.forgejo/workflows/test.yaml +++ /dev/null @@ -1,34 +0,0 @@ -on: - push: - workflow_dispatch: - inputs: - verbose: - description: "Verbose" - required: false - default: false - type: boolean - -jobs: - test: - runs-on: container - container: - image: tiptop:5000/treetrail-backend-ci - volumes: - - "uv_cache:/root/.cache/uv" - - "ca-cert:/etc/containers/certs.d" - services: - treetrail-database: - image: treetrail-database - steps: - - name: Echo env - if: ${{ inputs.verbose }} - run: | - echo '${{ toJSON(env) }}' - - - uses: actions/checkout@v4 - - - name: Install app with 'uv pip install' - run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - - - name: Run tests (API call) - run: pytest -s tests/basic.py diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/test_and_build.yalm similarity index 74% rename from .forgejo/workflows/build.yaml rename to .forgejo/workflows/test_and_build.yalm index 6605e1a..0c72721 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/test_and_build.yalm @@ -2,6 +2,11 @@ on: push: workflow_dispatch: inputs: + verbose: + description: "Verbose" + required: false + default: false + type: boolean build: description: "Build container" required: true @@ -9,8 +14,33 @@ on: type: boolean jobs: + test: + runs-on: container + container: + image: tiptop:5000/treetrail-backend-ci + volumes: + - "uv_cache:/root/.cache/uv" + - "ca-cert:/etc/containers/certs.d" + services: + treetrail-database: + image: treetrail-database + steps: + - name: Echo env + if: ${{ inputs.verbose }} + run: | + echo '${{ toJSON(env) }}' + + - uses: actions/checkout@v4 + + - name: Install app with 'uv pip install' + run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . + + - name: Run tests (API call) + run: pytest -s tests/basic.py + build: runs-on: container + needs: test steps: - uses: actions/checkout@v4 with: From 5ef71e1f17dde719069258bf7fe8d475c9562980 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 19:32:05 +0100 Subject: [PATCH 05/34] CI: fix file name --- .forgejo/workflows/{test_and_build.yalm => test_and_build.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .forgejo/workflows/{test_and_build.yalm => test_and_build.yaml} (100%) diff --git a/.forgejo/workflows/test_and_build.yalm b/.forgejo/workflows/test_and_build.yaml similarity index 100% rename from .forgejo/workflows/test_and_build.yalm rename to .forgejo/workflows/test_and_build.yaml From 5a9f28dfb4158af2a9aa6d8e156304a7ee1ee366 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 19:34:33 +0100 Subject: [PATCH 06/34] CI: default not to build container image manually --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 0c72721..b5ffdf7 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -10,7 +10,7 @@ on: build: description: "Build container" required: true - default: true + default: false type: boolean jobs: From 2d0b78872832ca3977e4f984ec50a322c6d132ce Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Nov 2024 19:44:10 +0100 Subject: [PATCH 07/34] Cleanup --- Containerfile.for_runner | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Containerfile.for_runner diff --git a/Containerfile.for_runner b/Containerfile.for_runner deleted file mode 100644 index 71eef99..0000000 --- a/Containerfile.for_runner +++ /dev/null @@ -1,15 +0,0 @@ -# FIXME: do not use hardcoded registry -FROM tiptop:5000/trixie_python - -WORKDIR /app - -ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages - -COPY --from=tiptop:5000/treetrail_backend_deps /app /app -#COPY --from=tiptop:5000/treetrail_backend_deps /var/lib/treetrail/ /var/lib/treetrail -COPY ./treetrail ./pyproject.toml ./README.md ./ - -# Instances should override the prod.yaml file -#COPY ./prod.yaml /etc/treetrail/prod.yaml - -CMD ["uvicorn", "treetrail.application:app", "--port", "8081", "--log-config", "logging.yaml", "--host", "0.0.0.0"] From 1693662e75557bfacf7ebd2ae5d05ad050557c92 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 03:58:58 +0100 Subject: [PATCH 08/34] Version file added dynamically (workaround as uv does not have this feature yet) Tag container image with playbook Importable module with python -m treetrail --- .forgejo/workflows/test_and_build.yaml | 4 ++++ Containerfile | 3 +++ build.yaml | 14 ++++++++---- pyproject.toml | 3 +-- src/treetrail/__init__.py | 3 +++ src/treetrail/__main__.py | 3 +++ src/treetrail/_version.py | 1 - src/treetrail/api_v1.py | 3 ++- src/treetrail/application.py | 30 +++++++++++--------------- src/treetrail/config.py | 6 ++---- src/treetrail/utils.py | 25 +++++++++++++++++++++ 11 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 src/treetrail/__init__.py create mode 100644 src/treetrail/__main__.py delete mode 100644 src/treetrail/_version.py 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 From d1b7357de4574b9b476de4e2c0cad94d94eee6fc Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 04:10:09 +0100 Subject: [PATCH 09/34] CI: fix app version --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 929bf67..3ce200c 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -94,7 +94,7 @@ jobs: containerfiles: | ./Containerfile build-arg: | - "VERSION=$VERSION" + "APP_VERSION=$VERSION" - name: Push the image to the registry if: fromJSON(steps.builder.outputs.run) From c1ffb17162c7fe1928d353e74283169d8870dcee Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 04:17:55 +0100 Subject: [PATCH 10/34] CI: fix app version 2 --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 3ce200c..c0c1c10 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -93,7 +93,7 @@ jobs: tags: ${{ steps.version.outputs.version }} containerfiles: | ./Containerfile - build-arg: | + build-args: | "APP_VERSION=$VERSION" - name: Push the image to the registry From a23674ff639f3026ccc4b1895600265328ecdcf6 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 04:36:12 +0100 Subject: [PATCH 11/34] CI: fix app version 3 --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index c0c1c10..bcd11fc 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -94,7 +94,7 @@ jobs: containerfiles: | ./Containerfile build-args: | - "APP_VERSION=$VERSION" + "APP_VERSION=${{ steps.version.outputs.version }}" - name: Push the image to the registry if: fromJSON(steps.builder.outputs.run) From e77bb9eb5437f5fd5e631fe7234ab26b115960d4 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 04:39:06 +0100 Subject: [PATCH 12/34] CI: fix app version fix --- .forgejo/workflows/test_and_build.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index bcd11fc..5286f5b 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -84,8 +84,6 @@ 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 From 6abdb5e0d66d2e86f632b1824f3d1026d3ad775e Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 13:39:38 +0100 Subject: [PATCH 13/34] CI: full image name for the database service --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 5286f5b..128bae1 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -23,7 +23,7 @@ jobs: - "ca-cert:/etc/containers/certs.d" services: treetrail-database: - image: treetrail-database + image: tiptop:5000/treetrail-database steps: - name: Echo env if: ${{ inputs.verbose }} From 259f881815b9fefcd54648b7662163df2a2ecc98 Mon Sep 17 00:00:00 2001 From: phil Date: Mon, 4 Nov 2024 23:15:01 +0100 Subject: [PATCH 14/34] CI: full image name for the database service 2 --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 128bae1..d384e1e 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -92,7 +92,7 @@ jobs: containerfiles: | ./Containerfile build-args: | - "APP_VERSION=${{ steps.version.outputs.version }}" + APP_VERSION=${{ steps.version.outputs.version }} - name: Push the image to the registry if: fromJSON(steps.builder.outputs.run) From 5c27a26e785f83c733bcb48be1c4bbe632ffc4e5 Mon Sep 17 00:00:00 2001 From: phil Date: Thu, 5 Dec 2024 18:59:55 +0100 Subject: [PATCH 15/34] Update registry and containers for CI --- .forgejo/workflows/test_and_build.yaml | 2 +- Containerfile | 2 +- Containerfile.ci | 2 +- Containerfile.deps | 2 +- Containerfile.full_copy | 1 + Containerfile.trixie_python | 14 +++++++------- uv.lock | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index d384e1e..bbaedf9 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -98,6 +98,6 @@ jobs: if: fromJSON(steps.builder.outputs.run) uses: actions/push-to-registry@v2 with: - registry: "docker://${{ vars.REGISTRY }}" + registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" image: treetrail-backend tags: ${{ steps.version.outputs.version }} diff --git a/Containerfile b/Containerfile index 0351e3d..07fadf4 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -# Build: podman build -t treetrail-backend-base -f Containerfile.base +# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-base -f Containerfile.base FROM tiptop:5000/treetrail-backend-deps diff --git a/Containerfile.ci b/Containerfile.ci index 4725b1c..76b217f 100644 --- a/Containerfile.ci +++ b/Containerfile.ci @@ -1,4 +1,4 @@ -# Build: podman build -t treetrail-backend-ci -f Containerfile.ci +# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-ci -f Containerfile.ci FROM tiptop:5000/python-ci diff --git a/Containerfile.deps b/Containerfile.deps index dd111f8..c80eeff 100644 --- a/Containerfile.deps +++ b/Containerfile.deps @@ -1,4 +1,4 @@ -# Build: podman build -t treetrail-backend-deps -f Containerfile.deps +# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-deps -f Containerfile.deps FROM tiptop:5000/trixie_python diff --git a/Containerfile.full_copy b/Containerfile.full_copy index 357a81f..c725c87 100644 --- a/Containerfile.full_copy +++ b/Containerfile.full_copy @@ -1,3 +1,4 @@ +# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-full -f Containerfile.full_copy FROM localhost/trixie_python ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages diff --git a/Containerfile.trixie_python b/Containerfile.trixie_python index 53d6c3c..34ae5ff 100644 --- a/Containerfile.trixie_python +++ b/Containerfile.trixie_python @@ -1,4 +1,4 @@ -# Build: podman build -t trixie_python -f Containerfile.trixie_python +# Build: podman build -t code.philo.ydns.eu/philorg/trixie_python -f Containerfile.trixie_python FROM debian:trixie-slim @@ -15,9 +15,9 @@ EOT COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv ENV UV_LINK_MODE=copy \ - UV_COMPILE_BYTECODE=1 \ - UV_PYTHON_DOWNLOADS=never \ - #UV_PYTHON=python3.12 \ - UV_PROJECT_ENVIRONMENT=/app \ - PYTHONPATH=/app/lib/python3.12/site-packages \ - PATH=/app/bin:$PATH + UV_COMPILE_BYTECODE=1 \ + UV_PYTHON_DOWNLOADS=never \ + #UV_PYTHON=python3.12 \ + UV_PROJECT_ENVIRONMENT=/app \ + PYTHONPATH=/app/lib/python3.12/site-packages \ + PATH=/app/bin:$PATH diff --git a/uv.lock b/uv.lock index 6bce419..5947abe 100644 --- a/uv.lock +++ b/uv.lock @@ -1589,7 +1589,7 @@ wheels = [ [[package]] name = "treetrail-backend" -version = "0.3.0" +version = "0.0.0" source = { editable = "." } dependencies = [ { name = "aiofiles" }, From 23afaa7c82873d76e43bbb004755e1d8e15e61ae Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 03:05:43 +0100 Subject: [PATCH 16/34] CI: build python package --- .forgejo/workflows/test_and_build.yaml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index bbaedf9..ef91b7c 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -17,13 +17,13 @@ jobs: test: runs-on: container container: - image: tiptop:5000/treetrail-backend-ci + image: code.philo.ydns.eu/philorg/treetrail-backend-ci volumes: - "uv_cache:/root/.cache/uv" - "ca-cert:/etc/containers/certs.d" services: treetrail-database: - image: tiptop:5000/treetrail-database + image: code.philo.ydns.eu/philorg/treetrail-database steps: - name: Echo env if: ${{ inputs.verbose }} @@ -58,7 +58,7 @@ jobs: echo "run=$RUN" >> $GITHUB_OUTPUT echo "Run build: $RUN" - - name: Info - version and if the image container should be built + - name: Info - version and test if the git version is clean (then python package and image container should be built) env: VERSION: ${{ steps.version.outputs.version }} RUN: ${{ steps.builder.outputs.run }} @@ -66,6 +66,22 @@ jobs: run: | echo "Version $VERSION, force (manual input): $FORCE, run the build: $RUN" + - name: Set the version in pyproject.toml (workaround for uv not supporting dynamic version) + if: fromJSON(steps.builder.outputs.run) + env: + VERSION: ${{ steps.version.outputs.version }} + run: sed "s/0.0.0/${VERSION}/" -i pyproject.toml + + - name: Build python package + if: fromJSON(steps.builder.outputs.run) + run: uv build --wheel + + - name: Publish Python package (home) + if: fromJSON(steps.builder.outputs.run) + env: + LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} + run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN + - name: Workaround for bug of podman-login if: fromJSON(steps.builder.outputs.run) run: | From a1a499b370eaa5959f364f984f6e7ded8fedf86f Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 03:16:21 +0100 Subject: [PATCH 17/34] Containers: use public registry --- Containerfile | 2 +- Containerfile.ci | 2 +- Containerfile.deps | 2 +- Containerfile.full_copy | 2 +- Containerfile.trixie_python | 2 +- build.yaml | 7 ++++--- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Containerfile b/Containerfile index 07fadf4..3c5b98a 100644 --- a/Containerfile +++ b/Containerfile @@ -1,6 +1,6 @@ # Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-base -f Containerfile.base -FROM tiptop:5000/treetrail-backend-deps +FROM code.philo.ydns.eu/philorg/treetrail-backend-deps ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages ARG APP_VERSION=0.0.0 diff --git a/Containerfile.ci b/Containerfile.ci index 76b217f..160472c 100644 --- a/Containerfile.ci +++ b/Containerfile.ci @@ -1,6 +1,6 @@ # Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-ci -f Containerfile.ci -FROM tiptop:5000/python-ci +FROM code.philo.ydns.eu/philorg/python-ci COPY ./pyproject.toml ./README.md ./uv.lock /_lock/ diff --git a/Containerfile.deps b/Containerfile.deps index c80eeff..f78d8db 100644 --- a/Containerfile.deps +++ b/Containerfile.deps @@ -1,6 +1,6 @@ # Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-deps -f Containerfile.deps -FROM tiptop:5000/trixie_python +FROM code.philo.ydns.eu/philorg/trixie_python COPY ./pyproject.toml ./README.md ./uv.lock /_lock/ diff --git a/Containerfile.full_copy b/Containerfile.full_copy index c725c87..7fb7d55 100644 --- a/Containerfile.full_copy +++ b/Containerfile.full_copy @@ -1,5 +1,5 @@ # Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-full -f Containerfile.full_copy -FROM localhost/trixie_python +FROM code.philo.ydns.eu/philorg/trixie_python ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages ENV PATH=/app/bin:$PATH diff --git a/Containerfile.trixie_python b/Containerfile.trixie_python index 34ae5ff..1adb8f6 100644 --- a/Containerfile.trixie_python +++ b/Containerfile.trixie_python @@ -1,6 +1,6 @@ # Build: podman build -t code.philo.ydns.eu/philorg/trixie_python -f Containerfile.trixie_python -FROM debian:trixie-slim +FROM docker.io/library/debian:trixie-slim RUN < Date: Fri, 6 Dec 2024 03:34:01 +0100 Subject: [PATCH 18/34] Playbook: build and publish ci image --- build.yaml | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/build.yaml b/build.yaml index bb2ad70..b76339d 100644 --- a/build.yaml +++ b/build.yaml @@ -17,9 +17,31 @@ ansible.builtin.debug: var: force_rm + - name: Get the version from git + command: git describe --dirty --tags + register: version + args: + chdir: "{{ playbook_dir }}" + + - name: Build the base CI image + containers.podman.podman_image: + name: treetrail-backend-ci + tag: "{{ version }}" + state: build + path: "{{ playbook_dir }}" + build: + format: oci + force_rm: "{{ force_rm }}" + cache: "{{ cache }}" + file: Containerfile.ci + push: true + push_args: + dest: "{{ repository }}/{{ organisation }}/treetrail-backend-ci" + - name: Build the base image, only with python dependencies containers.podman.podman_image: name: treetrail-backend-deps + tag: "{{ version }}" state: build path: "{{ playbook_dir }}" build: @@ -29,17 +51,12 @@ file: Containerfile.deps push: true push_args: - dest: "{{ repository }}/{{ organisation }}/treetrail-backend-deps" - - - name: Get the version from git - command: git describe --dirty --tags - register: version - args: - chdir: "{{ playbook_dir }}" + dest: "{{ repository }}/{{ organisation }}" - name: Build the backend container image containers.podman.podman_image: - name: "treetrail-backend:{{ version.stdout }}" + name: treetrail-backend + tag: "{{ version.stdout }}" state: build force: true path: "{{ playbook_dir }}" @@ -51,4 +68,4 @@ extra_args: "--build-arg APP_VERSION={{ version.stdout }}" push: true push_args: - dest: "{{ repository }}/{{ organisation }}/treetrail-backend:{{ version.stdout }}" + dest: "{{ repository }}/{{ organisation }}" From 425aaf9dc06732f0ca989d5880416d741bd65346 Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 03:35:08 +0100 Subject: [PATCH 19/34] Playbook: fix build and publish ci image --- build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.yaml b/build.yaml index b76339d..92eaf0d 100644 --- a/build.yaml +++ b/build.yaml @@ -26,7 +26,7 @@ - name: Build the base CI image containers.podman.podman_image: name: treetrail-backend-ci - tag: "{{ version }}" + tag: "{{ version.stdout }}" state: build path: "{{ playbook_dir }}" build: @@ -41,7 +41,7 @@ - name: Build the base image, only with python dependencies containers.podman.podman_image: name: treetrail-backend-deps - tag: "{{ version }}" + tag: "{{ version.stdout }}" state: build path: "{{ playbook_dir }}" build: From 48507cc01c87e2be46c49f73c86343acaf2be4a9 Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 05:03:55 +0100 Subject: [PATCH 20/34] Add database container image build --- Containerfile.database | 4 ++++ build.yaml | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Containerfile.database diff --git a/Containerfile.database b/Containerfile.database new file mode 100644 index 0000000..5145954 --- /dev/null +++ b/Containerfile.database @@ -0,0 +1,4 @@ +FROM docker.io/postgis/postgis:17-3.5-alpine + +ENV POSTGRES_USER treetrail +ENV POSTGRES_PASSWORD treetrail diff --git a/build.yaml b/build.yaml index 92eaf0d..600f96a 100644 --- a/build.yaml +++ b/build.yaml @@ -13,17 +13,37 @@ # file: prod.yaml # name: conf + - name: Build the database image + tags: db + containers.podman.podman_image: + name: treetrail-database + state: build + path: "{{ playbook_dir }}" + build: + format: oci + force_rm: "{{ force_rm }}" + cache: "{{ cache }}" + file: Containerfile.database + push: true + push_args: + dest: "{{ repository }}/{{ organisation }}" + - name: Using the variables ansible.builtin.debug: var: force_rm - name: Get the version from git + tags: + - ci + - deps + - backend command: git describe --dirty --tags register: version args: chdir: "{{ playbook_dir }}" - name: Build the base CI image + tags: ci containers.podman.podman_image: name: treetrail-backend-ci tag: "{{ version.stdout }}" @@ -36,9 +56,10 @@ file: Containerfile.ci push: true push_args: - dest: "{{ repository }}/{{ organisation }}/treetrail-backend-ci" + dest: "{{ repository }}/{{ organisation }}" - name: Build the base image, only with python dependencies + tags: deps containers.podman.podman_image: name: treetrail-backend-deps tag: "{{ version.stdout }}" @@ -54,6 +75,7 @@ dest: "{{ repository }}/{{ organisation }}" - name: Build the backend container image + tags: backend containers.podman.podman_image: name: treetrail-backend tag: "{{ version.stdout }}" From ffd3e99eccd6fab3563c7d2132d21b0f4d6f09ce Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 05:04:39 +0100 Subject: [PATCH 21/34] CI: add Python package build --- .forgejo/workflows/test_and_build.yaml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index ef91b7c..21ff1f2 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -72,16 +72,6 @@ jobs: VERSION: ${{ steps.version.outputs.version }} run: sed "s/0.0.0/${VERSION}/" -i pyproject.toml - - name: Build python package - if: fromJSON(steps.builder.outputs.run) - run: uv build --wheel - - - name: Publish Python package (home) - if: fromJSON(steps.builder.outputs.run) - env: - LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} - run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN - - name: Workaround for bug of podman-login if: fromJSON(steps.builder.outputs.run) run: | @@ -117,3 +107,18 @@ jobs: registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" image: treetrail-backend tags: ${{ steps.version.outputs.version }} + + - name: Install uv + uses: astral-sh/setup-uv@4 + with: + version: "0.5.5" + + - name: Build python package + if: fromJSON(steps.builder.outputs.run) + run: uv build --wheel + + - name: Publish Python package (home) + if: fromJSON(steps.builder.outputs.run) + env: + LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} + run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN From 6601a6ced392a11624d917356aff034b8c625c90 Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 05:08:05 +0100 Subject: [PATCH 22/34] CI: fix add Python package build --- .forgejo/workflows/test_and_build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 21ff1f2..4f51fa9 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -109,7 +109,7 @@ jobs: tags: ${{ steps.version.outputs.version }} - name: Install uv - uses: astral-sh/setup-uv@4 + uses: astral-sh/setup-uv@v4 with: version: "0.5.5" From ed6c70e1a9230f7df0d862d8bd837db28c47c5ee Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 20:07:13 +0100 Subject: [PATCH 23/34] CI: publish container with tag latest along with the version --- .forgejo/workflows/test_and_build.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index 4f51fa9..bd98561 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -100,7 +100,7 @@ jobs: build-args: | APP_VERSION=${{ steps.version.outputs.version }} - - name: Push the image to the registry + - name: Push the image to the registry (version tag) if: fromJSON(steps.builder.outputs.run) uses: actions/push-to-registry@v2 with: @@ -108,6 +108,14 @@ jobs: image: treetrail-backend tags: ${{ steps.version.outputs.version }} + - name: Push the image to the registry (latest tag) + if: fromJSON(steps.builder.outputs.run) + uses: actions/push-to-registry@v2 + with: + registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" + image: treetrail-backend + tags: latest + - name: Install uv uses: astral-sh/setup-uv@v4 with: From 53f935b916ae1a14dc339f18734402f96cd7185c Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 6 Dec 2024 20:14:42 +0100 Subject: [PATCH 24/34] CI: build container with version and latest tags --- .forgejo/workflows/test_and_build.yaml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/test_and_build.yaml index bd98561..5232c2e 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/test_and_build.yaml @@ -94,27 +94,19 @@ jobs: image: treetrail-backend oci: true labels: treetrail-backend - tags: ${{ steps.version.outputs.version }} + tags: latest ${{ steps.version.outputs.version }} containerfiles: | ./Containerfile build-args: | APP_VERSION=${{ steps.version.outputs.version }} - - name: Push the image to the registry (version tag) + - name: Push the image to the registry if: fromJSON(steps.builder.outputs.run) uses: actions/push-to-registry@v2 with: registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" image: treetrail-backend - tags: ${{ steps.version.outputs.version }} - - - name: Push the image to the registry (latest tag) - if: fromJSON(steps.builder.outputs.run) - uses: actions/push-to-registry@v2 - with: - registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" - image: treetrail-backend - tags: latest + tags: latest ${{ steps.version.outputs.version }} - name: Install uv uses: astral-sh/setup-uv@v4 From d0c7e4614abd8f124a2413411d0b10a15153048e Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 8 Dec 2024 02:23:30 +0100 Subject: [PATCH 25/34] Fix loose config with environment variables --- src/treetrail/config.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/treetrail/config.py b/src/treetrail/config.py index 2bdfa4e..f095a72 100644 --- a/src/treetrail/config.py +++ b/src/treetrail/config.py @@ -64,14 +64,8 @@ def get_cache_dir() -> Path: return Path(conf.storage.root_cache_path) -class MyBaseSettings(BaseSettings): - model_config = SettingsConfigDict( - env_prefix="treetrail_", - env_nested_delimiter="_", - ) - - -class DB(MyBaseSettings): +class DB(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_db_") # uri: str host: str = "treetrail-database" port: int = 5432 @@ -91,16 +85,19 @@ class DB(MyBaseSettings): return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}" -class App(MyBaseSettings): +class App(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_app_") title: str = "Tree Trail" -class Storage(MyBaseSettings): +class Storage(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_storage_") root_attachment_path: str = "/var/lib/treetrail/attachments" root_cache_path: str = "/var/lib/treetrail/cache" -class Tiles(MyBaseSettings): +class Tiles(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_tiles_") baseDir: str = "/var/lib/treetrail/mbtiles_files" useRequestUrl: bool = True spriteBaseDir: str = "/var/lib/treetrail/mbtiles_sprites" @@ -109,7 +106,8 @@ class Tiles(MyBaseSettings): osmBaseDir: str = "/var/lib/treetrail/osm" -class Map(MyBaseSettings): +class Map(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_map_") zoom: float = 14.0 pitch: float = 0.0 lat: float = 45.8822 @@ -118,12 +116,14 @@ class Map(MyBaseSettings): background: str = "OpenFreeMap" -class Geo(MyBaseSettings): +class Geo(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_geo_") simplify_geom_factor: int = 10000000 simplify_preserve_topology: bool = False -class Security(MyBaseSettings): +class Security(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_security_") """ JWT security configuration """ @@ -133,12 +133,14 @@ class Security(MyBaseSettings): access_token_expire_minutes: float = 30 -class ExternalMapStyle(MyBaseSettings): +class ExternalMapStyle(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_external_map_style_") name: str url: str -class Config(MyBaseSettings): +class Config(BaseSettings): + model_config = SettingsConfigDict(env_prefix="treetrail_") @classmethod def settings_customise_sources( @@ -161,7 +163,7 @@ class Config(MyBaseSettings): tiles: Tiles = Tiles() security: Security = Security() geo: Geo = Geo() - version: str = '-' + version: str = "-" db: DB = DB() base_href: str = "/treetrail" From 727698527ec02bdc33bd10f3abde4a3d231e3f6a Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 8 Dec 2024 02:46:31 +0100 Subject: [PATCH 26/34] CI: split test and build workflows, run build only on git push tag --- .../{test_and_build.yaml => build.yaml} | 7 ++-- .forgejo/workflows/test.yaml | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) rename .forgejo/workflows/{test_and_build.yaml => build.yaml} (96%) create mode 100644 .forgejo/workflows/test.yaml diff --git a/.forgejo/workflows/test_and_build.yaml b/.forgejo/workflows/build.yaml similarity index 96% rename from .forgejo/workflows/test_and_build.yaml rename to .forgejo/workflows/build.yaml index 5232c2e..11544bb 100644 --- a/.forgejo/workflows/test_and_build.yaml +++ b/.forgejo/workflows/build.yaml @@ -1,5 +1,7 @@ on: push: + tags: + - "**" workflow_dispatch: inputs: verbose: @@ -7,11 +9,6 @@ on: required: false default: false type: boolean - build: - description: "Build container" - required: true - default: false - type: boolean jobs: test: diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml new file mode 100644 index 0000000..096dc40 --- /dev/null +++ b/.forgejo/workflows/test.yaml @@ -0,0 +1,34 @@ +on: + push: + workflow_dispatch: + inputs: + verbose: + description: "Verbose" + required: false + default: false + type: boolean + +jobs: + test: + runs-on: container + container: + image: code.philo.ydns.eu/philorg/treetrail-backend-ci + volumes: + - "uv_cache:/root/.cache/uv" + - "ca-cert:/etc/containers/certs.d" + services: + treetrail-database: + image: code.philo.ydns.eu/philorg/treetrail-database + steps: + - name: Echo env + if: ${{ inputs.verbose }} + run: | + echo '${{ toJSON(env) }}' + + - uses: actions/checkout@v4 + + - name: Install app with 'uv pip install' + run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . + + - name: Run tests (API call) + run: pytest -s tests/basic.py From 4a54a815a0daec0d4625d50f108046a06a43aa1b Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 8 Dec 2024 05:32:00 +0100 Subject: [PATCH 27/34] Config: set default db host to localhost --- src/treetrail/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/treetrail/config.py b/src/treetrail/config.py index f095a72..2fd0934 100644 --- a/src/treetrail/config.py +++ b/src/treetrail/config.py @@ -67,7 +67,7 @@ def get_cache_dir() -> Path: class DB(BaseSettings): model_config = SettingsConfigDict(env_prefix="treetrail_db_") # uri: str - host: str = "treetrail-database" + host: str = "localhost" port: int = 5432 user: str = "treetrail" db: str = "treetrail" From 8bfb410ee13fc4fcb38f7724c00e3bf1aea5a348 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 8 Dec 2024 05:57:04 +0100 Subject: [PATCH 28/34] CI: set db host for tests --- .forgejo/workflows/build.yaml | 2 +- .forgejo/workflows/test.yaml | 2 +- Containerfile | 2 +- src/treetrail/database.py | 7 ++++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 11544bb..2852887 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -33,7 +33,7 @@ jobs: run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - name: Run tests (API call) - run: pytest -s tests/basic.py + run: TREETRAIL_DB_HOST=treetrail-database pytest -s tests/basic.py build: runs-on: container diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml index 096dc40..fb41758 100644 --- a/.forgejo/workflows/test.yaml +++ b/.forgejo/workflows/test.yaml @@ -31,4 +31,4 @@ jobs: run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - name: Run tests (API call) - run: pytest -s tests/basic.py + run: TREETRAIL_DB_HOST=treetrail-database pytest -s tests/basic.py diff --git a/Containerfile b/Containerfile index 3c5b98a..ee769f8 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend-base -f Containerfile.base +# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend -f Containerfile FROM code.philo.ydns.eu/philorg/treetrail-backend-deps diff --git a/src/treetrail/database.py b/src/treetrail/database.py index 4433b58..94e15bf 100644 --- a/src/treetrail/database.py +++ b/src/treetrail/database.py @@ -14,7 +14,7 @@ from treetrail.config import conf logger = logging.getLogger(__name__) -CREATE_DB_TIMEOUT = 30 +CREATE_DB_TIMEOUT = 10 engine = create_async_engine( conf.db.get_sqla_url(), @@ -33,7 +33,7 @@ async def create_db(drop=False): await conn.run_sync(SQLModel.metadata.drop_all) await conn.run_sync(SQLModel.metadata.create_all) - logger.debug(f'Connect to database with config: {conf.db}') + logger.debug(f"Connect to database with config: {conf.db}") while attempts > 0: try: await try_once() @@ -68,6 +68,7 @@ async def populate_init_db(): """Populate the database for a fresh install""" from sqlalchemy import text from treetrail.security import create_user, add_role, add_user_role + logger.info("Populating initial database") user = await create_user(username="admin", password="admin") @@ -76,7 +77,7 @@ async def populate_init_db(): async with db_session() as session: for initial in initials: await session.execute(text(initial)) - logger.debug(f'Added map style {initial}') + logger.debug(f"Added map style {initial}") await session.commit() From 3745cfe3f07cb02895ec4a86d192751bbf408989 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 8 Dec 2024 06:12:18 +0100 Subject: [PATCH 29/34] Add kube yaml --- treetrail-kube.yaml | 116 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 treetrail-kube.yaml diff --git a/treetrail-kube.yaml b/treetrail-kube.yaml new file mode 100644 index 0000000..2b51de3 --- /dev/null +++ b/treetrail-kube.yaml @@ -0,0 +1,116 @@ +apiVersion: v1 +kind: Service +metadata: + name: treetrail + labels: + app: treetrail +spec: + ports: + - name: "80" + nodePort: 31080 + port: 80 + targetPort: 80 + - name: "4532" + nodePort: 31432 + port: 4532 + targetPort: 4532 + selector: + app: treetrail + type: NodePort +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: treetrail + name: treetrail +spec: + containers: + - image: code.philo.ydns.eu/philorg/treetrail-frontend:latest + args: + - nginx + - -g + - daemon off; + name: treetrail-frontend + ports: + - containerPort: 80 + hostPort: 8080 + - image: code.philo.ydns.eu/philorg/treetrail-backend:latest + name: treetrail-backend + - image: code.philo.ydns.eu/philorg/treetrail-database:latest + args: + - postgres + name: treetrail-database + ports: + - containerPort: 4532 + hostPort: 15432 + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: treetrail-pgdata + volumes: + - name: treetrail-pgdata + persistentVolumeClaim: + claimName: treetrail-pgdata-pvc + restartPolicy: Always +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: treetrail-pgdata-pv + labels: + type: local + app: postgres +spec: + storageClassName: manual + capacity: + storage: 2Gi + accessModes: + - ReadWriteMany + hostPath: + path: /data/postgresql +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: treetrail-pgdata-pvc +spec: + storageClassName: manual + accessModes: + - ReadWriteMany + resources: + requests: + storage: 2Gi +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: treetrail + namespace: default + #annotations: + # kubernetes.io/ingress.class: traefik + # #traefik.ingress.kubernetes.io/router.middlewares: default-strip-prefix@kubernetescrd +spec: + rules: + - http: + paths: + - path: /treetrail + pathType: Prefix + backend: + service: + name: treetrail-frontend + port: + number: 80 + - path: /treetrail/v1 + pathType: Prefix + backend: + service: + name: treetrail-backend + port: + number: 8081 + - path: /treetrail/plantekey + pathType: Prefix + backend: + service: + name: treetrail-backend + port: + number: 8081 From c7deb34bae2d2f76b54dfd3135987a817aab5045 Mon Sep 17 00:00:00 2001 From: phil Date: Sat, 15 Mar 2025 16:30:07 +0100 Subject: [PATCH 30/34] Add annotations to kube --- treetrail-kube.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/treetrail-kube.yaml b/treetrail-kube.yaml index 2b51de3..a245ff3 100644 --- a/treetrail-kube.yaml +++ b/treetrail-kube.yaml @@ -2,6 +2,12 @@ apiVersion: v1 kind: Service metadata: name: treetrail + annotations: + io.kubernetes.cri-o.SandboxID/gisaf-backend: treetrail-cri-o + io.kubernetes.cri-o.SandboxID/gisaf-database: treetrail-cri-o + io.kubernetes.cri-o.SandboxID/gisaf-frontend: treetrail-cri-o + io.kubernetes.cri-o.SandboxID/gisaf-redis: treetrail-cri-o + io.podman.annotations.infra.name: treetrail-infra labels: app: treetrail spec: From ea7e3087cd8556811d205d722845d50b0a1d1d38 Mon Sep 17 00:00:00 2001 From: phil Date: Sat, 15 Mar 2025 17:43:07 +0100 Subject: [PATCH 31/34] Use dynamic versioning --- .forgejo/workflows/build.yaml | 66 +++++++++----------- pyproject.toml | 109 +++++++++++++++++----------------- src/treetrail/__init__.py | 9 ++- src/treetrail/utils.py | 53 ++++++----------- uv.lock | 70 +++++++++++++++------- 5 files changed, 157 insertions(+), 150 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index 2852887..fd6e189 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -18,9 +18,11 @@ jobs: volumes: - "uv_cache:/root/.cache/uv" - "ca-cert:/etc/containers/certs.d" + services: treetrail-database: image: code.philo.ydns.eu/philorg/treetrail-database + steps: - name: Echo env if: ${{ inputs.verbose }} @@ -43,40 +45,34 @@ jobs: with: fetch-depth: 0 - - name: Get the version from git - id: version - run: echo "version=$(git describe --dirty --tags)" >> $GITHUB_OUTPUT + - name: Install the latest version of uv + uses: astral-sh/setup-uv@v4 + with: + version: "0.6.6" - - name: Check if the container should be built - id: builder - env: - RUN: ${{ toJSON(inputs.build || !contains(steps.version.outputs.version, '-')) }} - run: | - echo "run=$RUN" >> $GITHUB_OUTPUT - echo "Run build: $RUN" + - name: Install + run: uv sync - - name: Info - version and test if the git version is clean (then python package and image container should be built) - env: - VERSION: ${{ steps.version.outputs.version }} - RUN: ${{ steps.builder.outputs.run }} - FORCE: ${{ toJSON(inputs.build) }} - run: | - echo "Version $VERSION, force (manual input): $FORCE, run the build: $RUN" + - name: Get version + run: echo "VERSION=$(.venv/bin/dunamai from any --style semver)" >> $GITHUB_ENV - - name: Set the version in pyproject.toml (workaround for uv not supporting dynamic version) - if: fromJSON(steps.builder.outputs.run) - env: - VERSION: ${{ steps.version.outputs.version }} - run: sed "s/0.0.0/${VERSION}/" -i pyproject.toml + - name: Version + run: echo $VERSION + + - name: Get distance from tag + run: echo "DISTANCE=$(.venv/bin/dunamai from any --format '{distance}')" >> $GITHUB_ENV + + - name: Distance + run: echo $DISTANCE - name: Workaround for bug of podman-login - if: fromJSON(steps.builder.outputs.run) + if: env.DISTANCE == '0' run: | mkdir -p $HOME/.docker echo "{ \"auths\": {} }" > $HOME/.docker/config.json - name: Log in to the container registry (with another workaround) - if: fromJSON(steps.builder.outputs.run) + if: env.DISTANCE == '0' uses: actions/podman-login@v1 with: registry: ${{ vars.REGISTRY }} @@ -85,37 +81,31 @@ jobs: auth_file_path: /tmp/auth.json - name: Build the container image - if: fromJSON(steps.builder.outputs.run) + if: env.DISTANCE == '0' uses: actions/buildah-build@v1 with: image: treetrail-backend oci: true labels: treetrail-backend - tags: latest ${{ steps.version.outputs.version }} + tags: latest env.VERSION containerfiles: | ./Containerfile - build-args: | - APP_VERSION=${{ steps.version.outputs.version }} - name: Push the image to the registry - if: fromJSON(steps.builder.outputs.run) + if: env.DISTANCE == '0' uses: actions/push-to-registry@v2 with: registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" image: treetrail-backend - tags: latest ${{ steps.version.outputs.version }} + tags: latest env.VERSION - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - version: "0.5.5" - - - name: Build python package - if: fromJSON(steps.builder.outputs.run) + - name: Build wheel + if: env.DISTANCE == '0' run: uv build --wheel - name: Publish Python package (home) - if: fromJSON(steps.builder.outputs.run) + if: env.DISTANCE == '0' env: LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN + continue-on-error: true diff --git a/pyproject.toml b/pyproject.toml index 6cf4e5a..3d9b52d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,77 +1,80 @@ [project] name = "treetrail-backend" -version = "0.0.0" -#dynamic = ["version"] +dynamic = ["version"] description = "A fun and pedagogic tool to discover the trails and trees around" -authors = [ - { name = "Philippe May", email = "phil.treetrail@philome.mooo.com" } -] +authors = [{ name = "Philippe May", email = "phil.treetrail@philome.mooo.com" }] dependencies = [ - "aiofiles", - "aiohttp-client-cache", - "aiosqlite", - "asyncpg", - "fastapi", - "geoalchemy2", - "geopandas", - "httptools>=0.6.1", - "orjson", - "pandas", - "passlib[bcrypt]", - "pillow", - "psycopg2-binary", - "pyarrow", - "pydantic-settings", - "python-jose[cryptography]", - "python-multipart", - "requests", - "sqlalchemy[asyncio]", - "sqlmodel", - "uvicorn[standard]", - "uvloop", + "aiofiles", + "aiohttp-client-cache", + "aiosqlite", + "asyncpg", + "fastapi", + "geoalchemy2", + "geopandas", + "httptools>=0.6.1", + "orjson", + "pandas", + "passlib[bcrypt]", + "pillow", + "psycopg2-binary", + "pyarrow>=19.0.1", + "pydantic-settings", + "python-jose[cryptography]", + "python-multipart", + "requests", + "sqlalchemy[asyncio]", + "sqlmodel", + "uvicorn[standard]", + "uvloop", ] requires-python = ">=3.11" readme = "README.md" -license = {text = "MIT"} +license = { text = "MIT" } classifiers = [ - "Development Status :: 3 - Alpha", - "Framework :: FastAPI", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "License :: OSI Approved :: GNU General Public License (GPL)", - "Programming Language :: Python :: 3", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX", - "Programming Language :: Python", + "Development Status :: 3 - Alpha", + "Framework :: FastAPI", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Programming Language :: Python :: 3", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", + "Programming Language :: Python", ] #[project.scripts] #treetrail-backend = "treetrail_backend:main" +[dependency-groups] +dev = ["dunamai>=1.23.0", "ipdb>=0.13.13"] + [build-system] -requires = ["hatchling"] +requires = ["hatchling", "uv-dynamic-versioning"] build-backend = "hatchling.build" +[tool.hatch.version] +source = "uv-dynamic-versioning" + [tool.hatch.build.targets.wheel] packages = ["src/treetrail"] +[tool.uv-dynamic-versioning] +style = "semver" + [tool.uv] package = true dev-dependencies = [ - "httpx", - "ipdb", - "pandas-stubs", - "pytest", - "types-Pillow", - "types-PyYAML", - "types-aiofiles", - "types-passlib", - "types-python-jose", - "types-requests", + "httpx", + "ipdb", + "pandas-stubs", + "pytest", + "types-Pillow", + "types-PyYAML", + "types-aiofiles", + "types-passlib", + "types-python-jose", + "types-requests", ] -#[tool.pdm.version] -#source = "scm" -#write_to = "treetrail/_version.py" -#write_template = "__version__ = '{}'" -# +[tool.black] +line-length = 98 diff --git a/src/treetrail/__init__.py b/src/treetrail/__init__.py index 56ead07..95b89f2 100644 --- a/src/treetrail/__init__.py +++ b/src/treetrail/__init__.py @@ -1,3 +1,8 @@ -from treetrail.utils import get_version +import importlib.metadata -__version__ = get_version() \ No newline at end of file +try: + from dunamai import Version, Style + + __version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True) +except ImportError: + __version__ = importlib.metadata.version("treetrail-backend") diff --git a/src/treetrail/utils.py b/src/treetrail/utils.py index 78dc42e..50efc95 100644 --- a/src/treetrail/utils.py +++ b/src/treetrail/utils.py @@ -7,19 +7,19 @@ import pandas as pd from sqlalchemy.ext.declarative import DeclarativeMeta from sqlalchemy.engine.row import Row from sqlalchemy.sql.selectable import Select -import geopandas as gpd # type: ignore +import geopandas as gpd # type: ignore from treetrail.config import conf logger = logging.getLogger(__name__) + class AlchemyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj.__class__, DeclarativeMeta): # an SQLAlchemy class fields = {} - for field in [x for x in dir(obj) - if not x.startswith('_') and x != 'metadata']: + for field in [x for x in dir(obj) if not x.startswith("_") and x != "metadata"]: data = obj.__getattribute__(field) try: # this will fail on non-encodable values, like other classes @@ -50,24 +50,30 @@ def get_attachment_root(type: str): def get_attachment_tree_root(): - return get_attachment_root('tree') + return get_attachment_root("tree") def get_attachment_trail_root(): - return get_attachment_root('trail') + return get_attachment_root("trail") def get_attachment_poi_root(): - return get_attachment_root('poi') + return get_attachment_root("poi") def pandas_query(session, query): return pd.read_sql_query(query, session.connection()) -def geopandas_query(session, query: Select, model, *, - # simplify_tolerance: float|None=None, - crs=None, cast=True, - ): + +def geopandas_query( + session, + query: Select, + model, + *, + # simplify_tolerance: float|None=None, + crs=None, + cast=True, +): ## XXX: I could not get the add_columns work without creating a subquery, ## so moving the simplification to geopandas - see in _get_df # if simplify_tolerance is not None: @@ -78,34 +84,11 @@ def geopandas_query(session, query: Select, model, *, # query = query.add_columns(new_column) return gpd.GeoDataFrame.from_postgis(query, session.connection(), crs=crs) + def mkdir(dir: Path | str) -> Path: path = Path(dir) if not path.is_dir(): - logger.info(f'Create directory {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 diff --git a/uv.lock b/uv.lock index 5947abe..20f6558 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 1 requires-python = ">=3.11" resolution-markers = [ "python_full_version < '3.12'", @@ -342,7 +343,7 @@ name = "click" version = "8.1.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } wheels = [ @@ -396,6 +397,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, ] +[[package]] +name = "dunamai" +version = "1.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/4e/a5c8c337a1d9ac0384298ade02d322741fb5998041a5ea74d1cd2a4a1d47/dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4", size = 44681 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/4c/963169386309fec4f96fd61210ac0a0666887d0fb0a50205395674d20b71/dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041", size = 26342 }, +] + [[package]] name = "ecdsa" version = "0.19.0" @@ -1109,6 +1122,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, + { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, ] [[package]] @@ -1131,27 +1145,37 @@ wheels = [ [[package]] name = "pyarrow" -version = "17.0.0" +version = "19.0.1" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/27/4e/ea6d43f324169f8aec0e57569443a38bab4b398d09769ca64f7b4d467de3/pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28", size = 1112479 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/09/a9046344212690f0632b9c709f9bf18506522feb333c894d0de81d62341a/pyarrow-19.0.1.tar.gz", hash = "sha256:3bf266b485df66a400f282ac0b6d1b500b9d2ae73314a153dbe97d6d5cc8a99e", size = 1129437 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/46/ce89f87c2936f5bb9d879473b9663ce7a4b1f4359acc2f0eb39865eaa1af/pyarrow-17.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977", size = 29028748 }, - { url = "https://files.pythonhosted.org/packages/8d/8e/ce2e9b2146de422f6638333c01903140e9ada244a2a477918a368306c64c/pyarrow-17.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3", size = 27190965 }, - { url = "https://files.pythonhosted.org/packages/3b/c8/5675719570eb1acd809481c6d64e2136ffb340bc387f4ca62dce79516cea/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15", size = 39269081 }, - { url = "https://files.pythonhosted.org/packages/5e/78/3931194f16ab681ebb87ad252e7b8d2c8b23dad49706cadc865dff4a1dd3/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597", size = 39864921 }, - { url = "https://files.pythonhosted.org/packages/d8/81/69b6606093363f55a2a574c018901c40952d4e902e670656d18213c71ad7/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420", size = 38740798 }, - { url = "https://files.pythonhosted.org/packages/4c/21/9ca93b84b92ef927814cb7ba37f0774a484c849d58f0b692b16af8eebcfb/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4", size = 39871877 }, - { url = "https://files.pythonhosted.org/packages/30/d1/63a7c248432c71c7d3ee803e706590a0b81ce1a8d2b2ae49677774b813bb/pyarrow-17.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03", size = 25151089 }, - { url = "https://files.pythonhosted.org/packages/d4/62/ce6ac1275a432b4a27c55fe96c58147f111d8ba1ad800a112d31859fae2f/pyarrow-17.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22", size = 29019418 }, - { url = "https://files.pythonhosted.org/packages/8e/0a/dbd0c134e7a0c30bea439675cc120012337202e5fac7163ba839aa3691d2/pyarrow-17.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053", size = 27152197 }, - { url = "https://files.pythonhosted.org/packages/cb/05/3f4a16498349db79090767620d6dc23c1ec0c658a668d61d76b87706c65d/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a", size = 39263026 }, - { url = "https://files.pythonhosted.org/packages/c2/0c/ea2107236740be8fa0e0d4a293a095c9f43546a2465bb7df34eee9126b09/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc", size = 39880798 }, - { url = "https://files.pythonhosted.org/packages/f6/b0/b9164a8bc495083c10c281cc65064553ec87b7537d6f742a89d5953a2a3e/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a", size = 38715172 }, - { url = "https://files.pythonhosted.org/packages/f1/c4/9625418a1413005e486c006e56675334929fad864347c5ae7c1b2e7fe639/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b", size = 39874508 }, - { url = "https://files.pythonhosted.org/packages/ae/49/baafe2a964f663413be3bd1cf5c45ed98c5e42e804e2328e18f4570027c1/pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7", size = 25099235 }, + { url = "https://files.pythonhosted.org/packages/a0/55/f1a8d838ec07fe3ca53edbe76f782df7b9aafd4417080eebf0b42aab0c52/pyarrow-19.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:cc55d71898ea30dc95900297d191377caba257612f384207fe9f8293b5850f90", size = 30713987 }, + { url = "https://files.pythonhosted.org/packages/13/12/428861540bb54c98a140ae858a11f71d041ef9e501e6b7eb965ca7909505/pyarrow-19.0.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:7a544ec12de66769612b2d6988c36adc96fb9767ecc8ee0a4d270b10b1c51e00", size = 32135613 }, + { url = "https://files.pythonhosted.org/packages/2f/8a/23d7cc5ae2066c6c736bce1db8ea7bc9ac3ef97ac7e1c1667706c764d2d9/pyarrow-19.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0148bb4fc158bfbc3d6dfe5001d93ebeed253793fff4435167f6ce1dc4bddeae", size = 41149147 }, + { url = "https://files.pythonhosted.org/packages/a2/7a/845d151bb81a892dfb368bf11db584cf8b216963ccce40a5cf50a2492a18/pyarrow-19.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f24faab6ed18f216a37870d8c5623f9c044566d75ec586ef884e13a02a9d62c5", size = 42178045 }, + { url = "https://files.pythonhosted.org/packages/a7/31/e7282d79a70816132cf6cae7e378adfccce9ae10352d21c2fecf9d9756dd/pyarrow-19.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:4982f8e2b7afd6dae8608d70ba5bd91699077323f812a0448d8b7abdff6cb5d3", size = 40532998 }, + { url = "https://files.pythonhosted.org/packages/b8/82/20f3c290d6e705e2ee9c1fa1d5a0869365ee477e1788073d8b548da8b64c/pyarrow-19.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:49a3aecb62c1be1d822f8bf629226d4a96418228a42f5b40835c1f10d42e4db6", size = 42084055 }, + { url = "https://files.pythonhosted.org/packages/ff/77/e62aebd343238863f2c9f080ad2ef6ace25c919c6ab383436b5b81cbeef7/pyarrow-19.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:008a4009efdb4ea3d2e18f05cd31f9d43c388aad29c636112c2966605ba33466", size = 25283133 }, + { url = "https://files.pythonhosted.org/packages/78/b4/94e828704b050e723f67d67c3535cf7076c7432cd4cf046e4bb3b96a9c9d/pyarrow-19.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:80b2ad2b193e7d19e81008a96e313fbd53157945c7be9ac65f44f8937a55427b", size = 30670749 }, + { url = "https://files.pythonhosted.org/packages/7e/3b/4692965e04bb1df55e2c314c4296f1eb12b4f3052d4cf43d29e076aedf66/pyarrow-19.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:ee8dec072569f43835932a3b10c55973593abc00936c202707a4ad06af7cb294", size = 32128007 }, + { url = "https://files.pythonhosted.org/packages/22/f7/2239af706252c6582a5635c35caa17cb4d401cd74a87821ef702e3888957/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d5d1ec7ec5324b98887bdc006f4d2ce534e10e60f7ad995e7875ffa0ff9cb14", size = 41144566 }, + { url = "https://files.pythonhosted.org/packages/fb/e3/c9661b2b2849cfefddd9fd65b64e093594b231b472de08ff658f76c732b2/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ad4c0eb4e2a9aeb990af6c09e6fa0b195c8c0e7b272ecc8d4d2b6574809d34", size = 42202991 }, + { url = "https://files.pythonhosted.org/packages/fe/4f/a2c0ed309167ef436674782dfee4a124570ba64299c551e38d3fdaf0a17b/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:d383591f3dcbe545f6cc62daaef9c7cdfe0dff0fb9e1c8121101cabe9098cfa6", size = 40507986 }, + { url = "https://files.pythonhosted.org/packages/27/2e/29bb28a7102a6f71026a9d70d1d61df926887e36ec797f2e6acfd2dd3867/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b4c4156a625f1e35d6c0b2132635a237708944eb41df5fbe7d50f20d20c17832", size = 42087026 }, + { url = "https://files.pythonhosted.org/packages/16/33/2a67c0f783251106aeeee516f4806161e7b481f7d744d0d643d2f30230a5/pyarrow-19.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:5bd1618ae5e5476b7654c7b55a6364ae87686d4724538c24185bbb2952679960", size = 25250108 }, + { url = "https://files.pythonhosted.org/packages/2b/8d/275c58d4b00781bd36579501a259eacc5c6dfb369be4ddeb672ceb551d2d/pyarrow-19.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e45274b20e524ae5c39d7fc1ca2aa923aab494776d2d4b316b49ec7572ca324c", size = 30653552 }, + { url = "https://files.pythonhosted.org/packages/a0/9e/e6aca5cc4ef0c7aec5f8db93feb0bde08dbad8c56b9014216205d271101b/pyarrow-19.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:d9dedeaf19097a143ed6da37f04f4051aba353c95ef507764d344229b2b740ae", size = 32103413 }, + { url = "https://files.pythonhosted.org/packages/6a/fa/a7033f66e5d4f1308c7eb0dfcd2ccd70f881724eb6fd1776657fdf65458f/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ebfb5171bb5f4a52319344ebbbecc731af3f021e49318c74f33d520d31ae0c4", size = 41134869 }, + { url = "https://files.pythonhosted.org/packages/2d/92/34d2569be8e7abdc9d145c98dc410db0071ac579b92ebc30da35f500d630/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a21d39fbdb948857f67eacb5bbaaf36802de044ec36fbef7a1c8f0dd3a4ab2", size = 42192626 }, + { url = "https://files.pythonhosted.org/packages/0a/1f/80c617b1084fc833804dc3309aa9d8daacd46f9ec8d736df733f15aebe2c/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:99bc1bec6d234359743b01e70d4310d0ab240c3d6b0da7e2a93663b0158616f6", size = 40496708 }, + { url = "https://files.pythonhosted.org/packages/e6/90/83698fcecf939a611c8d9a78e38e7fed7792dcc4317e29e72cf8135526fb/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1b93ef2c93e77c442c979b0d596af45e4665d8b96da598db145b0fec014b9136", size = 42075728 }, + { url = "https://files.pythonhosted.org/packages/40/49/2325f5c9e7a1c125c01ba0c509d400b152c972a47958768e4e35e04d13d8/pyarrow-19.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:d9d46e06846a41ba906ab25302cf0fd522f81aa2a85a71021826f34639ad31ef", size = 25242568 }, + { url = "https://files.pythonhosted.org/packages/3f/72/135088d995a759d4d916ec4824cb19e066585b4909ebad4ab196177aa825/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c0fe3dbbf054a00d1f162fda94ce236a899ca01123a798c561ba307ca38af5f0", size = 30702371 }, + { url = "https://files.pythonhosted.org/packages/2e/01/00beeebd33d6bac701f20816a29d2018eba463616bbc07397fdf99ac4ce3/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:96606c3ba57944d128e8a8399da4812f56c7f61de8c647e3470b417f795d0ef9", size = 32116046 }, + { url = "https://files.pythonhosted.org/packages/1f/c9/23b1ea718dfe967cbd986d16cf2a31fe59d015874258baae16d7ea0ccabc/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f04d49a6b64cf24719c080b3c2029a3a5b16417fd5fd7c4041f94233af732f3", size = 41091183 }, + { url = "https://files.pythonhosted.org/packages/3a/d4/b4a3aa781a2c715520aa8ab4fe2e7fa49d33a1d4e71c8fc6ab7b5de7a3f8/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a9137cf7e1640dce4c190551ee69d478f7121b5c6f323553b319cac936395f6", size = 42171896 }, + { url = "https://files.pythonhosted.org/packages/23/1b/716d4cd5a3cbc387c6e6745d2704c4b46654ba2668260d25c402626c5ddb/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:7c1bca1897c28013db5e4c83944a2ab53231f541b9e0c3f4791206d0c0de389a", size = 40464851 }, + { url = "https://files.pythonhosted.org/packages/ed/bd/54907846383dcc7ee28772d7e646f6c34276a17da740002a5cefe90f04f7/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:58d9397b2e273ef76264b45531e9d552d8ec8a6688b7390b5be44c02a37aade8", size = 42085744 }, ] [[package]] @@ -1589,7 +1613,6 @@ wheels = [ [[package]] name = "treetrail-backend" -version = "0.0.0" source = { editable = "." } dependencies = [ { name = "aiofiles" }, @@ -1618,6 +1641,7 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "dunamai" }, { name = "httpx" }, { name = "ipdb" }, { name = "pandas-stubs" }, @@ -1645,7 +1669,7 @@ requires-dist = [ { name = "passlib", extras = ["bcrypt"] }, { name = "pillow" }, { name = "psycopg2-binary" }, - { name = "pyarrow" }, + { name = "pyarrow", specifier = ">=19.0.1" }, { name = "pydantic-settings" }, { name = "python-jose", extras = ["cryptography"] }, { name = "python-multipart" }, @@ -1658,8 +1682,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "dunamai", specifier = ">=1.23.0" }, { name = "httpx" }, { name = "ipdb" }, + { name = "ipdb", specifier = ">=0.13.13" }, { name = "pandas-stubs" }, { name = "pytest" }, { name = "types-aiofiles" }, From 7105edecd176f3ff559012df751b3178fd59df61 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 16 Mar 2025 14:14:39 +0100 Subject: [PATCH 32/34] CI: build container from plain Python image --- .containerignore | 1 - Containerfile | 21 ++++++--------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.containerignore b/.containerignore index 5724d4f..15697f7 100644 --- a/.containerignore +++ b/.containerignore @@ -1,5 +1,4 @@ .venv -.git dist .pytest_cache .forgejo diff --git a/Containerfile b/Containerfile index ee769f8..ff60531 100644 --- a/Containerfile +++ b/Containerfile @@ -1,22 +1,13 @@ -# Build: podman build -t code.philo.ydns.eu/philorg/treetrail-backend -f Containerfile +FROM docker.io/library/python:latest -FROM code.philo.ydns.eu/philorg/treetrail-backend-deps +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ -ENV PYTHONPATH $UV_PROJECT_ENVIRONMENT/lib/python3.12/site-packages -ARG APP_VERSION=0.0.0 +COPY . /app -COPY . /src +# Sync the project into a new environment, using the frozen lockfile +WORKDIR /app -#RUN --mount=type=cache,target=/root/.cache \ -# cd /src && \ -# uv sync --locked --no-dev --no-editable - -RUN uv pip install \ - --python=$UV_PROJECT_ENVIRONMENT \ - --no-deps \ - /src - -RUN echo $APP_VERSION > /app/version.txt +RUN uv pip install --system . CMD [ \ "uvicorn", "treetrail.application:app", \ From ec4cc9a58a1ad6c22dbc07768a31760d8d53079b Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 16 Mar 2025 14:21:50 +0100 Subject: [PATCH 33/34] CI: fix container version --- .forgejo/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml index fd6e189..de939bf 100644 --- a/.forgejo/workflows/build.yaml +++ b/.forgejo/workflows/build.yaml @@ -87,7 +87,7 @@ jobs: image: treetrail-backend oci: true labels: treetrail-backend - tags: latest env.VERSION + tags: "latest ${{ env.VERSION }}" containerfiles: | ./Containerfile @@ -97,7 +97,7 @@ jobs: with: registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" image: treetrail-backend - tags: latest env.VERSION + tags: "latest ${{ env.VERSION }}" - name: Build wheel if: env.DISTANCE == '0' From 7d0d6011d77b7d5701dc4192babdd73c4754c6df Mon Sep 17 00:00:00 2001 From: phil Date: Fri, 27 Jun 2025 18:06:27 +0200 Subject: [PATCH 34/34] CI: switch to Woodpecker --- .forgejo/workflows/build.yaml | 111 ---------------------------------- .forgejo/workflows/test.yaml | 34 ----------- .woodpecker/build.yaml | 70 +++++++++++++++++++++ .woodpecker/test.yaml | 21 +++++++ README.md | 5 +- src/treetrail/__init__.py | 4 +- tests/__init__.py | 0 7 files changed, 97 insertions(+), 148 deletions(-) delete mode 100644 .forgejo/workflows/build.yaml delete mode 100644 .forgejo/workflows/test.yaml create mode 100644 .woodpecker/build.yaml create mode 100644 .woodpecker/test.yaml delete mode 100644 tests/__init__.py diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml deleted file mode 100644 index de939bf..0000000 --- a/.forgejo/workflows/build.yaml +++ /dev/null @@ -1,111 +0,0 @@ -on: - push: - tags: - - "**" - workflow_dispatch: - inputs: - verbose: - description: "Verbose" - required: false - default: false - type: boolean - -jobs: - test: - runs-on: container - container: - image: code.philo.ydns.eu/philorg/treetrail-backend-ci - volumes: - - "uv_cache:/root/.cache/uv" - - "ca-cert:/etc/containers/certs.d" - - services: - treetrail-database: - image: code.philo.ydns.eu/philorg/treetrail-database - - steps: - - name: Echo env - if: ${{ inputs.verbose }} - run: | - echo '${{ toJSON(env) }}' - - - uses: actions/checkout@v4 - - - name: Install app with 'uv pip install' - run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - - - name: Run tests (API call) - run: TREETRAIL_DB_HOST=treetrail-database pytest -s tests/basic.py - - build: - runs-on: container - needs: test - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install the latest version of uv - uses: astral-sh/setup-uv@v4 - with: - version: "0.6.6" - - - name: Install - run: uv sync - - - name: Get version - run: echo "VERSION=$(.venv/bin/dunamai from any --style semver)" >> $GITHUB_ENV - - - name: Version - run: echo $VERSION - - - name: Get distance from tag - run: echo "DISTANCE=$(.venv/bin/dunamai from any --format '{distance}')" >> $GITHUB_ENV - - - name: Distance - run: echo $DISTANCE - - - name: Workaround for bug of podman-login - if: env.DISTANCE == '0' - run: | - mkdir -p $HOME/.docker - echo "{ \"auths\": {} }" > $HOME/.docker/config.json - - - name: Log in to the container registry (with another workaround) - if: env.DISTANCE == '0' - uses: actions/podman-login@v1 - with: - registry: ${{ vars.REGISTRY }} - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} - auth_file_path: /tmp/auth.json - - - name: Build the container image - if: env.DISTANCE == '0' - uses: actions/buildah-build@v1 - with: - image: treetrail-backend - oci: true - labels: treetrail-backend - tags: "latest ${{ env.VERSION }}" - containerfiles: | - ./Containerfile - - - name: Push the image to the registry - if: env.DISTANCE == '0' - uses: actions/push-to-registry@v2 - with: - registry: "docker://${{ vars.REGISTRY }}/${{ vars.ORGANISATION }}" - image: treetrail-backend - tags: "latest ${{ env.VERSION }}" - - - name: Build wheel - if: env.DISTANCE == '0' - run: uv build --wheel - - - name: Publish Python package (home) - if: env.DISTANCE == '0' - env: - LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }} - run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/philorg/pypi --token $LOCAL_PYPI_TOKEN - continue-on-error: true diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml deleted file mode 100644 index fb41758..0000000 --- a/.forgejo/workflows/test.yaml +++ /dev/null @@ -1,34 +0,0 @@ -on: - push: - workflow_dispatch: - inputs: - verbose: - description: "Verbose" - required: false - default: false - type: boolean - -jobs: - test: - runs-on: container - container: - image: code.philo.ydns.eu/philorg/treetrail-backend-ci - volumes: - - "uv_cache:/root/.cache/uv" - - "ca-cert:/etc/containers/certs.d" - services: - treetrail-database: - image: code.philo.ydns.eu/philorg/treetrail-database - steps: - - name: Echo env - if: ${{ inputs.verbose }} - run: | - echo '${{ toJSON(env) }}' - - - uses: actions/checkout@v4 - - - name: Install app with 'uv pip install' - run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps . - - - name: Run tests (API call) - run: TREETRAIL_DB_HOST=treetrail-database pytest -s tests/basic.py diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml new file mode 100644 index 0000000..fd4d9cd --- /dev/null +++ b/.woodpecker/build.yaml @@ -0,0 +1,70 @@ +when: + - event: manual + - event: tag + +depends_on: + - test + +steps: + python_sync: + image: code.philo.ydns.eu/philorg/uv + volumes: + - uv-cache:/uv-cache + environment: + UV_CACHE_DIR: /uv-cache + UV_LINK_MODE: copy + commands: + - uv sync + + python_build: + image: code.philo.ydns.eu/philorg/uv + volumes: + - uv-cache:/uv-cache + environment: + UV_CACHE_DIR: /uv-cache + UV_LINK_MODE: copy + commands: + - uv build --wheel + - uv cache prune --ci + + python_publish: + image: code.philo.ydns.eu/philorg/uv + volumes: + - uv-cache:/uv-cache + environment: + UV_CACHE_DIR: /uv-cache + UV_LINK_MODE: copy + environment: + OWNER: philorg + REGISTRY_URL: https://code.philo.ydns.eu + REGISTRY_TOKEN: + from_secret: registry_token + commands: + - uv publish --publish-url $REGISTRY_URL/api/packages/$OWNER/pypi --token $REGISTRY_TOKEN dist/*.whl + failure: ignore + + container_build_publish: + image: quay.io/podman/stable:latest + # Caution: This image is built daily. It might fill up your image store quickly. + #pull: true + volumes: + - containers:/var/lib/containers + - uv-cache:/uv-cache + # Fill in the trusted checkbox in Woodpecker's settings as well + privileged: true + environment: + UV_CACHE_DIR: /uv-cache + UV_LINK_MODE: copy + registry: code.philo.ydns.eu + org: philorg + container_name: treetrail-backend + registry_token: + from_secret: registry_token + commands: + # Login at the registry + - podman login -u __token__ --password $registry_token $registry + # Build the container image + - podman build --volume=/var/lib/containers:/var/lib/containers --tag $registry/$org/$container_name:latest --tag $registry/$org/$container_name:$CI_COMMIT_TAG . + # Push the image + - podman push $registry/$org/$container_name:latest + - podman push $registry/$org/$container_name:$CI_COMMIT_TAG diff --git a/.woodpecker/test.yaml b/.woodpecker/test.yaml new file mode 100644 index 0000000..d8816b2 --- /dev/null +++ b/.woodpecker/test.yaml @@ -0,0 +1,21 @@ +when: + - event: push + branch: main + - event: manual + - event: tag + +steps: + sync: + image: code.philo.ydns.eu/philorg/uv + volumes: + - uv-cache:/uv-cache + environment: + UV_CACHE_DIR: /uv-cache + UV_LINK_MODE: copy + commands: + - uv sync + + test: + image: code.philo.ydns.eu/philorg/uv + commands: + - .venv/bin/pytest -s tests/basic.py diff --git a/README.md b/README.md index 393dbd8..759cac0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ *Tree Trail* is a fun and pedagogic tool to discover the trails and trees around. -This is the server (back-end), written in Python. \ No newline at end of file +This is the server (back-end), written in Python. + +[![status-badge](https://code.philo.ydns.eu/woodpecker/api/badges/20/status.svg)](https://code.philo.ydns.eu/woodpecker/repos/20) + diff --git a/src/treetrail/__init__.py b/src/treetrail/__init__.py index 95b89f2..00eba03 100644 --- a/src/treetrail/__init__.py +++ b/src/treetrail/__init__.py @@ -4,5 +4,5 @@ try: from dunamai import Version, Style __version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True) -except ImportError: - __version__ = importlib.metadata.version("treetrail-backend") +except (ImportError, RuntimeError): + __version__ = importlib.metadata.version(__name__) diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000