Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
182 lines
5.4 KiB
JavaScript
182 lines
5.4 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { spawnSync } from "node:child_process";
|
|
import {
|
|
chmod,
|
|
copyFile,
|
|
mkdir,
|
|
mkdtemp,
|
|
readFile,
|
|
writeFile
|
|
} from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import test from "node:test";
|
|
|
|
import { createIsolatedGitEnvironment } from "./git-environment.mjs";
|
|
|
|
const sourceScriptPath = resolve(
|
|
dirname(fileURLToPath(import.meta.url)),
|
|
"push-checked.mjs"
|
|
);
|
|
|
|
test("push-checked validates and pushes with the fetched remote lease", async () => {
|
|
const fixture = await createFixture();
|
|
await commitLocalChange(fixture.workspaceRoot, "local change");
|
|
|
|
const result = runPushChecked(fixture);
|
|
|
|
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
assert.equal(
|
|
remoteHead(fixture.remoteRoot),
|
|
localHead(fixture.workspaceRoot)
|
|
);
|
|
assert.equal(await readFile(fixture.pnpmLogPath, "utf8"), "run check:full\n");
|
|
assert.match(result.stdout, /push:checked pushed/u);
|
|
});
|
|
|
|
test("push-checked rejects a dirty worktree before validation", async () => {
|
|
const fixture = await createFixture();
|
|
await writeFile(join(fixture.workspaceRoot, "source.txt"), "dirty\n");
|
|
|
|
const result = runPushChecked(fixture);
|
|
|
|
assert.notEqual(result.status, 0);
|
|
assert.match(result.stderr, /commit or stash local changes/u);
|
|
});
|
|
|
|
test("push-checked lease rejects a concurrent remote update", async () => {
|
|
const fixture = await createFixture();
|
|
const peerRoot = await mkdtemp(join(tmpdir(), "push-checked-peer-"));
|
|
runGit(tmpdir(), [
|
|
"clone",
|
|
"--quiet",
|
|
"--branch",
|
|
"main",
|
|
fixture.remoteRoot,
|
|
peerRoot
|
|
]);
|
|
await commitLocalChange(fixture.workspaceRoot, "local change");
|
|
|
|
const result = runPushChecked(fixture, {
|
|
TUTTI_PUSH_CHECKED_TEST_PEER: peerRoot
|
|
});
|
|
|
|
assert.notEqual(result.status, 0);
|
|
assert.equal(remoteHead(fixture.remoteRoot), localHead(peerRoot));
|
|
assert.notEqual(
|
|
remoteHead(fixture.remoteRoot),
|
|
localHead(fixture.workspaceRoot)
|
|
);
|
|
assert.match(result.stderr, /stale info/u);
|
|
});
|
|
|
|
async function createFixture() {
|
|
const workspaceRoot = await mkdtemp(
|
|
join(tmpdir(), "push-checked-workspace-")
|
|
);
|
|
const remoteRoot = await mkdtemp(join(tmpdir(), "push-checked-remote-"));
|
|
const binRoot = await mkdtemp(join(tmpdir(), "push-checked-bin-"));
|
|
const copiedScriptPath = join(
|
|
workspaceRoot,
|
|
"tools/scripts/push-checked.mjs"
|
|
);
|
|
const pnpmPath = join(binRoot, "pnpm");
|
|
const pnpmLogPath = join(binRoot, "pnpm.log");
|
|
|
|
await mkdir(dirname(copiedScriptPath), { recursive: true });
|
|
await copyFile(sourceScriptPath, copiedScriptPath);
|
|
await writeFile(
|
|
pnpmPath,
|
|
[
|
|
"#!/usr/bin/env node",
|
|
'import { appendFileSync } from "node:fs";',
|
|
'import { spawnSync } from "node:child_process";',
|
|
"",
|
|
'appendFileSync(process.env.TUTTI_PUSH_CHECKED_TEST_LOG, `${process.argv.slice(2).join(" ")}\\n`);',
|
|
"const peer = process.env.TUTTI_PUSH_CHECKED_TEST_PEER;",
|
|
"if (peer) {",
|
|
' const commit = spawnSync("git", ["-C", peer, "-c", "user.email=test@example.com", "-c", "user.name=Test", "commit", "--quiet", "--allow-empty", "-m", "concurrent"], { encoding: "utf8" });',
|
|
" if (commit.status !== 0) process.exit(commit.status ?? 1);",
|
|
' const push = spawnSync("git", ["-C", peer, "push", "--quiet", "origin", "HEAD:main"], { encoding: "utf8" });',
|
|
" if (push.status !== 0) process.exit(push.status ?? 1);",
|
|
"}",
|
|
""
|
|
].join("\n")
|
|
);
|
|
await chmod(pnpmPath, 0o755);
|
|
|
|
runGit(remoteRoot, ["init", "--bare", "--quiet"]);
|
|
runGit(workspaceRoot, ["init", "--quiet", "--initial-branch=main"]);
|
|
await writeFile(join(workspaceRoot, "source.txt"), "initial\n");
|
|
runGit(workspaceRoot, ["add", "."]);
|
|
commit(workspaceRoot, "initial");
|
|
runGit(workspaceRoot, ["remote", "add", "origin", remoteRoot]);
|
|
runGit(workspaceRoot, [
|
|
"push",
|
|
"--quiet",
|
|
"--set-upstream",
|
|
"origin",
|
|
"main"
|
|
]);
|
|
runGit(remoteRoot, ["symbolic-ref", "HEAD", "refs/heads/main"]);
|
|
|
|
return {
|
|
binRoot,
|
|
copiedScriptPath,
|
|
pnpmLogPath,
|
|
remoteRoot,
|
|
workspaceRoot
|
|
};
|
|
}
|
|
|
|
async function commitLocalChange(workspaceRoot, message) {
|
|
await writeFile(join(workspaceRoot, "source.txt"), `${message}\n`);
|
|
runGit(workspaceRoot, ["add", "source.txt"]);
|
|
commit(workspaceRoot, message);
|
|
}
|
|
|
|
function commit(workspaceRoot, message) {
|
|
runGit(workspaceRoot, [
|
|
"-c",
|
|
"user.email=test@example.com",
|
|
"-c",
|
|
"user.name=Test",
|
|
"commit",
|
|
"--quiet",
|
|
"-m",
|
|
message
|
|
]);
|
|
}
|
|
|
|
function runPushChecked(fixture, extraEnv = {}) {
|
|
return spawnSync(process.execPath, [fixture.copiedScriptPath], {
|
|
cwd: fixture.workspaceRoot,
|
|
encoding: "utf8",
|
|
env: createIsolatedGitEnvironment(fixture.workspaceRoot, {
|
|
...process.env,
|
|
...extraEnv,
|
|
PATH: `${fixture.binRoot}:${process.env.PATH ?? ""}`,
|
|
TUTTI_PUSH_CHECKED_TEST_LOG: fixture.pnpmLogPath
|
|
})
|
|
});
|
|
}
|
|
|
|
function localHead(workspaceRoot) {
|
|
return runGit(workspaceRoot, ["rev-parse", "HEAD"]).stdout.trim();
|
|
}
|
|
|
|
function remoteHead(remoteRoot) {
|
|
return runGit(remoteRoot, ["rev-parse", "refs/heads/main"]).stdout.trim();
|
|
}
|
|
|
|
function runGit(cwd, args) {
|
|
const result = spawnSync("git", args, {
|
|
cwd,
|
|
encoding: "utf8",
|
|
env: createIsolatedGitEnvironment(cwd)
|
|
});
|
|
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
return result;
|
|
}
|