feat: added bot versioning

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-08-22 20:22:06 +02:00
parent 353abfc39f
commit df861689b6
4 changed files with 76 additions and 2 deletions

View File

@ -0,0 +1 @@
1

View File

@ -11,7 +11,7 @@ import chess.pgn
from .engine import RandomEngine
from .lichess_api import LichessAPI
from .utils import backoff_sleep
from .utils import backoff_sleep, get_and_increment_version
def run_bot(log_level: str = "INFO", decline_correspondence: bool = False) -> None:
@ -25,13 +25,16 @@ def run_bot(log_level: str = "INFO", decline_correspondence: bool = False) -> No
raise RuntimeError("LICHESS_TOKEN environment variable is required")
logging.info("Token present. Initializing client and engine...")
# Self-incrementing bot version (persisted on disk)
bot_version = get_and_increment_version()
logging.info(f"Bot version: v{bot_version}")
api = LichessAPI(token)
engine = RandomEngine()
game_threads = {}
def handle_game(game_id: str, my_color: Optional[str] = None):
logging.info(f"Starting game thread for {game_id}")
logging.info(f"Starting game thread for {game_id} [bot v{bot_version}]")
board = chess.Board()
color: Optional[str] = my_color
# Track how many moves we have already processed; start at -1 so we act on the first state (0 moves)
@ -41,6 +44,7 @@ def run_bot(log_level: str = "INFO", decline_correspondence: bool = False) -> No
try:
with open(game_log_path, "w") as lf:
lf.write(f"game {game_id} started\n")
lf.write(f"bot_version v{bot_version}\n")
except Exception:
game_log_path = None
# Simple time manager state
@ -149,6 +153,11 @@ def run_bot(log_level: str = "INFO", decline_correspondence: bool = False) -> No
try:
if game_log_path:
game = chess.pgn.Game.from_board(board)
# Record the bot version in the PGN headers
try:
game.headers["BotVersion"] = f"v{bot_version}"
except Exception:
pass
with open(game_log_path, "a") as lf:
lf.write("\nPGN:\n")
exporter = chess.pgn.StringExporter(headers=True, variations=False, comments=False)

View File

@ -0,0 +1,19 @@
import os
import tempfile
from PYTHON.lichess_bot.utils import get_and_increment_version
def test_version_file_increments_and_persists(tmp_path, monkeypatch):
version_file = tmp_path / "version.txt"
monkeypatch.setenv("LICHESS_BOT_VERSION_FILE", str(version_file))
v1 = get_and_increment_version()
v2 = get_and_increment_version()
assert v1 == 1
assert v2 == 2
# Ensure it persisted
with open(version_file, "r") as f:
assert f.read().strip() == "2"

View File

@ -1,7 +1,52 @@
import logging
import os
import time
def _version_file_path() -> str:
"""Return the path to the persistent bot version file.
Stored alongside this module as a simple text file containing an integer.
"""
override = os.getenv("LICHESS_BOT_VERSION_FILE")
if override:
return override
return os.path.join(os.path.dirname(__file__), ".bot_version")
def get_and_increment_version() -> int:
"""Read the current bot version, increment it, persist, and return the new version.
If the version file doesn't exist or is invalid, starts from 0, then sets to 1.
"""
path = _version_file_path()
current = 0
try:
with open(path, "r") as f:
raw = f.read().strip()
if raw:
current = int(raw)
except Exception:
# Missing or unreadable file -> treat as version 0
current = 0
new_version = current + 1
try:
tmp_path = path + ".tmp"
with open(tmp_path, "w") as f:
f.write(str(new_version))
os.replace(tmp_path, path)
except Exception:
# As a fallback, try a direct write; failure is non-fatal to bot operation
try:
with open(path, "w") as f:
f.write(str(new_version))
except Exception:
logging.debug("Could not persist bot version to %s", path)
return new_version
def backoff_sleep(current_backoff: int, base: float = 0.5, cap: float = 8.0) -> int:
"""Sleep with exponential backoff. Returns the next backoff step.