Release ForgeFlow 0.8.9 Git Validator
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtemp, rm, writeFile, readFile } from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { execFile } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { createRequire } from "node:module";
|
||||
|
||||
const exec = promisify(execFile);
|
||||
const require = createRequire(import.meta.url);
|
||||
const { GitService } = require("../src/main/git-service.cjs");
|
||||
const {
|
||||
GitValidatorService,
|
||||
isSensitiveTrackedPath,
|
||||
sameRemote,
|
||||
} = require("../src/main/git-validator-service.cjs");
|
||||
|
||||
async function git(args, cwd) {
|
||||
return exec("git", args, { cwd, encoding: "utf8" });
|
||||
}
|
||||
|
||||
test("Git Validator scores repository hygiene and offers bounded safe repairs", async (t) => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), "forgeflow-validator-"));
|
||||
t.after(() => rm(root, { recursive: true, force: true }));
|
||||
await git(["init", "-b", "main"], root);
|
||||
await git(["config", "user.name", "ForgeFlow Test"], root);
|
||||
await git(["config", "user.email", "forgeflow@example.invalid"], root);
|
||||
await git(
|
||||
["remote", "add", "origin", "https://gitea.example.test/jens/app.git"],
|
||||
root,
|
||||
);
|
||||
await writeFile(path.join(root, "README.md"), "# App\n", "utf8");
|
||||
await writeFile(path.join(root, ".gitignore"), ".env\n", "utf8");
|
||||
await git(["add", "."], root);
|
||||
await git(["commit", "-m", "Initial"], root);
|
||||
|
||||
const validator = new GitValidatorService({
|
||||
git: new GitService(),
|
||||
gitea: {
|
||||
getBranchProtection: async () => ({
|
||||
protected: false,
|
||||
enableForcePush: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
const repository = {
|
||||
fullName: "jens/app",
|
||||
name: "app",
|
||||
owner: { login: "jens" },
|
||||
defaultBranch: "main",
|
||||
localPath: root,
|
||||
cloneUrl: "https://gitea.example.test/jens/app.git",
|
||||
sshUrl: "git@gitea.example.test:jens/app.git",
|
||||
};
|
||||
const report = await validator.scan(repository);
|
||||
assert.ok(report.score > 60);
|
||||
assert.equal(
|
||||
report.checks.find((check) => check.id === "origin").status,
|
||||
"pass",
|
||||
);
|
||||
assert.equal(
|
||||
report.checks.find((check) => check.id === "default-branch-protection")
|
||||
.fixAction,
|
||||
"protect-default-branch",
|
||||
);
|
||||
const safety = report.checks.find((check) => check.id === "local-safety");
|
||||
assert.equal(safety.safe, true);
|
||||
await validator.repair(repository, safety);
|
||||
const rescanned = await validator.scan(repository);
|
||||
assert.equal(
|
||||
rescanned.checks.find((check) => check.id === "local-safety").status,
|
||||
"pass",
|
||||
);
|
||||
});
|
||||
|
||||
test("Git Validator creates a reviewable gitignore without committing it", async (t) => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), "forgeflow-ignore-"));
|
||||
t.after(() => rm(root, { recursive: true, force: true }));
|
||||
await git(["init", "-b", "main"], root);
|
||||
const validator = new GitValidatorService({ git: new GitService() });
|
||||
const repository = { localPath: root };
|
||||
await validator.repair(repository, { fixAction: "add-gitignore" });
|
||||
const content = await readFile(path.join(root, ".gitignore"), "utf8");
|
||||
assert.match(content, /\.env/);
|
||||
const status = await git(["status", "--short"], root);
|
||||
assert.match(status.stdout, /\?\? \.gitignore/);
|
||||
});
|
||||
|
||||
test("Git Validator recognizes remote aliases and secret-shaped tracked paths", () => {
|
||||
assert.equal(
|
||||
sameRemote(
|
||||
"git@gitea.example.test:jens/app.git",
|
||||
"https://gitea.example.test/jens/app",
|
||||
),
|
||||
true,
|
||||
);
|
||||
assert.equal(isSensitiveTrackedPath(".env.production"), true);
|
||||
assert.equal(isSensitiveTrackedPath("config/private.pem"), true);
|
||||
assert.equal(isSensitiveTrackedPath(".env.example"), false);
|
||||
});
|
||||
Reference in New Issue
Block a user