Compare commits

...
Sign in to create a new pull request.

17 commits
master ... main

Author SHA1 Message Date
2973bc58eb CI: remove forgejo actions
All checks were successful
ci/woodpecker/push/test Pipeline was successful
2025-06-28 13:40:41 +02:00
8012c7d706 Update README with CI badge
Some checks failed
ci/woodpecker/push/test Pipeline was successful
/ test (push) Has been cancelled
2025-06-28 13:39:49 +02:00
c2ba8c6db5 CI: add redis service for test
Some checks failed
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/test Pipeline was successful
ci/woodpecker/tag/build Pipeline was successful
/ test (push) Has been cancelled
/ build (push) Has been cancelled
2025-06-28 13:36:43 +02:00
1b25f8243e CI: add redis service for test
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 13:34:50 +02:00
2b43290157 CI: add redis service for test
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 13:33:20 +02:00
d07cd79560 Fix create_db (on startup, for testing, CI)
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 13:28:28 +02:00
f3fd25f47a CI: fix typo
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 05:07:52 +02:00
1c76934e17 CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:59:24 +02:00
9ff61ca382 CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:56:53 +02:00
8c06817fbe CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:55:24 +02:00
f4de623b86 CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:48:49 +02:00
e7cbb1e645 CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:48:00 +02:00
0a7402e7ca CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:45:43 +02:00
72ab25096a CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:44:49 +02:00
f045a2cc77 CI: debug
Some checks failed
/ test (push) Waiting to run
ci/woodpecker/push/test Pipeline failed
2025-06-28 04:42:36 +02:00
547b2edaaa Clean version 2025-06-28 04:42:10 +02:00
5c490f5127 Clean cli 2025-06-28 04:41:57 +02:00
8 changed files with 38 additions and 173 deletions

View file

@ -1,117 +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/gisaf-backend-ci
volumes:
- "uv_cache:/root/.cache/uv"
- "ca-cert:/etc/containers/certs.d"
services:
gisaf-database:
image: code.philo.ydns.eu/philorg/gisaf-database
redis:
image: docker.io/redis:alpine
steps:
- name: Echo env
if: ${{ inputs.verbose }}
run: |
echo '${{ toJSON(env) }}'
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install app with 'uv pip install'
run: uv pip install --python=$UV_PROJECT_ENVIRONMENT --no-deps .
- name: Initialize database
run: GISAF__DB__HOST=gisaf-database gisaf create-db
- name: Run tests (API call)
run: GISAF__DB__HOST=gisaf-database GISAF__GISAF_LIVE__REDIS=redis://redis pytest -s tests/basic.py -W ignore::DeprecationWarning
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: gisaf-backend
oci: true
labels: gisaf-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: gisaf-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

View file

@ -1,39 +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/gisaf-backend-ci
volumes:
- "uv_cache:/root/.cache/uv"
- "ca-cert:/etc/containers/certs.d"
services:
gisaf-database:
image: code.philo.ydns.eu/philorg/gisaf-database
redis:
image: docker.io/redis:alpine
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: Initialize database
run: GISAF__DB__HOST=gisaf-database gisaf create-db
- name: Run tests (API call)
run: GISAF__DB__HOST=gisaf-database GISAF__GISAF_LIVE__REDIS=redis://redis pytest -s tests/basic.py -W ignore::DeprecationWarning

View file

@ -1 +0,0 @@
3.12

View file

@ -20,11 +20,14 @@ steps:
image: code.philo.ydns.eu/philorg/uv-geo
environment:
GISAF__DB__HOST: gisaf-database
GISAF__GISAF_LIVE__REDIS: redis://redis
commands:
# Initialize database
- .venv/bin/gisaf create-db
- .venv/bin/pytest -s tests/basic.py
services:
redis:
image: docker.io/redis:alpine
gisaf-database:
image: code.philo.ydns.eu/philorg/treetrail-database
image: code.philo.ydns.eu/philorg/gisaf-database

View file

@ -57,3 +57,5 @@ Documentation is being rewritten. Please contact us.
A very basic demo without any data, basically to give a feel of the user interface,
is available [here](https://gisaf.philo.ydns.eu).
[![status-badge](https://code.philo.ydns.eu/woodpecker/api/badges/17/status.svg)](https://code.philo.ydns.eu/woodpecker/repos/17)

View file

@ -4,7 +4,7 @@ try:
from dunamai import Version, Style
__version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True)
except ImportError:
except (ImportError, RuntimeError):
# __name__ could be used if the package name is the same
# as the directory - not the case here
# __version__ = importlib.metadata.version(__name__)

View file

@ -1,6 +1,4 @@
#!/usr/bin/env python
from importlib.metadata import version as importlib_version
from sqlalchemy.engine import create
from typing_extensions import Annotated
import typer
@ -11,7 +9,6 @@ cli = typer.Typer(no_args_is_help=True, help="Gisaf GIS backend")
@cli.command()
def create_db():
"""Populate the database with a functional empty structure"""
from gisaf.application import app
from gisaf.database import create_db
from asyncio import run
@ -36,15 +33,15 @@ def serve(host: str = "localhost", port: int = 8000):
def version_callback(show_version: bool):
if show_version:
print(importlib_version("gisaf-backend"))
from gisaf import __version__
typer.echo(__version__)
raise typer.Exit()
@cli.callback()
def main(
version: Annotated[
bool | None, typer.Option("--version", callback=version_callback)
] = None
version: Annotated[bool | None, typer.Option("--version", callback=version_callback)] = None,
):
pass

View file

@ -166,9 +166,24 @@ async def create_db(drop=False):
async with engine.begin() as conn:
await create_schemas(conn)
async with engine.begin() as conn:
# Import modules to populate the SQLModel metadata
from gisaf.models import admin
from gisaf.models import authentication
from gisaf.models import category
from gisaf.models import dashboard
from gisaf.models import geo_models_base
from gisaf.models import info
from gisaf.models import misc
from gisaf.models import project
from gisaf.models import raw_survey
from gisaf.models import reconcile
from gisaf.models import survey
from gisaf.models import tags
if drop:
await conn.run_sync(SQLModel.metadata.drop_all)
await conn.run_sync(SQLModel.metadata.create_all)
resp = await conn.run_sync(SQLModel.metadata.create_all)
pass
logger.debug(f"Connect to database with config: {conf.db}")
while attempts > 0:
@ -186,9 +201,7 @@ async def create_db(drop=False):
await populate_init_db()
return
else:
logger.warning(
f"Cannot connect to database after {CREATE_DB_TIMEOUT}, giving up."
)
logger.warning(f"Cannot connect to database after {CREATE_DB_TIMEOUT}, giving up.")
exit(1)
@ -196,6 +209,15 @@ async def is_fresh_install() -> bool:
"""Detect is the database is newly created, without data"""
from gisaf.models.authentication import User
async with engine.begin() as conn:
has_table_query = """
SELECT count(tablename)
FROM pg_catalog.pg_tables
WHERE schemaname = 'gisaf_admin' and tablename='user'"""
resp = await conn.execute(text(has_table_query))
if resp.scalar() == 0:
return True
async with db_session() as session:
nb_users = (await session.exec(select(func.count(col(User.username))))).one()
return nb_users == 0
@ -222,9 +244,7 @@ async def populate_init_db():
from gisaf.models.map_bases import BaseStyle
logger.info("Populating initial database")
async with db_session() as session:
user = await create_user(
session=session,
username="admin",