create-portfoliable 1.2.2 → 1.2.4
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/README.md
CHANGED
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// MARK: IMPORTS
|
|
6
6
|
import { execFileSync } from "node:child_process";
|
|
7
7
|
import { readFileSync, writeFileSync, appendFileSync, existsSync } from "node:fs";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
8
9
|
|
|
9
10
|
// MARK: RELEASE CONFIGURATION
|
|
10
11
|
// Defines canonical repository URL used for changelog compare and commit links.
|
|
@@ -19,6 +20,7 @@ const packages = [
|
|
|
19
20
|
{
|
|
20
21
|
key: "package",
|
|
21
22
|
displayName: "create-portfoliable",
|
|
23
|
+
npmPackageName: "create-portfoliable",
|
|
22
24
|
packageJsonPath: "create-portfoliable/package.json",
|
|
23
25
|
changelogPath: "CHANGELOG.md",
|
|
24
26
|
tagPrefix: "v",
|
|
@@ -175,6 +177,46 @@ function bumpVersion(currentVersion, level) {
|
|
|
175
177
|
return `${major}.${minor}.${patch + 1}`;
|
|
176
178
|
}
|
|
177
179
|
|
|
180
|
+
export function parsePublishedVersionList(rawResponse) {
|
|
181
|
+
if (!rawResponse || rawResponse.trim() === "") {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const parsed = JSON.parse(rawResponse);
|
|
187
|
+
if (!Array.isArray(parsed)) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return parsed
|
|
192
|
+
.filter((value) => typeof value === "string")
|
|
193
|
+
.map((value) => value.trim())
|
|
194
|
+
.filter(Boolean);
|
|
195
|
+
} catch {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function isVersionPublished(publishedVersions, candidateVersion) {
|
|
201
|
+
return Array.isArray(publishedVersions) && publishedVersions.includes(candidateVersion);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function getPublishedVersionsForPackage(packageName) {
|
|
205
|
+
try {
|
|
206
|
+
const output = execFileSync("npm", ["view", packageName, "versions", "--json"], {
|
|
207
|
+
encoding: "utf8",
|
|
208
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
209
|
+
}).trim();
|
|
210
|
+
return parsePublishedVersionList(output);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const message = error?.stderr ? String(error.stderr) : String(error);
|
|
213
|
+
if (message.includes("E404") || message.includes("404 Not Found")) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
178
220
|
// Updates package.json version field with computed release version.
|
|
179
221
|
function updatePackageJson(filePath, nextVersion) {
|
|
180
222
|
// Reads and parses package manifest.
|
|
@@ -267,6 +309,14 @@ function createReleasePlan(pkg) {
|
|
|
267
309
|
const currentVersion = JSON.parse(readFileSync(pkg.packageJsonPath, "utf8")).version;
|
|
268
310
|
// Computes next version using selected bump level.
|
|
269
311
|
const nextVersion = bumpVersion(currentVersion, bump);
|
|
312
|
+
const publishedVersions = getPublishedVersionsForPackage(pkg.npmPackageName);
|
|
313
|
+
|
|
314
|
+
if (isVersionPublished(publishedVersions, nextVersion)) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`Refusing to publish ${pkg.displayName} version ${nextVersion}: it is already published to npm (${pkg.npmPackageName}). Please bump the version before releasing.`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
270
320
|
// Builds package tag string from prefix and next version.
|
|
271
321
|
const nextTag = `${pkg.tagPrefix}${nextVersion}`;
|
|
272
322
|
|
|
@@ -359,5 +409,10 @@ function run() {
|
|
|
359
409
|
}
|
|
360
410
|
}
|
|
361
411
|
|
|
362
|
-
|
|
363
|
-
|
|
412
|
+
const isMainModule =
|
|
413
|
+
typeof process.argv[1] === "string" &&
|
|
414
|
+
import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
415
|
+
|
|
416
|
+
if (isMainModule) {
|
|
417
|
+
run();
|
|
418
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { isVersionPublished, parsePublishedVersionList } from './release-orchestrator.mjs';
|
|
3
|
+
|
|
4
|
+
describe('release orchestrator version guard', () => {
|
|
5
|
+
it('detects versions already published to npm', () => {
|
|
6
|
+
expect(parsePublishedVersionList('[]')).toEqual([]);
|
|
7
|
+
expect(parsePublishedVersionList('["1.2.2","1.2.3"]')).toEqual(['1.2.2', '1.2.3']);
|
|
8
|
+
expect(isVersionPublished(['1.2.2', '1.2.3'], '1.2.3')).toBe(true);
|
|
9
|
+
expect(isVersionPublished(['1.2.2', '1.2.3'], '1.2.4')).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
});
|