From 6feeebab5408a0df9a3827653eb3fb033e26ac0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Vogel?= <104342347+cedricvogel-leo@users.noreply.github.com> Date: Fri, 6 Nov 2026 21:18:18 +0100 Subject: [PATCH] =?UTF-8?q?=E2=8B=AE=20=C2=ABInfo=C2=BB:=20the=20bundled?= =?UTF-8?q?=20glpython-editor's=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next to the IDE's commit, Info shows the glpython-editor tag the build bundles (from package.json, a commit's first 7 characters if it pins one), since most of what learners see comes from there. Co-Authored-By: Claude Opus 5.5 --- README.md | 3 ++- scripts/check-ide-browser.mjs | 2 ++ src/App.tsx | 4 ++++ src/i18n.ts | 4 ++++ vite.config.ts | 9 +++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b108db..e0788c0 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,8 @@ automatically in the browser: by the build, checked when the tab comes back into view and every 30 minutes): «Neue Version verfügbar.» · «Neu laden». The code survives the reload; Python's session doesn't. -- ⋮ **Info** shows the version - the short commit and the build date, as in +- ⋮ **Info** shows the version - the short commit, the bundled glpython-editor's + tag (from `package.json`) and the build date, as in `version.json` - and **Nach Updates suchen** runs the same check: «Diese Version ist aktuell.», or the notice with «Neu laden». When a learner reports a problem, it tells whether their browser still runs an old version. diff --git a/scripts/check-ide-browser.mjs b/scripts/check-ide-browser.mjs index dcfc594..cb45e06 100644 --- a/scripts/check-ide-browser.mjs +++ b/scripts/check-ide-browser.mjs @@ -604,6 +604,8 @@ try { await page.getByRole('menuitem', { name: 'Info' }).click() const dialog = page.getByRole('dialog') assert.match(await dialog.innerText(), new RegExp(`Version\\s+${version.slice(0, 7)}`)) + const editorSpec = JSON.parse(readFileSync('package.json', 'utf8')).dependencies['glpython-editor'].split('#')[1] + assert.match(await dialog.innerText(), new RegExp(`Editor\\s+${/^[0-9a-f]{40}$/.test(editorSpec) ? editorSpec.slice(0, 7) : editorSpec.replace(/\./g, '\\.')}`), 'the editor\'s version') await dialog.getByRole('button', { name: 'Nach Updates suchen' }).click() await page.waitForFunction(() => document.querySelector('.ide-info-check [role=status]')?.textContent === 'Diese Version ist aktuell.', null, { timeout: 10000 }) // A newer deploy: the same check offers the reload. diff --git a/src/App.tsx b/src/App.tsx index 802b1bd..188b0c0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -41,6 +41,9 @@ function timeAgo(time: number, locale: string, justNow: string): string { // deployed now (version.json, see vite.config.ts): a tab that stayed open - // on an iPad often for days - offers to load the new one; ⋮ «Info» shows it. declare const __GLPYTHON_IDE_VERSION__: string +// The glpython-editor version it bundles (its tag), for ⋮ «Info» too: most +// of what learners see (editor, Tests, visualizer, hints) comes from there. +declare const __GLPYTHON_EDITOR_VERSION__: string declare const __GLPYTHON_IDE_BUILT__: string const VERSION_CHECK_MS = 30 * 60 * 1000 async function checkForNewVersion(): Promise<'current' | 'available' | 'failed'> { @@ -521,6 +524,7 @@ function App() {
glpython
{t.version}
{__GLPYTHON_IDE_VERSION__.slice(0, 7)}
+
{t.editorVersion}
{__GLPYTHON_EDITOR_VERSION__}
{t.built}
{versionDate}
diff --git a/src/i18n.ts b/src/i18n.ts index 9656811..9124c84 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -37,6 +37,8 @@ type ShellStrings = { featureLabels: Record<'run' | 'tests' | 'visualize' | 'repl' | 'export' | 'coverage' | 'listtree' | 'tree', string> version: string built: string + // The bundled glpython-editor's version in ⋮ «Info». + editorVersion: string checkForUpdates: string checkingForUpdates: string upToDate: string @@ -118,6 +120,7 @@ export const translations: Record = { }, version: 'Version', built: 'Built', + editorVersion: 'Editor', checkForUpdates: 'Check for updates', checkingForUpdates: 'Checking …', upToDate: 'This version is up to date.', @@ -194,6 +197,7 @@ export const translations: Record = { }, version: 'Version', built: 'Erstellt', + editorVersion: 'Editor', checkForUpdates: 'Nach Updates suchen', checkingForUpdates: 'Wird geprüft …', upToDate: 'Diese Version ist aktuell.', diff --git a/vite.config.ts b/vite.config.ts index f249655..1b6fbbb 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,4 +1,5 @@ import { execSync } from 'node:child_process' +import { readFileSync } from 'node:fs' import react from '@vitejs/plugin-react' import { defineConfig, type Plugin } from 'vite' @@ -9,6 +10,13 @@ const version = process.env.GITHUB_SHA ?? (() => { try { return execSync('git rev-parse HEAD').toString().trim() } catch { return 'dev' } })() const built = new Date().toISOString() +// The glpython-editor it bundles, as package.json pins it: the tag +// ("…glpython-editor.git#v0.1.30"), or a commit's first 7 characters. +const editorVersion = (() => { + const spec = (JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8')) as { dependencies?: Record }).dependencies?.['glpython-editor'] ?? '' + const ref = spec.split('#')[1] ?? '' + return /^[0-9a-f]{40}$/.test(ref) ? ref.slice(0, 7) : ref || 'unknown' +})() const versionFile: Plugin = { name: 'glpython-version-file', apply: 'build', @@ -33,6 +41,7 @@ export default defineConfig({ define: { __GLPYTHON_IDE_VERSION__: JSON.stringify(version), __GLPYTHON_IDE_BUILT__: JSON.stringify(built), + __GLPYTHON_EDITOR_VERSION__: JSON.stringify(editorVersion), }, // glpython-editor's Pyodide worker is loaded via // `new Worker(new URL('./pyodide-worker.js', import.meta.url))`, resolved