Scripts
This commit is contained in:
parent
3cde94c222
commit
f18a8fd409
3 changed files with 125 additions and 1 deletions
|
|
@ -27,3 +27,15 @@ Preview without network writes.
|
|||
```sh
|
||||
bun scripts/forgejo-modules.ts --dry-run
|
||||
```
|
||||
|
||||
To commit changed integration module directories with generic `chore: update @muddle/<name> integration` messages and push their subtree history, preview the operation first. Unchanged modules are also synced so newly created Forgejo repositories receive their initial branch.
|
||||
|
||||
```sh
|
||||
bun scripts/forgejo-push.ts
|
||||
```
|
||||
|
||||
Push only after review. This requires the same token and creates local commits.
|
||||
|
||||
```sh
|
||||
MUDDLE_FORGEJO_TOKEN=token bun scripts/forgejo-push.ts --push
|
||||
```
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@
|
|||
"lint": "bunx eslint . --ignore-pattern node_modules --ignore-pattern ametrine --ignore-pattern .opencode --ignore-pattern dist --ignore-pattern .git --ignore-pattern .cache --ignore-pattern .next --ignore-pattern .turbo --ignore-pattern .vercel --ignore-pattern .vscode --ignore-pattern .idea",
|
||||
"format": "bun run cli.ts fmt .",
|
||||
"muddle": "bun run cli.ts",
|
||||
"forgejo:modules": "bun scripts/forgejo-modules.ts --dry-run"
|
||||
"forgejo:modules": "bun scripts/forgejo-modules.ts --dry-run",
|
||||
"forgejo:push": "bun scripts/forgejo-push.ts"
|
||||
},
|
||||
"bin": {
|
||||
"muddle": "./cli.ts"
|
||||
|
|
|
|||
111
scripts/forgejo-push.ts
Normal file
111
scripts/forgejo-push.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env bun
|
||||
import { chmod, rm, writeFile } from "node:fs/promises";
|
||||
import { join, resolve } from "node:path";
|
||||
|
||||
const root = resolve(import.meta.dir, "..");
|
||||
const modules = [
|
||||
"amezing",
|
||||
"analysis",
|
||||
"astro",
|
||||
"database",
|
||||
"latex",
|
||||
"mdx",
|
||||
"optimize",
|
||||
"prettier-plugin",
|
||||
"shadcn",
|
||||
"tailwind",
|
||||
];
|
||||
const api = (process.env.MUDDLE_FORGEJO_URL ?? "https://git.crit.rip").replace(
|
||||
/\/$/,
|
||||
"",
|
||||
);
|
||||
const owner = process.env.MUDDLE_FORGEJO_OWNER ?? "mdl";
|
||||
const arguments_ = process.argv.slice(2);
|
||||
const push = arguments_.includes("--push");
|
||||
const requested = arguments_.filter((argument) => !argument.startsWith("--"));
|
||||
const selected = requested.length > 0 ? requested : modules;
|
||||
const token = process.env.MUDDLE_FORGEJO_TOKEN;
|
||||
|
||||
if (push && !token) {
|
||||
throw new Error(
|
||||
"Set MUDDLE_FORGEJO_TOKEN before using --push.",
|
||||
);
|
||||
}
|
||||
for (const name of selected) {
|
||||
if (!modules.includes(name)) {
|
||||
throw new Error(`Unknown integration module ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function run(
|
||||
command: string[],
|
||||
environment: Record<string, string | undefined> = {},
|
||||
): Promise<string> {
|
||||
const child = Bun.spawn(command, {
|
||||
cwd: root,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env: { ...process.env, ...environment },
|
||||
});
|
||||
const [stdout, stderr, status] = await Promise.all([
|
||||
new Response(child.stdout).text(),
|
||||
new Response(child.stderr).text(),
|
||||
child.exited,
|
||||
]);
|
||||
if (status !== 0) {
|
||||
throw new Error(`${command.join(" ")} failed\n${stderr || stdout}`);
|
||||
}
|
||||
return stdout.trim();
|
||||
}
|
||||
|
||||
async function changed(path: string): Promise<boolean> {
|
||||
const tracked = await run(["git", "status", "--porcelain", "--", path]);
|
||||
return tracked.length > 0;
|
||||
}
|
||||
|
||||
let askPass: string | undefined;
|
||||
try {
|
||||
if (push && token) {
|
||||
askPass = join(import.meta.dir, `.forgejo-askpass-${process.pid}`);
|
||||
await writeFile(
|
||||
askPass,
|
||||
`#!/bin/sh\ncase "$1" in *Username*) printf '%s' token ;; *) printf '%s' "$MUDDLE_FORGEJO_TOKEN" ;; esac\n`,
|
||||
);
|
||||
await chmod(askPass, 0o700);
|
||||
}
|
||||
|
||||
for (const name of selected) {
|
||||
const prefix = `modules/${name}`;
|
||||
const hasChanges = await changed(prefix);
|
||||
const message = `chore: update @muddle/${name} integration`;
|
||||
if (!push) {
|
||||
console.log(
|
||||
`would ${hasChanges ? `commit with "${message}" and ` : ""}sync @muddle/${name} to ${api}/${owner}/${name}.git`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (hasChanges) {
|
||||
await run(["git", "add", "--", prefix]);
|
||||
await run(["git", "commit", "-m", message, "--", prefix]);
|
||||
}
|
||||
const branch = await run([
|
||||
"git",
|
||||
"subtree",
|
||||
"split",
|
||||
"--prefix",
|
||||
prefix,
|
||||
]);
|
||||
await run([
|
||||
"git",
|
||||
"push",
|
||||
`${api}/${owner}/${name}.git`,
|
||||
`${branch}:refs/heads/main`,
|
||||
], {
|
||||
GIT_ASKPASS: askPass,
|
||||
GIT_TERMINAL_PROMPT: "0",
|
||||
});
|
||||
console.log(`pushed @muddle/${name}`);
|
||||
}
|
||||
} finally {
|
||||
if (askPass) await rm(askPass, { force: true });
|
||||
}
|
||||
Loading…
Reference in a new issue