From 68a4f1800c87865cc15335eeba456e55a2626070 Mon Sep 17 00:00:00 2001 From: Ryan Kegel Date: Sun, 14 Dec 2025 23:20:51 -0500 Subject: [PATCH] versioning --- Jenkinsfile | 5 ++-- config/version.py | 12 ++++++++++ docker-compose.yml | 30 ++++++++++++++++++++++++ main.py | 7 +++++- web/vue-app/src/layout/ParentLayout.vue | 31 ++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 config/version.py create mode 100644 docker-compose.yml diff --git a/Jenkinsfile b/Jenkinsfile index 932f591..d6c463c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -10,6 +10,7 @@ pipeline { VUE_CONTAINER_NAME = "chore-app-frontend" FLASK_CONTAINER_NAME = "chore-app-backend" NETWORK_NAME = "chore-app-net" + BASE_VERSION = '1.0.0' } stages { @@ -32,8 +33,7 @@ pipeline { stage('Build Backend (Flask) App') { steps { dir('.') { - sh 'docker build -t ${BACKEND_IMAGE} .' - sh 'docker tag ${BACKEND_IMAGE} ${BACKEND_IMAGE_LATEST}' + sh """docker build --build-arg APP_BUILD=${BUILD_NUMBER} -t chore-app-backend:${BASE_VERSION} -t chore-app-backend:${BASE_VERSION}-${BUILD_NUMBER} -t chore-app-backend:latest .""" } } } @@ -65,6 +65,7 @@ pipeline { docker run -d \\ --name ${FLASK_CONTAINER_NAME} \\ --network ${NETWORK_NAME} \\ + -e BUILD_NUMBER=${BUILD_NUMBER} \\ -v ${FLASK_CONTAINER_NAME}_data:/app/data \\ ${BACKEND_IMAGE_LATEST} """ diff --git a/config/version.py b/config/version.py new file mode 100644 index 0000000..0aeb9d2 --- /dev/null +++ b/config/version.py @@ -0,0 +1,12 @@ +# python +# file: config/version.py +import os + +BASE_VERSION = "1.0.0" # update manually when releasing features + +def get_full_version() -> str: + """ + Return semantic version with optional Jenkins build metadata, e.g. 1.2.3+build.456. + """ + build = os.environ.get("BUILD_NUMBER") or os.environ.get("APP_BUILD") + return f"{BASE_VERSION}+build.{build}" if build else BASE_VERSION diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f8966f9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +# yaml +version: '3.8' + +services: + chore-app-backend: + image: devserver.lan:5900/chore-app-backend:production + container_name: chore-app-backend + restart: unless-stopped + expose: + - "5000" + networks: + - chore-app-net + volumes: + - chore-app-backend-data:/app/data # persists backend data + + chore-app-frontend: + image: devserver.lan:5900/chore-app-frontend:production + container_name: chore-app-frontend + restart: unless-stopped + ports: + - "4600:443" + networks: + - chore-app-net + +networks: + chore-app-net: + driver: bridge + +volumes: + chore-app-backend-data: {} \ No newline at end of file diff --git a/main.py b/main.py index f048433..67cc52b 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,13 @@ import sys, logging, os from config.paths import get_user_image_dir -from flask import Flask, request +from flask import Flask, request, jsonify from flask_cors import CORS from api.child_api import child_api from api.image_api import image_api from api.reward_api import reward_api from api.task_api import task_api +from config.version import get_full_version from events.broadcaster import Broadcaster from events.sse import sse_response_for_user, send_to_user from db.default import initializeImages @@ -29,6 +30,10 @@ app.register_blueprint(task_api) app.register_blueprint(image_api) CORS(app) +@app.route("/version") +def api_version(): + return jsonify({"version": get_full_version()}) + @app.route("/events") def events(): # Authenticate user or read a token diff --git a/web/vue-app/src/layout/ParentLayout.vue b/web/vue-app/src/layout/ParentLayout.vue index db8f8ab..6bff924 100644 --- a/web/vue-app/src/layout/ParentLayout.vue +++ b/web/vue-app/src/layout/ParentLayout.vue @@ -1,6 +1,6 @@ @@ -251,6 +267,19 @@ const showBack = computed( align-self: start; } +.app-version { + position: fixed; + right: 18px; + bottom: 12px; + font-size: 0.92rem; + color: #cbd5e1; /* Brighter slate-200 */ + opacity: 0.85; + z-index: 100; + pointer-events: none; + user-select: none; + font-family: monospace; +} + @media (max-width: 480px) { .back-btn { padding: 0.45rem 0.75rem;