feat: harden server pull deployments and git hygiene
This commit is contained in:
+77
-2
@@ -73,6 +73,11 @@ const required = [
|
||||
"docs/RELEASE_NOTES_0.8.9.md",
|
||||
"docs/RELEASE_NOTES_0.9.0.md",
|
||||
"docs/RELEASE_NOTES_0.9.1.md",
|
||||
"docs/RELEASE_NOTES_0.9.2.md",
|
||||
"docs/RELEASE_NOTES_0.9.3.md",
|
||||
"docs/RELEASE_NOTES_0.9.4.md",
|
||||
"docs/RELEASE_NOTES_0.9.5.md",
|
||||
"docs/RELEASE_NOTES_0.10.0.md",
|
||||
"docs/UPDATING.md",
|
||||
"docs/DIAGNOSTICS.md",
|
||||
"docs/DEPLOYMENT_SETUP.md",
|
||||
@@ -111,9 +116,9 @@ for (const file of required) await access(path.join(root, file));
|
||||
const packageJson = JSON.parse(
|
||||
await readFile(path.join(root, "package.json"), "utf8"),
|
||||
);
|
||||
if (packageJson.version !== "0.9.1")
|
||||
if (packageJson.version !== "0.10.0")
|
||||
throw new Error(
|
||||
`Expected package version 0.9.1, got ${packageJson.version}.`,
|
||||
`Expected package version 0.10.0, got ${packageJson.version}.`,
|
||||
);
|
||||
const sourceManifest = await readFile(
|
||||
path.join(root, "SOURCE_MANIFEST.txt"),
|
||||
@@ -373,6 +378,76 @@ for (const phrase of [
|
||||
]) {
|
||||
if (!release091.includes(phrase)) throw new Error(`0.9.1 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const release092 = await readFile(path.join(root, "docs/RELEASE_NOTES_0.9.2.md"), "utf8");
|
||||
for (const phrase of [
|
||||
"Push bundle",
|
||||
"server password",
|
||||
"docker ps -a",
|
||||
"DockerMan",
|
||||
"zero counts",
|
||||
]) {
|
||||
if (!release092.includes(phrase)) throw new Error(`0.9.2 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const release093 = await readFile(path.join(root, "docs/RELEASE_NOTES_0.9.3.md"), "utf8");
|
||||
for (const phrase of [
|
||||
"Direct copy",
|
||||
"Compose YAML",
|
||||
"linked automatically",
|
||||
"one-click",
|
||||
"no remote `git ls-remote`",
|
||||
]) {
|
||||
if (!release093.includes(phrase)) throw new Error(`0.9.3 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const release094 = await readFile(path.join(root, "docs/RELEASE_NOTES_0.9.4.md"), "utf8");
|
||||
for (const phrase of [
|
||||
"real Compose files",
|
||||
"stale service hints",
|
||||
"force-recreate",
|
||||
"container ID",
|
||||
"previous container",
|
||||
]) {
|
||||
if (!release094.includes(phrase)) throw new Error(`0.9.4 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const release095 = await readFile(path.join(root, "docs/RELEASE_NOTES_0.9.5.md"), "utf8");
|
||||
for (const phrase of [
|
||||
"Check / fix write access",
|
||||
"exact path, user, owner, group and mode",
|
||||
"preserves existing executable bits",
|
||||
"never implicitly executes `docker compose down`",
|
||||
"retains the backup evidence",
|
||||
]) {
|
||||
if (!release095.includes(phrase)) throw new Error(`0.9.5 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const release0100 = await readFile(path.join(root, "docs/RELEASE_NOTES_0.10.0.md"), "utf8");
|
||||
for (const phrase of [
|
||||
"Server pull",
|
||||
"read-only deploy key",
|
||||
"automatic discovery",
|
||||
"Git Validator",
|
||||
"SSH host fingerprint",
|
||||
]) {
|
||||
if (!release0100.includes(phrase)) throw new Error(`0.10.0 release notes are missing: ${phrase}`);
|
||||
}
|
||||
const configSource = await readFile(path.join(root, "src/main/config-store.cjs"), "utf8");
|
||||
for (const mode of ["server-git", "push-bundle", "monitor-only"]) {
|
||||
if (!configSource.includes(mode)) throw new Error(`Deployment configuration is missing mode: ${mode}`);
|
||||
}
|
||||
const unraidDirectSource = await readFile(path.join(root, "src/main/unraid-deployment-service.cjs"), "utf8");
|
||||
for (const requiredPhrase of [
|
||||
"executePushBundle",
|
||||
"executeServerGitBundle",
|
||||
"configureServerGitAccess",
|
||||
"server-git-access",
|
||||
"git ls-remote --exit-code",
|
||||
"repository-scoped read-only deploy key",
|
||||
]) {
|
||||
if (!unraidDirectSource.includes(requiredPhrase)) throw new Error(`Deployment source is missing: ${requiredPhrase}`);
|
||||
}
|
||||
const serverInventorySource = await readFile(path.join(root, "src/main/server-inventory.cjs"), "utf8");
|
||||
for (const requiredPhrase of ["server-compose-file", "composeDefinitions", "remoteFolderCandidate"]) {
|
||||
if (!serverInventorySource.includes(requiredPhrase)) throw new Error(`Server inventory source is missing: ${requiredPhrase}`);
|
||||
}
|
||||
|
||||
const giteaUpdateSource = await readFile(path.join(root, "src/main/gitea-service.cjs"), "utf8");
|
||||
for (const phrase of [
|
||||
"browser_download_url",
|
||||
|
||||
Reference in New Issue
Block a user