diff --git a/Dockerfile b/Dockerfile index 4886e8b..79f53b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN uv sync --frozen --no-dev COPY src/ src/ COPY scripts/ scripts/ -COPY strategies.yml portfolios.yml ./ +COPY strategies.yml portfolios.yml VERSION ./ VOLUME /app/data diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/scripts/bump_version.py b/scripts/bump_version.py new file mode 100644 index 0000000..4179337 --- /dev/null +++ b/scripts/bump_version.py @@ -0,0 +1,29 @@ +"""Incrementa la versione (semver) nel file VERSION. Default: patch +1. +Uso: uv run python scripts/bump_version.py [major|minor|patch] (default patch) +Stampa la nuova versione. Usato da scripts/deploy.sh ad ogni deploy.""" +import sys +from pathlib import Path + +VF = Path(__file__).resolve().parents[1] / "VERSION" + + +def main(): + part = sys.argv[1] if len(sys.argv) > 1 else "patch" + cur = VF.read_text().strip() if VF.exists() else "0.0.0" + try: + major, minor, patch = (int(x) for x in cur.split(".")) + except Exception: + major, minor, patch = 0, 0, 0 + if part == "major": + major, minor, patch = major + 1, 0, 0 + elif part == "minor": + minor, patch = minor + 1, 0 + else: + patch += 1 + new = f"{major}.{minor}.{patch}" + VF.write_text(new + "\n") + print(new) + + +if __name__ == "__main__": + main() diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 0000000..66dcc9c --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Deploy del paper trader a portafoglio: bumpa la VERSIONE, committa, rebuilda l'immagine e +# ricrea il container. La versione (es. v1.0.1) compare nei messaggi Telegram -> sai quale +# codice ha generato quale msg, e aumenta ad OGNI deploy. +# +# Uso: ./scripts/deploy.sh [major|minor|patch] (default patch) +set -euo pipefail +cd "$(dirname "$0")/.." + +PART="${1:-patch}" +NEW=$(uv run python scripts/bump_version.py "$PART") +echo ">> nuova versione: v$NEW" + +git add VERSION +git commit -q -m "release: v$NEW" || true + +echo ">> rebuild immagine + ricrea container" +docker compose up -d --build + +sleep 8 +docker compose ps --format "{{.Status}}" +echo ">> deploy v$NEW completato" diff --git a/scripts/portfolios/hourly_report.py b/scripts/portfolios/hourly_report.py index a5dd005..20b14b0 100644 --- a/scripts/portfolios/hourly_report.py +++ b/scripts/portfolios/hourly_report.py @@ -92,12 +92,16 @@ def build_report() -> str: r[2] += pnl now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") + try: + ver = (ROOT / "VERSION").read_text().strip() + except Exception: + ver = "?" eq = dd = cap = None if PORT_STATUS.exists(): ps = json.loads(PORT_STATUS.read_text()) eq, cap, dd = ps.get("equity"), ps.get("total_capital"), ps.get("max_dd") - L = [f"📊 PORT06 — Report orario", now] + L = [f"📊 PORT06 — Report orario v{ver}", now] if eq is not None: L.append(f"Equity €{eq:.2f} | Cap €{cap:.2f} | maxDD {dd:.3f}%") diff --git a/src/live/telegram_notifier.py b/src/live/telegram_notifier.py index 93a8bb2..efa247b 100644 --- a/src/live/telegram_notifier.py +++ b/src/live/telegram_notifier.py @@ -6,6 +6,8 @@ import urllib.request import urllib.parse import json +from src.version import APP_VERSION + BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "") CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "") @@ -30,7 +32,7 @@ def send_telegram(text: str) -> bool: def notify_event(event: str, data: dict | None = None): if event not in NOTIFY_EVENTS: return - lines = [f"📊 {event}"] + lines = [f"📊 {event} v{APP_VERSION}"] if data: for k, v in data.items(): if k in ("signal",): diff --git a/src/version.py b/src/version.py new file mode 100644 index 0000000..fb983c3 --- /dev/null +++ b/src/version.py @@ -0,0 +1,18 @@ +"""Versione dell'app, incrementata ad ogni deploy. Compare nei messaggi Telegram per correlare +i msg al codice in esecuzione. Sorgente: file VERSION nella root (cotto nell'immagine al build). +Bump: scripts/bump_version.py (o scripts/deploy.sh, che bumpa+committa+rebuilda).""" +from __future__ import annotations + +from pathlib import Path + +_VERSION_FILE = Path(__file__).resolve().parents[1] / "VERSION" + + +def get_version() -> str: + try: + return _VERSION_FILE.read_text().strip() + except Exception: + return "0.0.0" + + +APP_VERSION = get_version()