@timekast/factory 1.11.0 → 1.12.0
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/commands/status.js +4 -1
- package/dist/lib/unpack.js +46 -3
- package/package.json +1 -1
package/dist/commands/status.js
CHANGED
|
@@ -18,6 +18,7 @@ import { execa } from 'execa';
|
|
|
18
18
|
import { FACTORY_REPO } from '../lib/constants.js';
|
|
19
19
|
import { hasLockfile, readLockfile } from '../lib/lockfile.js';
|
|
20
20
|
import { compare } from '../lib/semver.js';
|
|
21
|
+
import { isKitReleaseTag } from '../lib/unpack.js';
|
|
21
22
|
/**
|
|
22
23
|
* The BETA channel banner (BETA-005). Emitted by `status` and `doctor` when the
|
|
23
24
|
* lockfile is on the beta channel (`lockfile.beta === true`) so the dev always
|
|
@@ -47,7 +48,9 @@ async function fetchLatestRelease() {
|
|
|
47
48
|
'30',
|
|
48
49
|
]);
|
|
49
50
|
const releases = JSON.parse(stdout);
|
|
50
|
-
|
|
51
|
+
// Only consider the KIT release line (`v*`): the repo also hosts `launcher-v*`
|
|
52
|
+
// releases, which must never be mistaken for the latest kit version.
|
|
53
|
+
const stable = releases.find((r) => !r.isPrerelease && isKitReleaseTag(r.tagName));
|
|
51
54
|
if (!stable)
|
|
52
55
|
return null;
|
|
53
56
|
return stripVersionPrefix(stable.tagName);
|
package/dist/lib/unpack.js
CHANGED
|
@@ -22,10 +22,31 @@ import { FACTORY_REPO, MANIFEST_FILE, TIMEKAST_DIR } from './constants.js';
|
|
|
22
22
|
import { compare } from './semver.js';
|
|
23
23
|
/** Download the profile tarball into `tmpDir`; returns the tarball path. */
|
|
24
24
|
export async function downloadProfileTarball(profile, tmpDir) {
|
|
25
|
+
// List releases and resolve the latest KIT release by tag, then download BY TAG.
|
|
26
|
+
// We do NOT let `gh` resolve repo-wide "latest": the repo also hosts the launcher
|
|
27
|
+
// release line (`launcher-v*`), whose assets are not kit tarballs, so "latest"
|
|
28
|
+
// can point at a launcher release. Filtering to `v*` keeps the kit line isolated.
|
|
29
|
+
const { stdout } = await execa('gh', [
|
|
30
|
+
'release',
|
|
31
|
+
'list',
|
|
32
|
+
'--repo',
|
|
33
|
+
FACTORY_REPO,
|
|
34
|
+
'--json',
|
|
35
|
+
'tagName,isPrerelease',
|
|
36
|
+
'--limit',
|
|
37
|
+
'30',
|
|
38
|
+
]);
|
|
39
|
+
const releases = JSON.parse(stdout);
|
|
40
|
+
const latestKit = resolveLatestKitRelease(releases);
|
|
41
|
+
if (!latestKit) {
|
|
42
|
+
throw new CLIError(`No se encontró un release del kit (\`v*\`) publicado en \`${FACTORY_REPO}\`.\n` +
|
|
43
|
+
'Verifica que exista un release con los assets de distribución.');
|
|
44
|
+
}
|
|
25
45
|
try {
|
|
26
46
|
await execa('gh', [
|
|
27
47
|
'release',
|
|
28
48
|
'download',
|
|
49
|
+
latestKit.tagName,
|
|
29
50
|
'--repo',
|
|
30
51
|
FACTORY_REPO,
|
|
31
52
|
'--pattern',
|
|
@@ -35,12 +56,12 @@ export async function downloadProfileTarball(profile, tmpDir) {
|
|
|
35
56
|
]);
|
|
36
57
|
}
|
|
37
58
|
catch {
|
|
38
|
-
throw new CLIError(`No se encontró
|
|
39
|
-
'Verifica que
|
|
59
|
+
throw new CLIError(`No se encontró el asset \`${profile}\` en el release del kit \`${latestKit.tagName}\` de \`${FACTORY_REPO}\`.\n` +
|
|
60
|
+
'Verifica que el release contenga los assets de distribución.');
|
|
40
61
|
}
|
|
41
62
|
const downloaded = readdirSync(tmpDir).filter((f) => f.endsWith('.tgz'));
|
|
42
63
|
if (downloaded.length === 0) {
|
|
43
|
-
throw new CLIError(`El release no contiene un asset para el perfil \`${profile}\`. ` +
|
|
64
|
+
throw new CLIError(`El release del kit \`${latestKit.tagName}\` no contiene un asset para el perfil \`${profile}\`. ` +
|
|
44
65
|
'Verifica el release del Factory.');
|
|
45
66
|
}
|
|
46
67
|
return path.join(tmpDir, downloaded[0]);
|
|
@@ -81,6 +102,28 @@ export function resolveLatestBeta(releases) {
|
|
|
81
102
|
// semver-max: `compare` strips the leading `v` itself, so tags pass verbatim.
|
|
82
103
|
return betas.reduce((max, r) => (compare(r.tagName, max.tagName) > 0 ? r : max));
|
|
83
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* True when a release tag belongs to the KIT's release line (`v<semver>`, e.g.
|
|
107
|
+
* `v10.9.0`). The same repo hosts the launcher line (`launcher-v*`) and — via npm,
|
|
108
|
+
* not GitHub Releases — the CLI line (`cli-v*`); neither starts with `v<digit>`,
|
|
109
|
+
* so this predicate isolates the kit from every other release line in the repo.
|
|
110
|
+
* Without it, `gh`'s repo-wide "latest" / a non-prerelease `launcher-v*` could be
|
|
111
|
+
* mistaken for the latest kit version and break `status` / `update`.
|
|
112
|
+
*/
|
|
113
|
+
export function isKitReleaseTag(tagName) {
|
|
114
|
+
return /^v\d/.test(tagName);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Pick the latest STABLE kit release from a list: filter to kit tags (excluding
|
|
118
|
+
* `launcher-v*` / any non-kit line) AND non-prerelease, then the highest by semver.
|
|
119
|
+
* Returns null when no stable kit release exists.
|
|
120
|
+
*/
|
|
121
|
+
export function resolveLatestKitRelease(releases) {
|
|
122
|
+
const kit = releases.filter((r) => !r.isPrerelease && isKitReleaseTag(r.tagName));
|
|
123
|
+
if (kit.length === 0)
|
|
124
|
+
return null;
|
|
125
|
+
return kit.reduce((max, r) => (compare(r.tagName, max.tagName) > 0 ? r : max));
|
|
126
|
+
}
|
|
84
127
|
/**
|
|
85
128
|
* Download the latest beta profile tarball into `tmpDir`; returns the tarball
|
|
86
129
|
* path. Beta counterpart of {@link downloadProfileTarball}: instead of letting
|