@lishugupta652/dokploy 0.1.3 → 0.1.5
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/.githooks/commit-msg +9 -0
- package/.githooks/pre-commit +2 -7
- package/CHANGELOG.md +28 -0
- package/README.md +34 -2
- package/dist/client.js +27 -4
- package/dist/index.js +0 -0
- package/package.json +5 -2
- package/scripts/commit-msg.mjs +185 -0
- package/scripts/generate-changelog.mjs +169 -0
- package/scripts/publish.sh +133 -0
package/.githooks/pre-commit
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
PACKAGE_DIR="."
|
|
7
|
-
fi
|
|
8
|
-
|
|
9
|
-
node "$PACKAGE_DIR/scripts/bump-version-on-commit.mjs"
|
|
10
|
-
git add "$PACKAGE_DIR/package.json" "$PACKAGE_DIR/package-lock.json"
|
|
4
|
+
# Commit message validation and semver bumping happen in commit-msg.
|
|
5
|
+
exit 0
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.5 - 2026-04-13
|
|
4
|
+
|
|
5
|
+
_Initial changelog generated from repository history._
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- scripts (2930c10)
|
|
10
|
+
|
|
11
|
+
### Other Changes
|
|
12
|
+
|
|
13
|
+
- add script for deployment (c511505)
|
|
14
|
+
- first commit (3f5e457)
|
|
15
|
+
|
|
16
|
+
## 0.1.4 - 2026-04-13
|
|
17
|
+
|
|
18
|
+
_Initial changelog generated from repository history._
|
|
19
|
+
|
|
20
|
+
### Fixes
|
|
21
|
+
|
|
22
|
+
- scripts (2930c10)
|
|
23
|
+
|
|
24
|
+
### Other Changes
|
|
25
|
+
|
|
26
|
+
- add script for deployment (c511505)
|
|
27
|
+
- first commit (3f5e457)
|
|
28
|
+
|
package/README.md
CHANGED
|
@@ -24,6 +24,14 @@ npm install -g @lishugupta652/dokploy
|
|
|
24
24
|
dokploy --help
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
For a local install, run the binary through npm:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @lishugupta652/dokploy
|
|
31
|
+
npx dokploy --help
|
|
32
|
+
npm exec dokploy -- --help
|
|
33
|
+
```
|
|
34
|
+
|
|
27
35
|
## Environment
|
|
28
36
|
|
|
29
37
|
```bash
|
|
@@ -31,7 +39,7 @@ export DOKPLOY_API_KEY=your-api-key
|
|
|
31
39
|
export DOKPLOY_HOST=https://your-dokploy.example.com/api
|
|
32
40
|
```
|
|
33
41
|
|
|
34
|
-
`DOKPLOY_HOST` is optional when `host` is set in the YAML file. API keys are never read from config.
|
|
42
|
+
`DOKPLOY_HOST` is optional when `host` is set in the YAML file. API keys are never read from config. The CLI accepts either `https://your-dokploy.example.com` or `https://your-dokploy.example.com/api` and normalizes root hosts to `/api`.
|
|
35
43
|
|
|
36
44
|
## Commands
|
|
37
45
|
|
|
@@ -39,6 +47,7 @@ export DOKPLOY_HOST=https://your-dokploy.example.com/api
|
|
|
39
47
|
dokploy projects --host https://your-dokploy.example.com/api
|
|
40
48
|
dokploy projects --summary --host https://your-dokploy.example.com/api
|
|
41
49
|
dokploy projects --json --host https://your-dokploy.example.com/api
|
|
50
|
+
dokploy projects --host https://your-dokploy.example.com
|
|
42
51
|
dokploy apply -f dokploy.yaml
|
|
43
52
|
dokploy apply -f dokploy.yaml --dry-run
|
|
44
53
|
dokploy deploy frontend -f dokploy.yaml
|
|
@@ -60,6 +69,19 @@ npm publish --access public
|
|
|
60
69
|
|
|
61
70
|
`prepublishOnly` runs the TypeScript check and build before publishing.
|
|
62
71
|
|
|
72
|
+
Or use the helper script:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
./scripts/publish.sh npm
|
|
76
|
+
./scripts/publish.sh npm --publish
|
|
77
|
+
./scripts/publish.sh pnpm
|
|
78
|
+
./scripts/publish.sh pnpm --publish
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The script defaults to dry-run mode and publishes only when `--publish` is passed.
|
|
82
|
+
|
|
83
|
+
Publishing also generates `CHANGELOG.md` from git commits since the latest tag. Conventional Commit messages are grouped into sections such as Features, Fixes, Breaking Changes, and Chores.
|
|
84
|
+
|
|
63
85
|
## Commit Version Hook
|
|
64
86
|
|
|
65
87
|
Install the repo hook once:
|
|
@@ -68,7 +90,17 @@ Install the repo hook once:
|
|
|
68
90
|
npm run hooks:install
|
|
69
91
|
```
|
|
70
92
|
|
|
71
|
-
The
|
|
93
|
+
The `commit-msg` hook enforces Conventional Commits and bumps `package.json` plus `package-lock.json` from the commit message:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
feat: add project listing # minor
|
|
97
|
+
fix(projects): normalize host # patch
|
|
98
|
+
perf: improve status lookup # patch
|
|
99
|
+
feat!: change config schema # major
|
|
100
|
+
docs: update usage # no version bump
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use `SKIP_DOKPLOY_VERSION_BUMP=1` to keep commit validation but skip version changes. Use `SKIP_DOKPLOY_COMMIT_CHECK=1` only when you intentionally need to bypass the hook.
|
|
72
104
|
|
|
73
105
|
## Notes
|
|
74
106
|
|
package/dist/client.js
CHANGED
|
@@ -14,7 +14,7 @@ export class DokployClient {
|
|
|
14
14
|
baseUrl;
|
|
15
15
|
apiKey;
|
|
16
16
|
constructor(options) {
|
|
17
|
-
this.baseUrl = options.host
|
|
17
|
+
this.baseUrl = normalizeDokployHost(options.host);
|
|
18
18
|
this.apiKey = options.apiKey;
|
|
19
19
|
}
|
|
20
20
|
async get(endpoint, query) {
|
|
@@ -76,12 +76,35 @@ export class DokployClient {
|
|
|
76
76
|
}
|
|
77
77
|
formatErrorMessage(status, endpoint, body) {
|
|
78
78
|
const detail = extractErrorDetail(body);
|
|
79
|
-
const hint = status
|
|
80
|
-
? " Check DOKPLOY_API_KEY and the API key permissions."
|
|
81
|
-
: "";
|
|
79
|
+
const hint = errorHint(status, body);
|
|
82
80
|
return `Dokploy API ${endpoint} failed with HTTP ${status}${detail ? `: ${detail}` : ""}.${hint}`;
|
|
83
81
|
}
|
|
84
82
|
}
|
|
83
|
+
function normalizeDokployHost(host) {
|
|
84
|
+
const url = new URL(host);
|
|
85
|
+
const pathname = url.pathname.replace(/\/+$/, "");
|
|
86
|
+
if (!pathname || pathname === "/") {
|
|
87
|
+
url.pathname = "/api";
|
|
88
|
+
}
|
|
89
|
+
else if (!pathname.endsWith("/api")) {
|
|
90
|
+
url.pathname = `${pathname}/api`;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
url.pathname = pathname;
|
|
94
|
+
}
|
|
95
|
+
url.search = "";
|
|
96
|
+
url.hash = "";
|
|
97
|
+
return url.toString().replace(/\/+$/, "");
|
|
98
|
+
}
|
|
99
|
+
function errorHint(status, body) {
|
|
100
|
+
if (status === 401 || status === 403) {
|
|
101
|
+
return " Check DOKPLOY_API_KEY and the API key permissions.";
|
|
102
|
+
}
|
|
103
|
+
if (status === 404 && /<html/i.test(body)) {
|
|
104
|
+
return " Dokploy returned an HTML page, which usually means the request hit the web UI instead of the API. The CLI now normalizes root hosts to /api; verify the host points to your Dokploy server.";
|
|
105
|
+
}
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
85
108
|
function extractErrorDetail(body) {
|
|
86
109
|
if (!body.trim())
|
|
87
110
|
return undefined;
|
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lishugupta652/dokploy",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A YAML-driven CLI for applying Dokploy projects through the Dokploy API.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,15 +11,18 @@
|
|
|
11
11
|
"examples",
|
|
12
12
|
"scripts",
|
|
13
13
|
".githooks",
|
|
14
|
+
"CHANGELOG.md",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"changelog": "node scripts/generate-changelog.mjs",
|
|
18
20
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
19
21
|
"dev": "tsx src/index.ts",
|
|
22
|
+
"commit-msg": "node scripts/commit-msg.mjs",
|
|
20
23
|
"hooks:install": "node scripts/install-git-hooks.mjs",
|
|
21
24
|
"prepack": "npm run build",
|
|
22
|
-
"prepublishOnly": "npm run check && npm run build",
|
|
25
|
+
"prepublishOnly": "npm run check && npm run build && npm run changelog",
|
|
23
26
|
"version:commit": "node scripts/bump-version-on-commit.mjs"
|
|
24
27
|
},
|
|
25
28
|
"publishConfig": {
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const allowedTypes = new Set([
|
|
8
|
+
"feat",
|
|
9
|
+
"fix",
|
|
10
|
+
"perf",
|
|
11
|
+
"refactor",
|
|
12
|
+
"docs",
|
|
13
|
+
"test",
|
|
14
|
+
"build",
|
|
15
|
+
"ci",
|
|
16
|
+
"chore",
|
|
17
|
+
"style",
|
|
18
|
+
"revert",
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const bumpByType = new Map([
|
|
22
|
+
["feat", "minor"],
|
|
23
|
+
["fix", "patch"],
|
|
24
|
+
["perf", "patch"],
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
const messagePath = process.argv[2];
|
|
28
|
+
if (!messagePath) {
|
|
29
|
+
console.error("Missing commit message file path.");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const message = readFileSync(messagePath, "utf8");
|
|
34
|
+
const header = firstCommitMessageLine(message);
|
|
35
|
+
|
|
36
|
+
if (!header) {
|
|
37
|
+
fail("Commit message is empty.");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (process.env.SKIP_DOKPLOY_COMMIT_CHECK === "1") {
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (isGeneratedCommit(header)) {
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const parsed = parseConventionalCommit(header);
|
|
49
|
+
if (!parsed) {
|
|
50
|
+
fail(`Invalid commit message: ${header}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!allowedTypes.has(parsed.type)) {
|
|
54
|
+
fail(`Unsupported commit type "${parsed.type}".`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (parsed.subject.trim().length === 0) {
|
|
58
|
+
fail("Commit subject cannot be empty.");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const bump = resolveBump(parsed, message);
|
|
62
|
+
if (!bump) {
|
|
63
|
+
console.log(`Commit type "${parsed.type}" does not change the package version.`);
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (process.env.SKIP_DOKPLOY_VERSION_BUMP === "1") {
|
|
68
|
+
console.log(`Skipping ${bump} version bump because SKIP_DOKPLOY_VERSION_BUMP=1.`);
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
73
|
+
const packageJsonPath = path.join(packageDir, "package.json");
|
|
74
|
+
const packageLockPath = path.join(packageDir, "package-lock.json");
|
|
75
|
+
|
|
76
|
+
const packageJson = readJson(packageJsonPath);
|
|
77
|
+
const nextVersion = bumpVersion(packageJson.version, bump);
|
|
78
|
+
|
|
79
|
+
if (process.env.DOKPLOY_VERSION_DRY_RUN === "1") {
|
|
80
|
+
console.log(`${parsed.type} commit will create ${bump} version: ${packageJson.version} -> ${nextVersion}`);
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
packageJson.version = nextVersion;
|
|
85
|
+
writeJson(packageJsonPath, packageJson);
|
|
86
|
+
|
|
87
|
+
const packageLock = readJson(packageLockPath);
|
|
88
|
+
packageLock.name = packageJson.name;
|
|
89
|
+
packageLock.version = nextVersion;
|
|
90
|
+
if (packageLock.packages?.[""]) {
|
|
91
|
+
packageLock.packages[""].name = packageJson.name;
|
|
92
|
+
packageLock.packages[""].version = nextVersion;
|
|
93
|
+
packageLock.packages[""].bin = packageJson.bin;
|
|
94
|
+
}
|
|
95
|
+
writeJson(packageLockPath, packageLock);
|
|
96
|
+
|
|
97
|
+
execFileSync("git", ["-C", packageDir, "add", packageJsonPath, packageLockPath], {
|
|
98
|
+
stdio: "inherit",
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
console.log(`${parsed.type} commit created ${bump} version: ${packageJson.name}@${nextVersion}`);
|
|
102
|
+
|
|
103
|
+
function firstCommitMessageLine(rawMessage) {
|
|
104
|
+
return rawMessage
|
|
105
|
+
.split(/\r?\n/)
|
|
106
|
+
.map((line) => line.trim())
|
|
107
|
+
.find((line) => line.length > 0 && !line.startsWith("#"));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isGeneratedCommit(headerLine) {
|
|
111
|
+
return (
|
|
112
|
+
headerLine.startsWith("Merge ") ||
|
|
113
|
+
headerLine.startsWith("Revert ") ||
|
|
114
|
+
headerLine.startsWith("fixup!") ||
|
|
115
|
+
headerLine.startsWith("squash!")
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function parseConventionalCommit(headerLine) {
|
|
120
|
+
const match = headerLine.match(/^([a-z]+)(\([a-z0-9._/-]+\))?(!)?: (.+)$/);
|
|
121
|
+
if (!match) return undefined;
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
type: match[1],
|
|
125
|
+
breaking: Boolean(match[3]),
|
|
126
|
+
subject: match[4],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function resolveBump(parsedCommit, rawMessage) {
|
|
131
|
+
if (parsedCommit.breaking || /\nBREAKING[ -]CHANGE:/m.test(rawMessage)) {
|
|
132
|
+
return "major";
|
|
133
|
+
}
|
|
134
|
+
return bumpByType.get(parsedCommit.type);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function bumpVersion(version, bump) {
|
|
138
|
+
if (typeof version !== "string") {
|
|
139
|
+
throw new Error("package.json version must be a string");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(-.+)?$/);
|
|
143
|
+
if (!match) {
|
|
144
|
+
throw new Error(`Unsupported semver version: ${version}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const major = Number(match[1]);
|
|
148
|
+
const minor = Number(match[2]);
|
|
149
|
+
const patch = Number(match[3]);
|
|
150
|
+
|
|
151
|
+
switch (bump) {
|
|
152
|
+
case "major":
|
|
153
|
+
return `${major + 1}.0.0`;
|
|
154
|
+
case "minor":
|
|
155
|
+
return `${major}.${minor + 1}.0`;
|
|
156
|
+
case "patch":
|
|
157
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
158
|
+
default:
|
|
159
|
+
throw new Error(`Unsupported bump type: ${bump}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function readJson(filePath) {
|
|
164
|
+
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function writeJson(filePath, value) {
|
|
168
|
+
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function fail(messageText) {
|
|
172
|
+
console.error(messageText);
|
|
173
|
+
console.error("");
|
|
174
|
+
console.error("Use Conventional Commits:");
|
|
175
|
+
console.error(" feat: add project listing");
|
|
176
|
+
console.error(" fix(projects): normalize Dokploy host");
|
|
177
|
+
console.error(" feat!: change config schema");
|
|
178
|
+
console.error("");
|
|
179
|
+
console.error("Version bump rules:");
|
|
180
|
+
console.error(" feat or feat(scope) -> minor");
|
|
181
|
+
console.error(" fix/perf -> patch");
|
|
182
|
+
console.error(" ! or BREAKING CHANGE -> major");
|
|
183
|
+
console.error(" docs/chore/etc. -> no version bump");
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
|
+
const packageJsonPath = path.join(packageDir, "package.json");
|
|
9
|
+
const changelogPath = path.join(packageDir, "CHANGELOG.md");
|
|
10
|
+
const args = new Set(process.argv.slice(2));
|
|
11
|
+
const dryRun = args.has("--dry-run");
|
|
12
|
+
|
|
13
|
+
const packageJson = readJson(packageJsonPath);
|
|
14
|
+
const version = stringValue(packageJson.version, "0.0.0");
|
|
15
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
16
|
+
const lastTag = getLastTag();
|
|
17
|
+
const commits = getCommits(lastTag);
|
|
18
|
+
const section = renderVersionSection(version, today, lastTag, commits);
|
|
19
|
+
|
|
20
|
+
if (dryRun) {
|
|
21
|
+
console.log(section.trimEnd());
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const currentChangelog = readChangelog();
|
|
26
|
+
const nextChangelog = upsertVersionSection(currentChangelog, version, section);
|
|
27
|
+
writeFileSync(changelogPath, nextChangelog, "utf8");
|
|
28
|
+
|
|
29
|
+
console.log(`Updated CHANGELOG.md for ${packageJson.name}@${version}`);
|
|
30
|
+
|
|
31
|
+
function getLastTag() {
|
|
32
|
+
try {
|
|
33
|
+
return execFileSync("git", ["-C", packageDir, "describe", "--tags", "--abbrev=0"], {
|
|
34
|
+
encoding: "utf8",
|
|
35
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
36
|
+
}).trim();
|
|
37
|
+
} catch {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getCommits(tag) {
|
|
43
|
+
const range = tag ? [`${tag}..HEAD`] : [];
|
|
44
|
+
const output = execFileSync(
|
|
45
|
+
"git",
|
|
46
|
+
[
|
|
47
|
+
"-C",
|
|
48
|
+
packageDir,
|
|
49
|
+
"log",
|
|
50
|
+
"--date=short",
|
|
51
|
+
"--pretty=format:%H%x1f%ad%x1f%s%x1f%b%x1e",
|
|
52
|
+
...range,
|
|
53
|
+
],
|
|
54
|
+
{ encoding: "utf8" },
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return output
|
|
58
|
+
.split("\x1e")
|
|
59
|
+
.map((record) => record.trim())
|
|
60
|
+
.filter(Boolean)
|
|
61
|
+
.map(parseCommit);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseCommit(record) {
|
|
65
|
+
const [hash = "", date = "", subject = "", body = ""] = record.split("\x1f");
|
|
66
|
+
const conventional = subject.match(/^([a-z]+)(\([a-z0-9._/-]+\))?(!)?: (.+)$/);
|
|
67
|
+
|
|
68
|
+
if (!conventional) {
|
|
69
|
+
return {
|
|
70
|
+
hash,
|
|
71
|
+
date,
|
|
72
|
+
type: "other",
|
|
73
|
+
breaking: /\nBREAKING[ -]CHANGE:/m.test(body),
|
|
74
|
+
subject,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
hash,
|
|
80
|
+
date,
|
|
81
|
+
type: conventional[1],
|
|
82
|
+
breaking: Boolean(conventional[3]) || /\nBREAKING[ -]CHANGE:/m.test(body),
|
|
83
|
+
subject: conventional[4],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function renderVersionSection(nextVersion, date, tag, commits) {
|
|
88
|
+
const lines = [`## ${nextVersion} - ${date}`, ""];
|
|
89
|
+
lines.push(tag ? `_Changes since ${tag}._` : "_Initial changelog generated from repository history._");
|
|
90
|
+
lines.push("");
|
|
91
|
+
|
|
92
|
+
if (commits.length === 0) {
|
|
93
|
+
lines.push("- No commits found since the last tag.", "");
|
|
94
|
+
return `${lines.join("\n")}\n`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const breaking = commits.filter((commit) => commit.breaking);
|
|
98
|
+
appendGroup(lines, "Breaking Changes", breaking);
|
|
99
|
+
|
|
100
|
+
const grouped = [
|
|
101
|
+
["Features", ["feat"]],
|
|
102
|
+
["Fixes", ["fix"]],
|
|
103
|
+
["Performance", ["perf"]],
|
|
104
|
+
["Refactoring", ["refactor"]],
|
|
105
|
+
["Documentation", ["docs"]],
|
|
106
|
+
["Tests", ["test"]],
|
|
107
|
+
["Build", ["build"]],
|
|
108
|
+
["CI", ["ci"]],
|
|
109
|
+
["Chores", ["chore"]],
|
|
110
|
+
["Styles", ["style"]],
|
|
111
|
+
["Reverts", ["revert"]],
|
|
112
|
+
["Other Changes", ["other"]],
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
for (const [title, types] of grouped) {
|
|
116
|
+
appendGroup(
|
|
117
|
+
lines,
|
|
118
|
+
title,
|
|
119
|
+
commits.filter((commit) => types.includes(commit.type) && !commit.breaking),
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return `${lines.join("\n").trimEnd()}\n\n`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function appendGroup(lines, title, commits) {
|
|
127
|
+
if (commits.length === 0) return;
|
|
128
|
+
|
|
129
|
+
lines.push(`### ${title}`, "");
|
|
130
|
+
for (const commit of commits) {
|
|
131
|
+
lines.push(`- ${commit.subject} (${commit.hash.slice(0, 7)})`);
|
|
132
|
+
}
|
|
133
|
+
lines.push("");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function upsertVersionSection(currentChangelog, nextVersion, section) {
|
|
137
|
+
const header = "# Changelog\n\n";
|
|
138
|
+
const body = currentChangelog.startsWith("# Changelog\n")
|
|
139
|
+
? currentChangelog.slice(header.length)
|
|
140
|
+
: currentChangelog.trimStart();
|
|
141
|
+
const versionHeader = `## ${nextVersion} - `;
|
|
142
|
+
const start = body.indexOf(versionHeader);
|
|
143
|
+
|
|
144
|
+
if (start === -1) {
|
|
145
|
+
return `${header}${section}${body.trimStart()}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const nextSectionStart = body.indexOf("\n## ", start + 1);
|
|
149
|
+
const before = body.slice(0, start);
|
|
150
|
+
const after = nextSectionStart === -1 ? "" : body.slice(nextSectionStart + 1);
|
|
151
|
+
|
|
152
|
+
return `${header}${before}${section}${after}`.replace(/\n{3,}/g, "\n\n");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function readChangelog() {
|
|
156
|
+
try {
|
|
157
|
+
return readFileSync(changelogPath, "utf8");
|
|
158
|
+
} catch {
|
|
159
|
+
return "# Changelog\n\n";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function readJson(filePath) {
|
|
164
|
+
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function stringValue(value, fallback) {
|
|
168
|
+
return typeof value === "string" ? value : fallback;
|
|
169
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
PACKAGE_MANAGER="npm"
|
|
5
|
+
PUBLISH="0"
|
|
6
|
+
ACCESS="public"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'EOF'
|
|
10
|
+
Usage:
|
|
11
|
+
./scripts/publish.sh [npm|pnpm] [--publish] [--access public|restricted]
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
./scripts/publish.sh npm
|
|
15
|
+
./scripts/publish.sh npm --publish
|
|
16
|
+
./scripts/publish.sh pnpm
|
|
17
|
+
./scripts/publish.sh pnpm --publish
|
|
18
|
+
|
|
19
|
+
Default mode is safe: it runs checks and pack dry-run only.
|
|
20
|
+
Pass --publish to publish @lishugupta652/dokploy to npm.
|
|
21
|
+
EOF
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
while [ "$#" -gt 0 ]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
npm|pnpm)
|
|
27
|
+
PACKAGE_MANAGER="$1"
|
|
28
|
+
shift
|
|
29
|
+
;;
|
|
30
|
+
--publish)
|
|
31
|
+
PUBLISH="1"
|
|
32
|
+
shift
|
|
33
|
+
;;
|
|
34
|
+
--dry-run)
|
|
35
|
+
PUBLISH="0"
|
|
36
|
+
shift
|
|
37
|
+
;;
|
|
38
|
+
--access)
|
|
39
|
+
if [ "$#" -lt 2 ]; then
|
|
40
|
+
echo "Missing value for --access" >&2
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
ACCESS="$2"
|
|
44
|
+
shift 2
|
|
45
|
+
;;
|
|
46
|
+
-h|--help)
|
|
47
|
+
usage
|
|
48
|
+
exit 0
|
|
49
|
+
;;
|
|
50
|
+
*)
|
|
51
|
+
echo "Unknown argument: $1" >&2
|
|
52
|
+
usage
|
|
53
|
+
exit 1
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
cd "$(dirname "$0")/.."
|
|
59
|
+
|
|
60
|
+
if ! command -v "$PACKAGE_MANAGER" >/dev/null 2>&1; then
|
|
61
|
+
if [ "$PACKAGE_MANAGER" = "pnpm" ]; then
|
|
62
|
+
echo "pnpm is not installed. Try: corepack enable && corepack prepare pnpm@latest --activate" >&2
|
|
63
|
+
else
|
|
64
|
+
echo "$PACKAGE_MANAGER is not installed." >&2
|
|
65
|
+
fi
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [ "$PACKAGE_MANAGER" = "npm" ]; then
|
|
70
|
+
export NPM_CONFIG_CACHE="${NPM_CONFIG_CACHE:-/tmp/dokploy-npm-cache}"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
if [ "$PACKAGE_MANAGER" = "pnpm" ] && [ ! -f "pnpm-lock.yaml" ] && [ -f "package-lock.json" ]; then
|
|
74
|
+
echo "Note: package-lock.json exists and pnpm-lock.yaml does not."
|
|
75
|
+
echo "To fully switch this package to pnpm, run: rm package-lock.json && pnpm install"
|
|
76
|
+
echo ""
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
echo "Package manager: $PACKAGE_MANAGER"
|
|
80
|
+
echo "Publish mode: $PUBLISH"
|
|
81
|
+
echo "Access: $ACCESS"
|
|
82
|
+
echo ""
|
|
83
|
+
|
|
84
|
+
if [ "$PUBLISH" = "1" ]; then
|
|
85
|
+
if ! "$PACKAGE_MANAGER" whoami >/dev/null 2>&1; then
|
|
86
|
+
echo "Not logged in to npm. Run: $PACKAGE_MANAGER login" >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
echo "Logged in as: $("$PACKAGE_MANAGER" whoami)"
|
|
90
|
+
echo ""
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
echo "Checking package..."
|
|
94
|
+
"$PACKAGE_MANAGER" run check
|
|
95
|
+
|
|
96
|
+
echo ""
|
|
97
|
+
echo "Building package..."
|
|
98
|
+
"$PACKAGE_MANAGER" run build
|
|
99
|
+
|
|
100
|
+
echo ""
|
|
101
|
+
echo "CLI smoke test..."
|
|
102
|
+
node dist/index.js --version
|
|
103
|
+
node dist/index.js --help >/dev/null
|
|
104
|
+
|
|
105
|
+
echo ""
|
|
106
|
+
if [ "$PUBLISH" = "1" ]; then
|
|
107
|
+
echo "Generating changelog..."
|
|
108
|
+
"$PACKAGE_MANAGER" run changelog
|
|
109
|
+
else
|
|
110
|
+
echo "Changelog dry-run..."
|
|
111
|
+
"$PACKAGE_MANAGER" run changelog -- --dry-run
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
echo ""
|
|
115
|
+
echo "Pack dry-run..."
|
|
116
|
+
"$PACKAGE_MANAGER" pack --dry-run
|
|
117
|
+
|
|
118
|
+
if [ "$PUBLISH" != "1" ]; then
|
|
119
|
+
echo ""
|
|
120
|
+
echo "Dry run complete. Publish with:"
|
|
121
|
+
echo " ./scripts/publish.sh $PACKAGE_MANAGER --publish"
|
|
122
|
+
exit 0
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
echo ""
|
|
126
|
+
echo "Publishing @lishugupta652/dokploy..."
|
|
127
|
+
"$PACKAGE_MANAGER" publish --access "$ACCESS"
|
|
128
|
+
|
|
129
|
+
echo ""
|
|
130
|
+
echo "Published. Verify with:"
|
|
131
|
+
echo " npm view @lishugupta652/dokploy version"
|
|
132
|
+
echo " npm install -g @lishugupta652/dokploy"
|
|
133
|
+
echo " dokploy --help"
|