config and plugin
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { destOf } from '../config.js';
|
||||
import { destOfKind, type ArtifactKind } from '../config.js';
|
||||
import { db } from '../db/index.js';
|
||||
import { emit } from '../pipeline/bus.js';
|
||||
import { recordScript, removeScript } from './inventory.js';
|
||||
@@ -33,6 +33,7 @@ interface DepScriptRow {
|
||||
script_id: number;
|
||||
script_version_id: number;
|
||||
prior_version_id: number | null;
|
||||
kind: ArtifactKind;
|
||||
}
|
||||
|
||||
interface FileRow {
|
||||
@@ -49,6 +50,7 @@ interface FileRow {
|
||||
interface ScriptTargetRow {
|
||||
id: number;
|
||||
target_rel_path: string;
|
||||
kind: ArtifactKind;
|
||||
}
|
||||
|
||||
function nowIso(): string {
|
||||
@@ -91,7 +93,8 @@ export async function rollbackPromoteDeployment(promoteId: string): Promise<Roll
|
||||
deployment_id: promoteId,
|
||||
script_id: dep.script_id,
|
||||
script_version_id: dep.script_version_id,
|
||||
prior_version_id: dep.prior_version_id
|
||||
prior_version_id: dep.prior_version_id,
|
||||
kind: 'script'
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -105,18 +108,32 @@ export async function rollbackPromoteDeployment(promoteId: string): Promise<Roll
|
||||
// Map rel_path → scriptId (and prior_version_id) so we can restore the
|
||||
// inventory row's script_version_id correctly during file restore.
|
||||
const scriptByTarget = new Map<string, DepScriptRow>();
|
||||
const kindByScriptId = new Map<number, ArtifactKind>();
|
||||
if (scripts.length > 0) {
|
||||
const placeholders = scripts.map(() => '?').join(',');
|
||||
const targetRows = db()
|
||||
.prepare(`SELECT id, target_rel_path FROM scripts WHERE id IN (${placeholders})`)
|
||||
.prepare(`SELECT id, target_rel_path, kind FROM scripts WHERE id IN (${placeholders})`)
|
||||
.all(...scripts.map((s) => s.script_id)) as ScriptTargetRow[];
|
||||
const targetById = new Map<number, string>();
|
||||
for (const t of targetRows) targetById.set(t.id, t.target_rel_path);
|
||||
for (const t of targetRows) {
|
||||
targetById.set(t.id, t.target_rel_path);
|
||||
kindByScriptId.set(t.id, t.kind);
|
||||
}
|
||||
for (const s of scripts) {
|
||||
const t = targetById.get(s.script_id);
|
||||
if (t) scriptByTarget.set(t, s);
|
||||
}
|
||||
}
|
||||
const kindForRelPath = (relPath: string): ArtifactKind => {
|
||||
const owner = scriptByTarget.get(relPath);
|
||||
if (owner) return owner.kind ?? kindByScriptId.get(owner.script_id) ?? 'script';
|
||||
// Config/baseline aggregate rows have no per-artifact target_rel_path
|
||||
// mapping — the deployment_files row is keyed on the shared cfg name.
|
||||
// Any script/baseline in this deployment tagged as config/baseline
|
||||
// means the rollback for that path lives under the config destination.
|
||||
for (const s of scripts) if (s.kind === 'config' || s.kind === 'baseline') return 'config';
|
||||
return 'script';
|
||||
};
|
||||
|
||||
const newDepId = rollbackDeploymentId(promoteId);
|
||||
const startedAt = nowIso();
|
||||
@@ -133,9 +150,10 @@ export async function rollbackPromoteDeployment(promoteId: string): Promise<Roll
|
||||
const perServerFailures = new Map<string, string>();
|
||||
|
||||
for (const [server, files] of perServer) {
|
||||
const dest = destOf(server);
|
||||
try {
|
||||
for (const f of files) {
|
||||
const kind = kindForRelPath(f.rel_path);
|
||||
const dest = destOfKind(server, kind);
|
||||
const abs = join(dest, f.rel_path);
|
||||
await mkdir(join(dest, dirname(f.rel_path)), { recursive: true });
|
||||
const owningScript = scriptByTarget.get(f.rel_path);
|
||||
@@ -173,8 +191,8 @@ export async function rollbackPromoteDeployment(promoteId: string): Promise<Roll
|
||||
VALUES (?, 'rollback', ?, 'ui', NULL, NULL, NULL, NULL)`
|
||||
);
|
||||
const insertDepScript = db().prepare(
|
||||
`INSERT INTO deployment_scripts (deployment_id, script_id, script_version_id, prior_version_id)
|
||||
VALUES (?, ?, ?, ?)`
|
||||
`INSERT INTO deployment_scripts (deployment_id, script_id, script_version_id, prior_version_id, kind)
|
||||
VALUES (?, ?, ?, ?, ?)`
|
||||
);
|
||||
const insertDepServer = db().prepare(
|
||||
`INSERT INTO deployment_servers
|
||||
@@ -193,7 +211,13 @@ export async function rollbackPromoteDeployment(promoteId: string): Promise<Roll
|
||||
// after rollback is the promote's prior; the "prior" of the rollback
|
||||
// is what was current up until this call (i.e. the promote's version).
|
||||
for (const s of scripts) {
|
||||
insertDepScript.run(newDepId, s.script_id, s.prior_version_id ?? s.script_version_id, s.script_version_id);
|
||||
insertDepScript.run(
|
||||
newDepId,
|
||||
s.script_id,
|
||||
s.prior_version_id ?? s.script_version_id,
|
||||
s.script_version_id,
|
||||
s.kind ?? 'script'
|
||||
);
|
||||
}
|
||||
for (const [server, files] of perServer) {
|
||||
if (perServerFailures.has(server)) {
|
||||
|
||||
Reference in New Issue
Block a user