feat: Versionsanzeige (VERSION-Datei, Footer, /api/version, Image-Tag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ GRAFANA_CTR_NAME='finance-grafana_ctr'
|
||||
# needed).
|
||||
POSTGRES_IMAGE='docker.io/library/postgres:17.10'
|
||||
GRAFANA_IMAGE='docker.io/grafana/grafana-oss:12.1.0'
|
||||
API_IMAGE='localhost/finance-api:0.1.0'
|
||||
API_IMAGE="localhost/finance-api:$(cat "$HOME/bin/finance/VERSION")"
|
||||
|
||||
HOST_LOCAL_IP='127.0.0.1'
|
||||
# Expose API on 8096 -> 8000
|
||||
|
||||
@@ -6,6 +6,7 @@ RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY app/ app/
|
||||
COPY alembic/ alembic/
|
||||
COPY alembic.ini .
|
||||
COPY VERSION .
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
EXPOSE 8000
|
||||
|
||||
1
finance/VERSION
Normal file
1
finance/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
0.2.0
|
||||
@@ -1,17 +1,19 @@
|
||||
import hmac
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Form, Request
|
||||
from fastapi import Depends, FastAPI, Form, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from app import auth
|
||||
from app.auth import require_auth
|
||||
from app.config import get_settings
|
||||
from app.db import get_engine
|
||||
from app.models.views import create_views
|
||||
from app.routers import (accounts, categories, gui, imports, planning,
|
||||
scenarios, transactions)
|
||||
from app.routers.gui import templates
|
||||
from app.version import get_version
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@@ -55,3 +57,8 @@ def logout():
|
||||
resp = RedirectResponse("/login", status_code=303)
|
||||
resp.delete_cookie(auth.COOKIE)
|
||||
return resp
|
||||
|
||||
|
||||
@app.get("/api/version", dependencies=[Depends(require_auth)])
|
||||
def api_version():
|
||||
return {"version": get_version()}
|
||||
|
||||
@@ -21,8 +21,10 @@ from app.routers.planning import recurring_suggestions as _recurring_suggestions
|
||||
from app.routers.scenarios import list_scenarios as _list_scenarios
|
||||
from app.routers.transactions import list_transactions
|
||||
from app.services.balances import account_balance, total_balance
|
||||
from app.version import get_version
|
||||
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
templates.env.globals["app_version"] = get_version()
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
|
||||
@@ -151,3 +151,9 @@ section.planning-section {
|
||||
section.planning-section fieldset {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.version {
|
||||
margin-top: 2rem;
|
||||
color: #888;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
@@ -64,5 +64,6 @@
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<footer class="version">Finanzberatungs-Tool v{{ app_version }}</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
9
finance/app/version.py
Normal file
9
finance/app/version.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_version() -> str:
|
||||
f = Path(__file__).resolve().parent.parent / "VERSION"
|
||||
try:
|
||||
return f.read_text().strip()
|
||||
except OSError:
|
||||
return "0.0.0-dev"
|
||||
@@ -33,6 +33,13 @@ def test_import_list_fragment_renders_after_login(client):
|
||||
assert "Noch keine Imports" in r.text
|
||||
|
||||
|
||||
def test_version_visible(client):
|
||||
r = client.get("/api/version", headers={"Authorization": "Bearer test-key"})
|
||||
assert r.status_code == 200 and r.json()["version"] == "0.2.0"
|
||||
client.post("/login", data={"username": "admin", "password": "geheim"})
|
||||
assert "v0.2.0" in client.get("/").text
|
||||
|
||||
|
||||
def test_planning_page_has_all_sections(client):
|
||||
client.post("/login", data={"username": "admin", "password": "geheim"})
|
||||
r = client.get("/planung")
|
||||
|
||||
Reference in New Issue
Block a user