From c79184a6d973bd17105a11e3cc9ff1519486c253 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Mon, 9 Jun 2025 12:08:31 +0100 Subject: [PATCH] Use same version number for server and webapp, add CI check - Check webapp and server have same version number - Use `genversion` on build to create javascript file with version string from pyproject.toml - Expose the version number in the js interface - Correct format of current of alpha version string because javascript complains Closes #382 --- .gitignore | 3 + .gitlab-ci.yml | 13 ++ check_version_sync.py | 26 +++ pyproject.toml | 2 +- webapp/package-lock.json | 214 +++++++++++++++++- webapp/package.json | 12 +- .../aboutComponents/statusPane.vue | 2 +- webapp/src/main.js | 4 + 8 files changed, 267 insertions(+), 9 deletions(-) create mode 100755 check_version_sync.py diff --git a/.gitignore b/.gitignore index e30a155b..6d1962c3 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,6 @@ openflexure_settings/ # Files created by test utilities /tests/utilities/*.pstats /tests/utilities/*.png + +# js version file +/webapp/src/version.js diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6cd52db7..4879aaa1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -58,6 +58,19 @@ meta-build-image: - tags - web +# Check webapp and server hav matching version string +version-check: + stage: analysis + #use a base python image as nothing needs to be installed + image: python:3.11 + script: + - ./check_version_sync.py + only: + - branches + - merge_requests + - tags + - web + # Python static analysis with ruff ruff-lint: stage: analysis diff --git a/check_version_sync.py b/check_version_sync.py new file mode 100755 index 00000000..32f7b4ee --- /dev/null +++ b/check_version_sync.py @@ -0,0 +1,26 @@ +#! /usr/bin/env python3 + +""" +A script to check that th npm version string matches the python +version string exactly. +""" + +import json +import tomllib +import os + +with open("pyproject.toml", "rb") as toml_f: + pyproject_data = tomllib.load(toml_f) + +with open(os.path.join("webapp", "package.json"), "r", encoding="utf-8") as json_f: + webapp_data = json.load(json_f) + +py_ver = pyproject_data["project"]["version"] +js_ver = webapp_data["version"] + +assert py_ver == js_ver, ( + "The python and javascript version numbers should match.\n" + f"Python version: {py_ver}\n" + f"Javascript version: {js_ver}\n" + "" +) diff --git a/pyproject.toml b/pyproject.toml index bcc92396..c422165c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openflexure-microscope-server" -version = "3.0.0.alpha1" +version = "3.0.0-alpha1" authors = [ { name="Richard Bowman", email="richard.bowman@cantab.net" }, { name="Joel Collins" }, diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 38a12b77..4a6afceb 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -1,12 +1,12 @@ { "name": "openflexure-microscope-jsclient", - "version": "0.0.0", + "version": "3.0.0.alpha1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openflexure-microscope-jsclient", - "version": "0.0.0", + "version": "3.0.0.alpha1", "license": "GNU General Public License v3.0 ", "dependencies": { "imjoy-core": "^0.13", @@ -27,6 +27,7 @@ "eslint": "^6.8", "eslint-plugin-prettier": "^3.4", "eslint-plugin-vue": "^6.2", + "genversion": "^3.2.0", "less": "^3.13", "less-loader": "^5.0", "mdns-js": "^1.0", @@ -6867,6 +6868,39 @@ "dev": true, "optional": true }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/filesize": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", @@ -6984,6 +7018,16 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-package/-/find-package-1.0.0.tgz", + "integrity": "sha512-yVn71XCCaNgxz58ERTl8nA/8YYtIQDY9mHSrgFBfiFtdNNfY0h183Vh8BRkKxD8x9TUw3ec290uJKhDVxqGZBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parents": "^1.0.1" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -7245,6 +7289,50 @@ "node": ">=6.9.0" } }, + "node_modules/genversion": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/genversion/-/genversion-3.2.0.tgz", + "integrity": "sha512-OIYSX6XYA8PHecLDCTri30hadSZfAjZ8Iq1+BBDXqLWP4dRLuJNLoNjsSWtTpw97IccK2LDWzkEstxAB8GdN7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "ejs": "^3.1.9", + "find-package": "^1.0.0" + }, + "bin": { + "genversion": "bin/genversion.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/genversion/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/genversion/node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -9047,6 +9135,108 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -10798,6 +10988,16 @@ "node": ">=6" } }, + "node_modules/parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-platform": "~0.11.15" + } + }, "node_modules/parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", @@ -10924,6 +11124,16 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", diff --git a/webapp/package.json b/webapp/package.json index 10550b76..1db348dc 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -1,14 +1,15 @@ { "name": "openflexure-microscope-jsclient", - "version": "0.0.0", + "version": "3.0.0-alpha1", "private": true, "description": "User client for the OpenFlexure Microscope Server", "author": "OpenFlexure (https://www.openflexure.org)", "scripts": { - "serve": "vue-cli-service serve --mode development", - "serve-without-imjoy": "VUE_APP_ENABLE_IMJOY=false vue-cli-service serve --mode development", - "build": "vue-cli-service build --openssl-legacy-provider --mode production", - "build-without-imjoy": "VUE_APP_ENABLE_IMJOY=false vue-cli-service build --mode production", + "gv": "genversion src/version.js", + "serve": "npm run gv; vue-cli-service serve --mode development", + "serve-without-imjoy": "npm run gv; VUE_APP_ENABLE_IMJOY=false vue-cli-service serve --mode development", + "build": "npm run gv; vue-cli-service build --openssl-legacy-provider --mode production", + "build-without-imjoy": "npm run gv; VUE_APP_ENABLE_IMJOY=false vue-cli-service build --mode production", "lint": "vue-cli-service lint", "lint:fix": "vue-cli-service lint --fix" }, @@ -31,6 +32,7 @@ "eslint": "^6.8", "eslint-plugin-prettier": "^3.4", "eslint-plugin-vue": "^6.2", + "genversion": "^3.2.0", "less": "^3.13", "less-loader": "^5.0", "mdns-js": "^1.0", diff --git a/webapp/src/components/tabContentComponents/aboutComponents/statusPane.vue b/webapp/src/components/tabContentComponents/aboutComponents/statusPane.vue index 2d215f06..47cf4463 100644 --- a/webapp/src/components/tabContentComponents/aboutComponents/statusPane.vue +++ b/webapp/src/components/tabContentComponents/aboutComponents/statusPane.vue @@ -25,7 +25,7 @@
Server Version:
- V3 (pre-alpha) + v{{ app_version() }}

diff --git a/webapp/src/main.js b/webapp/src/main.js index 7844a302..ba55b940 100644 --- a/webapp/src/main.js +++ b/webapp/src/main.js @@ -11,6 +11,7 @@ require("vue-tour/dist/vue-tour.css"); // Import MD icons import "material-symbols/outlined.css"; +import version from './version.js' // UIKit overrides UIkit.mixin( @@ -35,6 +36,9 @@ Vue.config.productionTip = false; Vue.mixin({ methods: { + app_version() { + return version; + }, thingDescription(thing) { return this.$store.getters["wot/thingDescription"](thing); },