dksetup 1.0.19 → 1.0.22
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/dksetup-publish.mjs +202 -0
- package/justfile +24 -0
- package/package.json +1 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
const dryRun = process.argv.includes('--dry-run');
|
|
7
|
+
const resumeOnly = process.argv.includes('--resume');
|
|
8
|
+
|
|
9
|
+
const packageConfigs = [
|
|
10
|
+
{
|
|
11
|
+
name: 'dksetup',
|
|
12
|
+
path: 'package.json',
|
|
13
|
+
publishDir: '.'
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
function bumpPatch(version) {
|
|
18
|
+
const parts = version.split('.').map(Number);
|
|
19
|
+
if (parts.length !== 3 || parts.some(Number.isNaN)) {
|
|
20
|
+
throw new Error(`Invalid semver version: ${version}`);
|
|
21
|
+
}
|
|
22
|
+
return `${parts[0]}.${parts[1]}.${parts[2] + 1}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function runCommand(command, args, cwd) {
|
|
26
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
27
|
+
const child = spawn(command, args, {
|
|
28
|
+
cwd,
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
shell: process.platform === 'win32'
|
|
31
|
+
});
|
|
32
|
+
child.on('error', rejectPromise);
|
|
33
|
+
child.on('close', (code) => {
|
|
34
|
+
if (code === 0) {
|
|
35
|
+
resolvePromise();
|
|
36
|
+
} else {
|
|
37
|
+
rejectPromise(new Error(`${command} ${args.join(' ')} failed with code ${code}`));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function runCommandCapture(command, args, cwd) {
|
|
44
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
45
|
+
const child = spawn(command, args, {
|
|
46
|
+
cwd,
|
|
47
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
48
|
+
shell: process.platform === 'win32'
|
|
49
|
+
});
|
|
50
|
+
let stdout = '';
|
|
51
|
+
let stderr = '';
|
|
52
|
+
child.stdout.on('data', (chunk) => {
|
|
53
|
+
stdout += chunk.toString();
|
|
54
|
+
});
|
|
55
|
+
child.stderr.on('data', (chunk) => {
|
|
56
|
+
stderr += chunk.toString();
|
|
57
|
+
});
|
|
58
|
+
child.on('error', rejectPromise);
|
|
59
|
+
child.on('close', (code) => {
|
|
60
|
+
resolvePromise({ stdout: stdout.trim(), stderr: stderr.trim(), code });
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function loadPackageJson(path) {
|
|
66
|
+
const raw = await readFile(path, 'utf8');
|
|
67
|
+
const json = JSON.parse(raw);
|
|
68
|
+
return json;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function savePackageJson(path, json) {
|
|
72
|
+
const normalized = `${JSON.stringify(json, null, 2)}\n`;
|
|
73
|
+
await writeFile(path, normalized, 'utf8');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function isPublished(packageName, version, cwd) {
|
|
77
|
+
const lookup = `${packageName}@${version}`;
|
|
78
|
+
const result = await runCommandCapture('npm', ['view', lookup, 'version'], cwd);
|
|
79
|
+
return result.code === 0 && result.stdout === version;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function assertNpmAuth(cwd) {
|
|
83
|
+
const result = await runCommandCapture('npm', ['whoami'], cwd);
|
|
84
|
+
if (result.code !== 0 || !result.stdout) {
|
|
85
|
+
throw new Error('npm authentication failed (token expired/revoked). Run "npm login" and retry publish.');
|
|
86
|
+
}
|
|
87
|
+
return result.stdout;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function main() {
|
|
91
|
+
const repoRoot = process.cwd();
|
|
92
|
+
const packageStates = [];
|
|
93
|
+
for (const config of packageConfigs) {
|
|
94
|
+
const fullPath = resolve(repoRoot, config.path);
|
|
95
|
+
const pkgJson = await loadPackageJson(fullPath);
|
|
96
|
+
if (pkgJson.name !== config.name) {
|
|
97
|
+
throw new Error(`Package mismatch at ${config.path}. Expected ${config.name}, found ${pkgJson.name}`);
|
|
98
|
+
}
|
|
99
|
+
packageStates.push({
|
|
100
|
+
...config,
|
|
101
|
+
fullPath,
|
|
102
|
+
pkgJson,
|
|
103
|
+
oldVersion: pkgJson.version,
|
|
104
|
+
newVersion: bumpPatch(pkgJson.version)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
let publishedCount = 0;
|
|
108
|
+
for (const pkg of packageStates) {
|
|
109
|
+
pkg.currentPublished = await isPublished(pkg.name, pkg.oldVersion, repoRoot);
|
|
110
|
+
if (pkg.currentPublished) {
|
|
111
|
+
publishedCount += 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (resumeOnly && publishedCount > 0 && publishedCount < packageStates.length) {
|
|
115
|
+
if (!dryRun) {
|
|
116
|
+
const npmUser = await assertNpmAuth(repoRoot);
|
|
117
|
+
console.log(`\nAuthenticated as npm user: ${npmUser}`);
|
|
118
|
+
}
|
|
119
|
+
const missing = packageStates.filter((pkg) => !pkg.currentPublished);
|
|
120
|
+
console.log('\nPartial release detected.');
|
|
121
|
+
console.log('Already published at current local versions:');
|
|
122
|
+
for (const pkg of packageStates.filter((item) => item.currentPublished)) {
|
|
123
|
+
console.log(`- ${pkg.name}@${pkg.oldVersion}`);
|
|
124
|
+
}
|
|
125
|
+
console.log('\nPending publish (no version bump):');
|
|
126
|
+
for (const pkg of missing) {
|
|
127
|
+
console.log(`- ${pkg.name}@${pkg.oldVersion}`);
|
|
128
|
+
}
|
|
129
|
+
if (dryRun) {
|
|
130
|
+
console.log('\nDry run complete. No files were changed and no packages were published.');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
console.log('\nResuming publish for missing packages...');
|
|
134
|
+
for (const pkg of missing) {
|
|
135
|
+
const publishCwd = resolve(repoRoot, pkg.publishDir);
|
|
136
|
+
console.log(`\nPublishing ${pkg.name}@${pkg.oldVersion} from ${pkg.publishDir}`);
|
|
137
|
+
await runCommand('npm', ['publish', '--access', 'public'], publishCwd);
|
|
138
|
+
}
|
|
139
|
+
console.log('\nPublish resume completed successfully.');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (resumeOnly && publishedCount === 0) {
|
|
143
|
+
if (dryRun) {
|
|
144
|
+
console.log('\nResume mode: no packages published yet at current local versions.');
|
|
145
|
+
console.log('Pending publish (no version bump):');
|
|
146
|
+
for (const pkg of packageStates) {
|
|
147
|
+
console.log(`- ${pkg.name}@${pkg.oldVersion}`);
|
|
148
|
+
}
|
|
149
|
+
console.log('\nDry run complete. No files were changed and no packages were published.');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const npmUser = await assertNpmAuth(repoRoot);
|
|
153
|
+
console.log(`\nAuthenticated as npm user: ${npmUser}`);
|
|
154
|
+
console.log('\nResume mode: publishing current local versions without bump...');
|
|
155
|
+
for (const pkg of packageStates) {
|
|
156
|
+
const publishCwd = resolve(repoRoot, pkg.publishDir);
|
|
157
|
+
console.log(`\nPublishing ${pkg.name}@${pkg.oldVersion} from ${pkg.publishDir}`);
|
|
158
|
+
await runCommand('npm', ['publish', '--access', 'public'], publishCwd);
|
|
159
|
+
}
|
|
160
|
+
console.log('\nPublish resume completed successfully.');
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (resumeOnly && publishedCount === packageStates.length) {
|
|
164
|
+
console.log('\nNo partial release detected. All current local versions are already published.');
|
|
165
|
+
if (dryRun) {
|
|
166
|
+
console.log('\nDry run complete. No files were changed and no packages were published.');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
console.log('\nResume mode did not publish anything.');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (dryRun) {
|
|
173
|
+
console.log('\nPlanned version updates:');
|
|
174
|
+
for (const pkg of packageStates) {
|
|
175
|
+
console.log(`- ${pkg.name}: ${pkg.oldVersion} -> ${pkg.newVersion}`);
|
|
176
|
+
}
|
|
177
|
+
console.log('\nDry run complete. No files were changed and no packages were published.');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const npmUser = await assertNpmAuth(repoRoot);
|
|
181
|
+
console.log(`\nAuthenticated as npm user: ${npmUser}`);
|
|
182
|
+
for (const pkg of packageStates) {
|
|
183
|
+
pkg.pkgJson.version = pkg.newVersion;
|
|
184
|
+
await savePackageJson(pkg.fullPath, pkg.pkgJson);
|
|
185
|
+
}
|
|
186
|
+
console.log('\nVersion updates:');
|
|
187
|
+
for (const pkg of packageStates) {
|
|
188
|
+
console.log(`- ${pkg.name}: ${pkg.oldVersion} -> ${pkg.newVersion}`);
|
|
189
|
+
}
|
|
190
|
+
console.log('\nPublishing packages to npm...');
|
|
191
|
+
for (const pkg of packageStates) {
|
|
192
|
+
const publishCwd = resolve(repoRoot, pkg.publishDir);
|
|
193
|
+
console.log(`\nPublishing ${pkg.name}@${pkg.newVersion} from ${pkg.publishDir}`);
|
|
194
|
+
await runCommand('npm', ['publish', '--access', 'public'], publishCwd);
|
|
195
|
+
}
|
|
196
|
+
console.log('\nAll packages published successfully.');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
main().catch((error) => {
|
|
200
|
+
console.error(`\nPublish pipeline failed: ${error.message}`);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
});
|
package/justfile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Use PowerShell for all recipes
|
|
2
|
+
set shell := ["powershell", "-c"]
|
|
3
|
+
# Justfile for DK-CLI
|
|
4
|
+
|
|
5
|
+
# Publish: bump patch version and publish to npm
|
|
6
|
+
publish:
|
|
7
|
+
node dksetup-publish.mjs
|
|
8
|
+
|
|
9
|
+
# Bump only
|
|
10
|
+
bump:
|
|
11
|
+
npm version patch --no-git-tag-version
|
|
12
|
+
|
|
13
|
+
# Show current version
|
|
14
|
+
version:
|
|
15
|
+
node -p "require('./package.json').version"
|
|
16
|
+
|
|
17
|
+
# Install dependencies
|
|
18
|
+
install:
|
|
19
|
+
npm install
|
|
20
|
+
|
|
21
|
+
# Help
|
|
22
|
+
help:
|
|
23
|
+
echo "Available commands: publish, npm publish, bump, version, install"
|
|
24
|
+
|