seedproject-web/content-pipeline/scripts/lib/git.mjs
Carlos Arias 1559ce017d chore: scaffold SeedProject base (Phase 1)
Clean-room copy of the reusable engines from comiida, with all
instance data, secrets, dependencies, and build output excluded:
- app/         Astro theme skeleton (no comiida blog posts; hero image -> placeholder)
- api/         SeedProject PHP framework (no vendor/.env/config.php)
- content-pipeline/  engine only (scripts/admin/prompts; empty runtime state)
- astroagent.config.json + app/.astroagent/skills

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYHWLHihq3v9nxNwoPCKSn
2026-07-04 22:53:10 +00:00

37 lines
1.4 KiB
JavaScript

import { spawn } from "node:child_process";
function run(cmd, args, opts = {}) {
return new Promise((resolve, reject) => {
let out = "";
let err = "";
const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"], ...opts });
child.stdout.on("data", (b) => (out += b));
child.stderr.on("data", (b) => (err += b));
child.on("error", reject);
child.on("close", (code) =>
code === 0
? resolve(out)
: reject(new Error(`git ${args.join(" ")} exited ${code}: ${err.trim()}`))
);
});
}
/**
* Stage the given paths (relative to projectRoot) and commit if anything changed.
* Best-effort: never throws, so a git hiccup can't block a live publish. Returns
* the new commit hash, or null if nothing was staged / git failed.
* Keeping the working tree committed is what lets the console's git worktree +
* `merge --ff-only` operations run against a clean tree.
*/
export async function gitCommitPaths(projectRoot, paths, message) {
try {
await run("git", ["-C", projectRoot, "add", "--", ...paths]);
const staged = await run("git", ["-C", projectRoot, "diff", "--cached", "--name-only"]);
if (!staged.trim()) return null;
await run("git", ["-C", projectRoot, "commit", "-q", "-m", message]);
return (await run("git", ["-C", projectRoot, "rev-parse", "HEAD"])).trim();
} catch (e) {
console.warn(`[git] commit skipped: ${e.message}`);
return null;
}
}