固化部署体检与备份合同刷新(08-02-deployment-preflight-backup-contract-refresh)
这个提交包含在:
@@ -7,6 +7,9 @@ const { promisify } = require("node:util");
|
||||
const execFileAsync = promisify(execFile);
|
||||
const ROOT_DIR = path.resolve(__dirname, "../../../..");
|
||||
const PREFLIGHT = path.join(ROOT_DIR, "deploy/trialrun/preflight-remote.sh");
|
||||
const AGGREGATE_PREFLIGHT = path.join(ROOT_DIR, "deploy/trialrun/check-existing-deployment.sh");
|
||||
const REFRESH_HELPER = path.join(ROOT_DIR, "scripts/refresh-deployment-contract.sh");
|
||||
const REFRESH_INSTALLER = path.join(ROOT_DIR, "deploy/trialrun/install-deployment-contract-refresh.sh");
|
||||
|
||||
describe("deployment safety contract", () => {
|
||||
let fixtureRoot;
|
||||
@@ -77,11 +80,35 @@ describe("deployment safety contract", () => {
|
||||
expect(deploy.indexOf("REMOTE_PREFLIGHT_SCRIPT")).toBeGreaterThanOrEqual(0);
|
||||
expect(deploy.indexOf('>>> 3. 同步前只读校验远端部署合同')).toBeLessThan(deploy.indexOf("rsync -az --delete"));
|
||||
expect(deploy.indexOf('>>> 3. 同步前只读校验远端部署合同')).toBeLessThan(deploy.indexOf("mkdir -p '${REMOTE_DIR}'"));
|
||||
expect(wrapper).toContain("systemctl show '${DEPLOY_CONTRACT_UNIT}' -p Environment --value");
|
||||
expect(wrapper).toContain("check-existing-deployment.sh");
|
||||
expect(wrapper.indexOf("check-existing-deployment.sh")).toBeLessThan(wrapper.indexOf('bash "$ROOT_DIR/deploy/trialrun/deploy.sh"'));
|
||||
expect(wrapper).not.toContain("docker inspect");
|
||||
expect(wrapper).not.toContain("working_dir");
|
||||
expect(wrapper).toContain("DEPLOY_DATA_MODE=existing");
|
||||
expect(wrapper).toContain("SYNC_ENV=0");
|
||||
expect(wrapper).toContain("DEPLOY_DEFER_FINAL_SUCCESS=1");
|
||||
expect(wrapper.indexOf('ssh "$DEPLOY_REFRESH_SERVER" refresh')).toBeGreaterThan(wrapper.indexOf('bash "$ROOT_DIR/deploy/trialrun/deploy.sh"'));
|
||||
expect(wrapper).toContain("DEPLOYED_BUT_CONTRACT_REFRESH_FAILED");
|
||||
});
|
||||
|
||||
it("aggregates preflight checks and keeps the root helper self-contained", async () => {
|
||||
const aggregate = await require("node:fs/promises").readFile(AGGREGATE_PREFLIGHT, "utf8");
|
||||
const helper = await require("node:fs/promises").readFile(REFRESH_HELPER, "utf8");
|
||||
const installer = await require("node:fs/promises").readFile(REFRESH_INSTALLER, "utf8");
|
||||
expect(aggregate).toContain("set -uo pipefail");
|
||||
expect(aggregate).not.toMatch(/^set\s+-[A-Za-z]*e[A-Za-z]*(?:\s|$)/m);
|
||||
expect(aggregate).toContain("CHECK_NAMES=(");
|
||||
expect(aggregate).toContain("root_ssh_identity");
|
||||
expect(aggregate).toContain("refresh_program");
|
||||
expect(helper).toContain("SSH_ORIGINAL_COMMAND");
|
||||
expect(helper).toContain("20-active-build.conf");
|
||||
expect(helper).toContain("refresh_program_integrity_invalid");
|
||||
expect(helper).not.toContain("eval ");
|
||||
expect(helper).not.toContain("bash -c");
|
||||
expect(helper).not.toContain("REMOTE_DIR/");
|
||||
expect(installer).toContain("dedicated key already has unmanaged or unrestricted root authorization");
|
||||
expect(installer).toContain("no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty,no-user-rc");
|
||||
expect(installer).toContain("managed forced-command marker is malformed");
|
||||
});
|
||||
|
||||
it("keeps immutable build args after stable dependency layers", async () => {
|
||||
|
||||
在新工单中引用
屏蔽一个用户