create-deka-app 0.53.4 → 0.53.7-canary-4551de1
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 +37 -7
- package/package.json +1 -1
- package/src/channel.js +36 -0
- package/src/scaffold.js +28 -15
package/README.md
CHANGED
|
@@ -41,13 +41,43 @@ two publish together, from the same CI run (`.github/workflows/publish-runtime.y
|
|
|
41
41
|
the `deka` family), so a given create-deka-app version always produces the
|
|
42
42
|
same project: no registry lookup needed to decide the pin.
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
There is one publish path for this whole repo: create-deka-app has no
|
|
45
|
+
standalone release of its own. The version in this repo's own
|
|
46
|
+
`package.json` is a `0.0.0` placeholder — it is never bumped by hand or
|
|
47
|
+
committed as part of a release; the workflow stamps the real version into
|
|
48
|
+
it at publish time, in the working tree only.
|
|
49
|
+
|
|
50
|
+
The one exception to the lockstep pin is a create-deka-app release whose
|
|
51
|
+
exact-matching runtime build isn't published yet. If installing the exact
|
|
52
|
+
pin fails, create-deka-app falls back to the latest published
|
|
53
|
+
`@dekaruntime/deka` version, prints a clear warning, and never leaves a
|
|
54
|
+
nonexistent version pinned in the generated `package.json`.
|
|
55
|
+
|
|
56
|
+
## Channels
|
|
57
|
+
|
|
58
|
+
There are two channels, [rfd#68](https://github.com/dekaruntime/rfd/issues/68):
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
npx create-deka-app@latest myapp # stable (the default)
|
|
62
|
+
npx create-deka-app@canary myapp # canary
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Stable** (`npx create-deka-app@latest`, or just `npx create-deka-app`) pins
|
|
66
|
+
a plain `X.Y.Z` deka runtime — the default, and what everyone not
|
|
67
|
+
deliberately opting in gets.
|
|
68
|
+
|
|
69
|
+
**Canary** (`npx create-deka-app@canary`) pins a prerelease version shaped
|
|
70
|
+
`X.Y.Z-canary-<7-char-commit-sha>` (e.g. `0.59.0-canary-d5661ed`) — every
|
|
71
|
+
merge to deka's `main` branch, published immediately, before a human has
|
|
72
|
+
promoted it to stable. Lockstep versioning holds within a channel: a canary
|
|
73
|
+
create-deka-app pins the *matching* canary `@dekaruntime/deka`, never a
|
|
74
|
+
stable one.
|
|
75
|
+
|
|
76
|
+
A canary's binaries report their **base version** on `deka --version` /
|
|
77
|
+
`dsc --version` — `0.59.0`, never `0.59.0-canary-d5661ed`. Promotion
|
|
78
|
+
republishes the exact same compiled bytes under the plain stable tag, so
|
|
79
|
+
the binary itself never learns it was ever a canary; only the git tag, the
|
|
80
|
+
R2 path and the npm version string say so.
|
|
51
81
|
|
|
52
82
|
## Platforms
|
|
53
83
|
|
package/package.json
CHANGED
package/src/channel.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// rfd#68 (Release Channels): a version carries its channel in its own
|
|
2
|
+
// string. `X.Y.Z-canary-<sha>` is a canary -- a build published under the
|
|
3
|
+
// `canary` npm dist-tag, from a `vX.Y.Z-canary-<sha>` release tag. Anything
|
|
4
|
+
// else (plain `X.Y.Z`) is stable, published under `latest`.
|
|
5
|
+
//
|
|
6
|
+
// Shared between the CLI this package ships (src/scaffold.js: the lockstep
|
|
7
|
+
// pin and its registry-lookup fallback) and the release pipeline that is
|
|
8
|
+
// NOT shipped (scripts/lib/manifest.js: R2 URL shapes) -- kept in src/ (not
|
|
9
|
+
// scripts/) because scripts/ is excluded from the published npm tarball
|
|
10
|
+
// (see package.json "files"), so anything scaffold.js depends on has to
|
|
11
|
+
// live somewhere that ships.
|
|
12
|
+
// https://github.com/dekaruntime/rfd/issues/68
|
|
13
|
+
const CANARY_SUFFIX = /-canary-[0-9a-f]+$/i
|
|
14
|
+
|
|
15
|
+
export function versionChannel(version) {
|
|
16
|
+
return CANARY_SUFFIX.test(String(version)) ? 'canary' : 'stable'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function distTagFor(channel) {
|
|
20
|
+
return channel === 'canary' ? 'canary' : 'latest'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The base version a canary's own binaries report on `--version`.
|
|
24
|
+
// Promotion republishes the exact same bytes under the plain tag, so a
|
|
25
|
+
// canary build never learns it is a canary -- its `--version` output
|
|
26
|
+
// always names the base version (plus a commit sha), never the
|
|
27
|
+
// "-canary-<sha>" suffix. Manifests written under rfd#68 carry an explicit
|
|
28
|
+
// `base_version` field; a manifest that predates it (or a caller that
|
|
29
|
+
// hasn't fetched one) falls back to stripping the suffix from the full
|
|
30
|
+
// version string.
|
|
31
|
+
export function baseVersionOf(version, manifest) {
|
|
32
|
+
if (manifest && typeof manifest.base_version === 'string' && manifest.base_version) {
|
|
33
|
+
return manifest.base_version
|
|
34
|
+
}
|
|
35
|
+
return String(version).replace(CANARY_SUFFIX, '')
|
|
36
|
+
}
|
package/src/scaffold.js
CHANGED
|
@@ -3,6 +3,7 @@ import { spawnSync } from 'node:child_process'
|
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { detectPackageManager } from './package-manager.js'
|
|
5
5
|
import { isSupportedPlatform, platformKey } from './platform.js'
|
|
6
|
+
import { versionChannel, distTagFor } from './channel.js'
|
|
6
7
|
|
|
7
8
|
// Thrown for every expected failure. `message` is written straight to
|
|
8
9
|
// stderr, so it always says what happened and what to do about it.
|
|
@@ -104,21 +105,33 @@ export function buildPackageJson(dirName, runtimeVersion) {
|
|
|
104
105
|
// create or bun create, and `npm view` is a read-only registry query with
|
|
105
106
|
// no project-local side effects.
|
|
106
107
|
//
|
|
107
|
-
// Falls back to the
|
|
108
|
-
// know is wrong
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
// Falls back to the running version's OWN channel's dist-tag -- never to a
|
|
109
|
+
// version we already know is wrong, and never silently to `latest` for a
|
|
110
|
+
// canary -- if the registry can't be reached (offline, registry outage,
|
|
111
|
+
// etc), and says so via `log` so the fallback is visible.
|
|
112
|
+
//
|
|
113
|
+
// rfd#68: `channel` is the channel of the create-deka-app version that is
|
|
114
|
+
// running (see resolveRuntimeVersion / createApp below) -- `canary` looks
|
|
115
|
+
// up `@dekaruntime/deka@canary`, so `npx create-deka-app@canary myapp`
|
|
116
|
+
// falls back onto another canary build, never quietly onto `latest` stable.
|
|
117
|
+
export function resolveLatestRuntimeVersion({
|
|
118
|
+
spawn = spawnSync,
|
|
119
|
+
cwd = process.cwd(),
|
|
120
|
+
log = console.log,
|
|
121
|
+
channel = 'stable',
|
|
122
|
+
} = {}) {
|
|
123
|
+
const distTag = distTagFor(channel)
|
|
124
|
+
const result = spawn('npm', ['view', `${RUNTIME_PACKAGE}@${distTag}`, 'version'], { cwd, encoding: 'utf8' })
|
|
112
125
|
|
|
113
126
|
const version =
|
|
114
127
|
result && !result.error && result.status === 0 ? String(result.stdout || '').trim() : ''
|
|
115
128
|
|
|
116
129
|
if (!version) {
|
|
117
130
|
log(
|
|
118
|
-
`> Could not resolve the
|
|
119
|
-
|
|
131
|
+
`> Could not resolve the ${distTag} ${RUNTIME_PACKAGE} version from the npm registry ` +
|
|
132
|
+
`(offline, or the registry is unreachable); pinning "${distTag}" instead.`
|
|
120
133
|
)
|
|
121
|
-
return
|
|
134
|
+
return distTag
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
return version
|
|
@@ -199,12 +212,12 @@ export function createApp({
|
|
|
199
212
|
// given create-deka-app version always produces the same project).
|
|
200
213
|
//
|
|
201
214
|
// The one case this doesn't cover is a create-deka-app release whose
|
|
202
|
-
// exact-matching runtime build isn't published yet (
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
// as a fallback: re-resolve against the
|
|
206
|
-
// silently leaving a nonexistent version
|
|
207
|
-
// package.json (the ETARGET bug fixed in 0.0.3).
|
|
215
|
+
// exact-matching runtime build isn't published yet (there is no
|
|
216
|
+
// standalone scaffolder-only release path -- one publish path,
|
|
217
|
+
// .github/workflows/publish-runtime.yml). That surfaces as the install
|
|
218
|
+
// below failing, and is handled as a fallback: re-resolve against the
|
|
219
|
+
// registry and retry once, never silently leaving a nonexistent version
|
|
220
|
+
// pinned in the final package.json (the ETARGET bug fixed in 0.0.3).
|
|
208
221
|
let runtimeVersion = resolveRuntimeVersion({ ownVersion })
|
|
209
222
|
|
|
210
223
|
const writePackageJson = (version) => {
|
|
@@ -234,7 +247,7 @@ export function createApp({
|
|
|
234
247
|
`This can happen when create-deka-app@${ownVersion} shipped before its matching runtime build did. ` +
|
|
235
248
|
'Falling back to the latest published version instead.'
|
|
236
249
|
)
|
|
237
|
-
const fallbackVersion = resolveLatestRuntimeVersion({ spawn, cwd: targetDir, log })
|
|
250
|
+
const fallbackVersion = resolveLatestRuntimeVersion({ spawn, cwd: targetDir, log, channel: versionChannel(ownVersion) })
|
|
238
251
|
if (fallbackVersion === runtimeVersion) {
|
|
239
252
|
throw new ScaffoldError(
|
|
240
253
|
`"${pm.name} install" failed in ${targetDir} (exit code ${install.status}), ` +
|