hatchkit 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adopt.d.ts +2 -0
- package/dist/adopt.d.ts.map +1 -0
- package/dist/adopt.js +819 -0
- package/dist/adopt.js.map +1 -0
- package/dist/completion.d.ts.map +1 -1
- package/dist/completion.js +3 -0
- package/dist/completion.js.map +1 -1
- package/dist/config.d.ts +30 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +108 -0
- package/dist/config.js.map +1 -1
- package/dist/deploy/coolify-app.d.ts +35 -0
- package/dist/deploy/coolify-app.d.ts.map +1 -0
- package/dist/deploy/coolify-app.js +238 -0
- package/dist/deploy/coolify-app.js.map +1 -0
- package/dist/deploy/pages.js +50 -9
- package/dist/deploy/pages.js.map +1 -1
- package/dist/deploy/rename-domain.d.ts.map +1 -1
- package/dist/deploy/rename-domain.js +26 -6
- package/dist/deploy/rename-domain.js.map +1 -1
- package/dist/deploy/rollback.d.ts +10 -0
- package/dist/deploy/rollback.d.ts.map +1 -0
- package/dist/deploy/rollback.js +295 -0
- package/dist/deploy/rollback.js.map +1 -0
- package/dist/deploy/terraform.d.ts +10 -1
- package/dist/deploy/terraform.d.ts.map +1 -1
- package/dist/deploy/terraform.js +177 -42
- package/dist/deploy/terraform.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +25 -0
- package/dist/doctor.js.map +1 -1
- package/dist/explain.d.ts.map +1 -1
- package/dist/explain.js +5 -0
- package/dist/explain.js.map +1 -1
- package/dist/index.js +377 -122
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +283 -11
- package/dist/prompts.js.map +1 -1
- package/dist/provision/stripe.d.ts +19 -0
- package/dist/provision/stripe.d.ts.map +1 -0
- package/dist/provision/stripe.js +58 -0
- package/dist/provision/stripe.js.map +1 -0
- package/dist/scaffold/dotenvx.d.ts.map +1 -1
- package/dist/scaffold/dotenvx.js +35 -11
- package/dist/scaffold/dotenvx.js.map +1 -1
- package/dist/scaffold/infra.d.ts +21 -1
- package/dist/scaffold/infra.d.ts.map +1 -1
- package/dist/scaffold/infra.js +66 -20
- package/dist/scaffold/infra.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +7 -0
- package/dist/status.js.map +1 -1
- package/dist/utils/cloudflare-api.d.ts +23 -0
- package/dist/utils/cloudflare-api.d.ts.map +1 -1
- package/dist/utils/cloudflare-api.js +31 -0
- package/dist/utils/cloudflare-api.js.map +1 -1
- package/dist/utils/coolify-api.d.ts +64 -3
- package/dist/utils/coolify-api.d.ts.map +1 -1
- package/dist/utils/coolify-api.js +99 -3
- package/dist/utils/coolify-api.js.map +1 -1
- package/dist/utils/run-ledger.d.ts +68 -0
- package/dist/utils/run-ledger.d.ts.map +1 -0
- package/dist/utils/run-ledger.js +99 -0
- package/dist/utils/run-ledger.js.map +1 -0
- package/dist/utils/secrets.d.ts +2 -0
- package/dist/utils/secrets.d.ts.map +1 -1
- package/dist/utils/secrets.js +2 -0
- package/dist/utils/secrets.js.map +1 -1
- package/package.json +2 -2
- package/scripts/release-prep.mjs +130 -95
package/scripts/release-prep.mjs
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*
|
|
3
|
-
* release-prep —
|
|
4
|
-
* changes get committed and shipped with the release instead of hanging
|
|
5
|
-
* around on main afterwards.
|
|
3
|
+
* release-prep — strict pre-release verification.
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Refuses to release if any of the three repos (hatchkit main,
|
|
6
|
+
* infra submodule, starter submodule) has uncommitted or untracked
|
|
7
|
+
* changes. Exits with a clear list of which repos need handling and
|
|
8
|
+
* what's dirty in each — release scripts assume a clean baseline so
|
|
9
|
+
* the version commit + tag, the npm publish, and the cross-repo push
|
|
10
|
+
* all line up against the same set of trees.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Skip the whole thing with RELEASE_SKIP_PREP=1.
|
|
12
|
+
* ALSO refuses when the local cli/package.json version is at-or-
|
|
13
|
+
* behind the version published to npm. `npm version patch` increments
|
|
14
|
+
* from the LOCAL version, not the registry's, so drift between the
|
|
15
|
+
* two leads to the script generating a number that's already taken
|
|
16
|
+
* and the publish step crashing after build/typecheck. Catch it up
|
|
17
|
+
* front instead.
|
|
18
|
+
*
|
|
19
|
+
* Skip with RELEASE_SKIP_PREP=1 (e.g. a CI-driven release that's
|
|
20
|
+
* already vouched for cleanliness). RELEASE_SKIP_NPM_CHECK=1 only
|
|
21
|
+
* skips the npm-version comparison, useful offline.
|
|
23
22
|
*/
|
|
24
23
|
|
|
25
|
-
import { execSync
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
24
|
+
import { execSync } from "node:child_process";
|
|
25
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
26
|
+
import { join, relative } from "node:path";
|
|
28
27
|
|
|
29
28
|
if (process.env.RELEASE_SKIP_PREP === "1") {
|
|
30
29
|
console.log(" release-prep: RELEASE_SKIP_PREP=1 — skipping.");
|
|
@@ -35,96 +34,132 @@ function sh(cmd, opts = {}) {
|
|
|
35
34
|
return execSync(cmd, { encoding: "utf8", ...opts }).trim();
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
// Find the repo root so git commands work no matter where the script was
|
|
39
|
-
// launched from (pnpm invokes scripts with cwd=cli/).
|
|
40
37
|
let repoRoot;
|
|
41
38
|
try {
|
|
42
39
|
repoRoot = sh("git rev-parse --show-toplevel");
|
|
43
|
-
} catch
|
|
40
|
+
} catch {
|
|
44
41
|
console.error(" release-prep: not inside a git repo. Aborting.");
|
|
45
42
|
process.exit(1);
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
const repos = [
|
|
46
|
+
{ label: "hatchkit (main)", path: repoRoot, hint: `cd ${repoRoot}` },
|
|
47
|
+
{
|
|
48
|
+
label: "infra (submodule)",
|
|
49
|
+
path: join(repoRoot, "infra"),
|
|
50
|
+
hint: `cd ${join(repoRoot, "infra")}`,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
label: "starter (submodule)",
|
|
54
|
+
path: join(repoRoot, "starter"),
|
|
55
|
+
hint: `cd ${join(repoRoot, "starter")}`,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
53
58
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return { code, path };
|
|
60
|
-
});
|
|
59
|
+
const dirty = [];
|
|
60
|
+
for (const r of repos) {
|
|
61
|
+
// Submodule may not be initialized — skip silently rather than fail.
|
|
62
|
+
// (`.git` is a file inside an initialized submodule, a dir at the root.)
|
|
63
|
+
if (!existsSync(join(r.path, ".git"))) continue;
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
console.error(
|
|
73
|
-
"\n Resolve manually: gitignore, delete, or commit yourself and re-run the release.",
|
|
74
|
-
);
|
|
75
|
-
process.exit(1);
|
|
65
|
+
let status;
|
|
66
|
+
try {
|
|
67
|
+
status = sh("git status --porcelain", { cwd: r.path });
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(` release-prep: couldn't read ${r.label}: ${err.message}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (status) {
|
|
73
|
+
dirty.push({ ...r, status });
|
|
74
|
+
}
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
if (dirty.length === 0) {
|
|
78
|
+
// Tree is clean — also check that the local version isn't lagging
|
|
79
|
+
// behind what's on npm. `npm version patch` would silently bump
|
|
80
|
+
// into a taken number otherwise.
|
|
81
|
+
if (process.env.RELEASE_SKIP_NPM_CHECK !== "1") {
|
|
82
|
+
const driftError = checkNpmDrift(repoRoot);
|
|
83
|
+
if (driftError) {
|
|
84
|
+
console.error(`\n ✗ release-prep: ${driftError}\n`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
88
87
|
}
|
|
89
|
-
console.
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
-
process.exit(1);
|
|
88
|
+
console.log(" ✓ release-prep: all trees clean. Continuing release.");
|
|
89
|
+
process.exit(0);
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
resolve(answer.trim() || DEFAULT_MSG);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
} else {
|
|
107
|
-
console.log(` release-prep: non-interactive — using default message "${DEFAULT_MSG}".`);
|
|
92
|
+
console.error("\n ✗ release-prep: cannot release — dangling changes.\n");
|
|
93
|
+
for (const r of dirty) {
|
|
94
|
+
const rel = r.path === repoRoot ? "." : relative(repoRoot, r.path);
|
|
95
|
+
console.error(` ── ${r.label} (${rel}/)`);
|
|
96
|
+
for (const line of r.status.split("\n")) {
|
|
97
|
+
console.error(` ${line}`);
|
|
98
|
+
}
|
|
99
|
+
console.error();
|
|
108
100
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// commit); the secret-path guard above is what keeps it safe.
|
|
113
|
-
const add = spawnSync("git", ["add", "-A"], { cwd: repoRoot, stdio: "inherit" });
|
|
114
|
-
if (add.status !== 0) {
|
|
115
|
-
console.error(" release-prep: `git add -A` failed.");
|
|
116
|
-
process.exit(add.status ?? 1);
|
|
101
|
+
console.error(" Handle each tree before releasing:");
|
|
102
|
+
for (const r of dirty) {
|
|
103
|
+
console.error(` ${r.hint} && git status # commit / stash / discard`);
|
|
117
104
|
}
|
|
105
|
+
console.error("\n Then re-run the release.\n");
|
|
106
|
+
process.exit(1);
|
|
118
107
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
108
|
+
/** Returns null on success, an error message string when the local
|
|
109
|
+
* cli/package.json is at-or-behind what's published on npm. We only
|
|
110
|
+
* read the registry — never write — so it's safe to run blind. */
|
|
111
|
+
function checkNpmDrift(repoRoot) {
|
|
112
|
+
const pkgPath = join(repoRoot, "cli", "package.json");
|
|
113
|
+
if (!existsSync(pkgPath)) return null; // not the hatchkit monorepo layout
|
|
114
|
+
let pkg;
|
|
115
|
+
try {
|
|
116
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return `couldn't parse cli/package.json — ${err.message}`;
|
|
119
|
+
}
|
|
120
|
+
const local = pkg.version;
|
|
121
|
+
const name = pkg.name;
|
|
122
|
+
if (!local || !name) return null;
|
|
123
|
+
|
|
124
|
+
let registry;
|
|
125
|
+
try {
|
|
126
|
+
registry = sh(`npm view ${name} version`, { stdio: ["ignore", "pipe", "ignore"] });
|
|
127
|
+
} catch {
|
|
128
|
+
// 404 (package doesn't exist yet on npm) is fine — first publish.
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
if (!registry) return null;
|
|
132
|
+
|
|
133
|
+
// Only refuse when local is BEHIND registry. Equal is the post-sync
|
|
134
|
+
// state — `npm version patch` increments past it cleanly.
|
|
135
|
+
if (compareSemver(local, registry) < 0) {
|
|
136
|
+
return [
|
|
137
|
+
`local ${name}@${local} is behind the registry's ${registry}.`,
|
|
138
|
+
"",
|
|
139
|
+
" `npm version patch` increments from the LOCAL version, so a release now",
|
|
140
|
+
" would try to publish a version that's already taken. Sync first:",
|
|
141
|
+
"",
|
|
142
|
+
` cd ${join(repoRoot, "cli")}`,
|
|
143
|
+
` npm version ${registry} --no-git-tag-version # match the registry`,
|
|
144
|
+
` cd ${repoRoot}`,
|
|
145
|
+
` git add cli/package.json cli/package-lock.json`,
|
|
146
|
+
` git commit -m "chore: release v${registry}"`,
|
|
147
|
+
` git tag v${registry}`,
|
|
148
|
+
"",
|
|
149
|
+
" Then re-run the release; it'll bump cleanly past that.",
|
|
150
|
+
].join("\n");
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
128
153
|
}
|
|
129
154
|
|
|
130
|
-
|
|
155
|
+
/** Tiny semver compare — returns -1 / 0 / 1 for a vs b. We only feed
|
|
156
|
+
* it values that come straight out of package.json + npm view, so
|
|
157
|
+
* pre-release / build-metadata strings are out of scope. */
|
|
158
|
+
function compareSemver(a, b) {
|
|
159
|
+
const [aa, bb] = [a, b].map((v) => v.split(".").map((n) => Number(n) || 0));
|
|
160
|
+
for (let i = 0; i < 3; i++) {
|
|
161
|
+
if ((aa[i] ?? 0) > (bb[i] ?? 0)) return 1;
|
|
162
|
+
if ((aa[i] ?? 0) < (bb[i] ?? 0)) return -1;
|
|
163
|
+
}
|
|
164
|
+
return 0;
|
|
165
|
+
}
|