mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-28 12:21:32 +00:00
Add preamble versioning (#3147)
* Add preamble versioning * update migrations index
This commit is contained in:
committed by
GitHub
parent
cafdaf7b50
commit
c60626f772
@@ -78,6 +78,7 @@ const AVAILABLE_MIGRATIONS: [number, string[]][] = [
|
||||
[43, ['0047_app-url-updates.sql']],
|
||||
[44, ['0048_old-app-names-unique-tuple.sql']],
|
||||
[45, ['0049_music-player-pdf-player-updates.sql']],
|
||||
[46, ['0050_add_preamble_version.sql']],
|
||||
];
|
||||
|
||||
export class SqliteDatabaseClient extends AbstractDatabaseClient {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Copyright (C) 2024-present Puter Technologies Inc.
|
||||
--
|
||||
-- This file is part of Puter.
|
||||
--
|
||||
-- Puter is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU Affero General Public License as published
|
||||
-- by the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU Affero General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU Affero General Public License
|
||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
ALTER TABLE `subdomains` ADD COLUMN `preamble_version` varchar(64) DEFAULT NULL;
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Copyright (C) 2024-present Puter Technologies Inc.
|
||||
--
|
||||
-- This file is part of Puter.
|
||||
--
|
||||
-- Puter is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU Affero General Public License as published
|
||||
-- by the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU Affero General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU Affero General Public License
|
||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
ALTER TABLE `subdomains` ADD COLUMN `preamble_version` varchar(64) DEFAULT NULL;
|
||||
@@ -42,6 +42,7 @@ const WORKER_SUBDOMAIN_PREFIX = 'workers.puter.';
|
||||
let preamble = '';
|
||||
let preambleError = false;
|
||||
let preambleLineCount = 0;
|
||||
let preambleVersion: string | null = null;
|
||||
try {
|
||||
const preamblePath = path.join(
|
||||
__dirname,
|
||||
@@ -50,6 +51,13 @@ try {
|
||||
console.log('reading: ' + preamblePath);
|
||||
preamble = readFileSync(preamblePath, 'utf-8');
|
||||
preambleLineCount = preamble.split('\n').length - 1;
|
||||
|
||||
const versionMatch = /^var __PUTER_PREAMBLE_VERSION__\s*=\s*"([^"]+)"/.exec(
|
||||
preamble,
|
||||
);
|
||||
if (versionMatch) {
|
||||
preambleVersion = versionMatch[1];
|
||||
}
|
||||
} catch {
|
||||
console.warn(
|
||||
'[workers] preamble not built — workers will not have puter.js injected.',
|
||||
@@ -75,6 +83,10 @@ export class WorkerDriver extends PuterDriver {
|
||||
|
||||
#cfBaseUrl = '';
|
||||
|
||||
static currentPreambleVersion(): string | null {
|
||||
return preambleVersion;
|
||||
}
|
||||
|
||||
override onServerStart(): void {
|
||||
const cfg = this.#workerConfig();
|
||||
if (cfg.ACCOUNTID) {
|
||||
@@ -199,6 +211,7 @@ export class WorkerDriver extends PuterDriver {
|
||||
String(existingSub.uuid),
|
||||
{
|
||||
root_dir_id: loaded.fsEntry?.sqlId ?? null,
|
||||
preamble_version: preambleVersion,
|
||||
},
|
||||
{ userId: actor.user.id },
|
||||
);
|
||||
@@ -217,6 +230,7 @@ export class WorkerDriver extends PuterDriver {
|
||||
subdomain: subdomainName,
|
||||
rootDirId: loaded.fsEntry?.sqlId,
|
||||
appOwner: appOwnerId,
|
||||
preambleVersion,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -604,6 +618,14 @@ export class WorkerDriver extends PuterDriver {
|
||||
preamble + sourceCode,
|
||||
)) as { success?: boolean; errors?: unknown[]; url?: string };
|
||||
|
||||
if (cfResult.success && row.uuid) {
|
||||
await this.stores.subdomain.update(
|
||||
String(row.uuid),
|
||||
{ preamble_version: preambleVersion },
|
||||
{ userId },
|
||||
);
|
||||
}
|
||||
|
||||
// Notify the user
|
||||
await this.#notifyUser(userId, workerName, cfResult);
|
||||
} catch (err) {
|
||||
|
||||
@@ -182,13 +182,14 @@ export class SubdomainStore extends PuterStore {
|
||||
|
||||
// ── Writes ───────────────────────────────────────────────────────
|
||||
|
||||
/** @param {{ userId: number, subdomain: string, rootDirId?: number|null, associatedAppId?: number|null, appOwner?: number|null }} opts */
|
||||
/** @param {{ userId: number, subdomain: string, rootDirId?: number|null, associatedAppId?: number|null, appOwner?: number|null, preambleVersion?: string|null }} opts */
|
||||
async create({
|
||||
userId,
|
||||
subdomain,
|
||||
rootDirId = null,
|
||||
associatedAppId = null,
|
||||
appOwner = null,
|
||||
preambleVersion = null,
|
||||
}) {
|
||||
if (!userId || !subdomain) {
|
||||
throw new Error('create: userId and subdomain are required');
|
||||
@@ -196,8 +197,8 @@ export class SubdomainStore extends PuterStore {
|
||||
const uuid = uuidv4();
|
||||
await this.clients.db.write(
|
||||
`INSERT INTO \`subdomains\`
|
||||
(\`uuid\`, \`subdomain\`, \`user_id\`, \`root_dir_id\`, \`associated_app_id\`, \`app_owner\`)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
(\`uuid\`, \`subdomain\`, \`user_id\`, \`root_dir_id\`, \`associated_app_id\`, \`app_owner\`, \`preamble_version\`)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
uuid,
|
||||
subdomain,
|
||||
@@ -205,6 +206,7 @@ export class SubdomainStore extends PuterStore {
|
||||
rootDirId ?? null,
|
||||
associatedAppId,
|
||||
appOwner,
|
||||
preambleVersion,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -215,6 +217,7 @@ export class SubdomainStore extends PuterStore {
|
||||
root_dir_id: rootDirId ?? null,
|
||||
associated_app_id: associatedAppId,
|
||||
app_owner: appOwner,
|
||||
preamble_version: preambleVersion,
|
||||
};
|
||||
await this.#refreshCache(row);
|
||||
await this.#invalidatePrefixListsForUser(userId);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import { execSync } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
@@ -8,6 +9,16 @@ const templatePath = path.join(workerDir, 'template', 'puter-portable.template')
|
||||
const outputDir = path.join(workerDir, 'dist');
|
||||
const outputPath = path.join(outputDir, 'workerPreamble.js');
|
||||
|
||||
// Build a version stamp: puter-js version + short git SHA
|
||||
const puterJsPkg = JSON.parse(
|
||||
await readFile(path.resolve(workerDir, '../puter-js/package.json'), 'utf-8'),
|
||||
);
|
||||
let gitSha = 'unknown';
|
||||
try {
|
||||
gitSha = execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).trim();
|
||||
} catch { /* not in a git repo — keep "unknown" */ }
|
||||
const preambleVersion = `${puterJsPkg.version}+${gitSha}`;
|
||||
|
||||
const inlineIncludes = async (filePath) => {
|
||||
const fileContents = await readFile(filePath, 'utf-8');
|
||||
const lines = fileContents.split('\n');
|
||||
@@ -36,5 +47,6 @@ const inlineIncludes = async (filePath) => {
|
||||
};
|
||||
|
||||
await mkdir(outputDir, { recursive: true });
|
||||
const versionBanner = `var __PUTER_PREAMBLE_VERSION__ = ${JSON.stringify(preambleVersion)};\n`;
|
||||
const preambleSource = await inlineIncludes(templatePath);
|
||||
await writeFile(outputPath, preambleSource);
|
||||
await writeFile(outputPath, versionBanner + preambleSource);
|
||||
|
||||
Reference in New Issue
Block a user