@bongos/core 1.24.24 → 1.24.25
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/.bongos-core.json +14 -14
- package/docs/module-api-changelog.md +2 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/src/bongos/package-registry.js +3 -2
- package/src/bongos/routes/core-update.js +11 -3
- package/src/bongos/software-update.js +36 -16
- package/src/module-api.js +1 -1
- package/tests/software_update.mjs +61 -3
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/bongos/package-core.js",
|
|
5
|
-
"core_version": "1.24.
|
|
6
|
-
"core_contract": "1.24.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.24.25",
|
|
6
|
+
"core_contract": "1.24.25",
|
|
7
|
+
"source_commit": "dee2639f5053216958a0024b2e6af6d54c9b4628",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-11-
|
|
9
|
+
"built_at": "2026-11-03T22:09:15.437Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 632,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 4499,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "5e0b2f24b44dcffe4bd7a9d82e6024bddd12a6be61dc609c02447cb82ba6fc1f",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -3002,7 +3002,7 @@
|
|
|
3002
3002
|
{
|
|
3003
3003
|
"path": "docs/module-api-changelog.md",
|
|
3004
3004
|
"mode": "0000644",
|
|
3005
|
-
"sha256": "
|
|
3005
|
+
"sha256": "abd56f3acf0eed7e0ed62297e2bc5774c165f608c36163d9b3a015429fb9e4cd"
|
|
3006
3006
|
},
|
|
3007
3007
|
{
|
|
3008
3008
|
"path": "docs/modules-contract.md",
|
|
@@ -11767,12 +11767,12 @@
|
|
|
11767
11767
|
{
|
|
11768
11768
|
"path": "package-lock.json",
|
|
11769
11769
|
"mode": "0000644",
|
|
11770
|
-
"sha256": "
|
|
11770
|
+
"sha256": "52a5166b00e8a5761186ca4689a2481d5ee305cf937c40739b2c8357e90510db"
|
|
11771
11771
|
},
|
|
11772
11772
|
{
|
|
11773
11773
|
"path": "package.json",
|
|
11774
11774
|
"mode": "0000644",
|
|
11775
|
-
"sha256": "
|
|
11775
|
+
"sha256": "14f054f72fe8d56472d2dc94d3f5de9f68e0246533ea992519ff8e03f1628d2d"
|
|
11776
11776
|
},
|
|
11777
11777
|
{
|
|
11778
11778
|
"path": "public-docs/index.html",
|
|
@@ -11792,7 +11792,7 @@
|
|
|
11792
11792
|
{
|
|
11793
11793
|
"path": "release-notes.json",
|
|
11794
11794
|
"mode": "0000644",
|
|
11795
|
-
"sha256": "
|
|
11795
|
+
"sha256": "d7dc47351e474cd55f6c2a089146540e628a02976d308c8bcaf4bdf9462f74eb"
|
|
11796
11796
|
},
|
|
11797
11797
|
{
|
|
11798
11798
|
"path": "scripts/bongos/CLAUDE.md",
|
|
@@ -15392,7 +15392,7 @@
|
|
|
15392
15392
|
{
|
|
15393
15393
|
"path": "src/bongos/package-registry.js",
|
|
15394
15394
|
"mode": "0000644",
|
|
15395
|
-
"sha256": "
|
|
15395
|
+
"sha256": "a7a61e07e2aae983fd0a87f748fd4277bed136bb3062b4aabd5d7416dffdefd9"
|
|
15396
15396
|
},
|
|
15397
15397
|
{
|
|
15398
15398
|
"path": "src/bongos/passkeys.js",
|
|
@@ -15517,7 +15517,7 @@
|
|
|
15517
15517
|
{
|
|
15518
15518
|
"path": "src/bongos/routes/core-update.js",
|
|
15519
15519
|
"mode": "0000644",
|
|
15520
|
-
"sha256": "
|
|
15520
|
+
"sha256": "dbb6cc64939a87b3f6c79727d90e3a9948c2c04e650235a3f1d3446c36716685"
|
|
15521
15521
|
},
|
|
15522
15522
|
{
|
|
15523
15523
|
"path": "src/bongos/routes/feedback.js",
|
|
@@ -15637,7 +15637,7 @@
|
|
|
15637
15637
|
{
|
|
15638
15638
|
"path": "src/bongos/software-update.js",
|
|
15639
15639
|
"mode": "0000644",
|
|
15640
|
-
"sha256": "
|
|
15640
|
+
"sha256": "4805e1c822f1a55cf38fec99af788cc3654f67f9aaa2830fbf853f75583c1244"
|
|
15641
15641
|
},
|
|
15642
15642
|
{
|
|
15643
15643
|
"path": "src/bongos/task-needs.js",
|
|
@@ -15682,7 +15682,7 @@
|
|
|
15682
15682
|
{
|
|
15683
15683
|
"path": "src/module-api.js",
|
|
15684
15684
|
"mode": "0000644",
|
|
15685
|
-
"sha256": "
|
|
15685
|
+
"sha256": "f7b0423511136930dafb0f695c664c581cf2ac50b94c9b1dbd763e455f00a9ce"
|
|
15686
15686
|
},
|
|
15687
15687
|
{
|
|
15688
15688
|
"path": "src/module-loader/catalog.js",
|
|
@@ -21772,7 +21772,7 @@
|
|
|
21772
21772
|
{
|
|
21773
21773
|
"path": "tests/software_update.mjs",
|
|
21774
21774
|
"mode": "0000644",
|
|
21775
|
-
"sha256": "
|
|
21775
|
+
"sha256": "6fe6bb1ebb12a0d2ab06ec98f54f79f9fb91d1c526d7a38bfae2a716a9b35d0f"
|
|
21776
21776
|
},
|
|
21777
21777
|
{
|
|
21778
21778
|
"path": "tests/sound_player.mjs",
|
|
@@ -3304,5 +3304,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
3304
3304
|
landed since 1.24.22 with no explicit bump. run 41370306880. (task 1002620)
|
|
3305
3305
|
1.24.24 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3306
3306
|
landed since 1.24.23 with no explicit bump. run 41558735984. (task 1002620)
|
|
3307
|
+
1.24.25 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3308
|
+
landed since 1.24.24 with no explicit bump. run 41727989005. (task 1002620)
|
|
3307
3309
|
---------------------------------------------------------------------------
|
|
3308
3310
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.25",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.24.
|
|
9
|
+
"version": "1.24.25",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.25",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -11065,5 +11065,11 @@
|
|
|
11065
11065
|
"id": "1004908",
|
|
11066
11066
|
"text": "Contractors are now only paid once a signed NDA is on file and the payment processor has collected their tax details; if either is missing the payment waits and the person is told why. Bongos never stores tax numbers."
|
|
11067
11067
|
}
|
|
11068
|
+
],
|
|
11069
|
+
"1.24.25": [
|
|
11070
|
+
{
|
|
11071
|
+
"id": "1004593",
|
|
11072
|
+
"text": "A hosted project's Settings page no longer offers an unreleased version; it now offers exactly what the Upgrade page offers."
|
|
11073
|
+
}
|
|
11068
11074
|
]
|
|
11069
11075
|
}
|
|
@@ -255,7 +255,8 @@ async function cached(slot, fresh, load, t) {
|
|
|
255
255
|
* registry — `{ ok, versions, published, latest, newest }` or `{ ok:false, error }`
|
|
256
256
|
* notes — the newest version's release notes, `{ ok, version, notes }` or
|
|
257
257
|
* `{ ok:false, version, error }`; `{ ok:false, skipped }` when the caller
|
|
258
|
-
* already holds notes that reach the newest version
|
|
258
|
+
* already holds notes that reach the newest version, or needs none
|
|
259
|
+
* (`haveNotesFor(newest, registry)`).
|
|
259
260
|
*
|
|
260
261
|
* `get` swaps the HTTPS transport and `store`/`now` the cache, so tests drive the real
|
|
261
262
|
* parsing and failure paths rather than a stub standing in front of them.
|
|
@@ -267,7 +268,7 @@ async function readRegistry({ pkg, haveNotesFor = () => false, get = https.get,
|
|
|
267
268
|
() => fetchPackument({ pkg, get, origin }), t);
|
|
268
269
|
if (!registry.ok) return { registry, notes: { ok: false, error: 'the registry could not be read' } };
|
|
269
270
|
const version = registry.newest;
|
|
270
|
-
if (haveNotesFor(version)) return { registry, notes: { ok: false, skipped: true, version } };
|
|
271
|
+
if (haveNotesFor(version, registry)) return { registry, notes: { ok: false, skipped: true, version } };
|
|
271
272
|
const ns = store.notes;
|
|
272
273
|
if (ns.version !== version) { ns.version = version; ns.value = null; ns.at = 0; }
|
|
273
274
|
const notes = await cached(ns, (s) => s.value.ok || t - s.at < RETRY_AFTER_MS,
|
|
@@ -31,6 +31,7 @@ const { asyncHandler } = require('./_helpers');
|
|
|
31
31
|
const auth = require('../auth');
|
|
32
32
|
const { readCoreUpdate, readCoreUpgrades } = require('../core-update');
|
|
33
33
|
const { readSoftwareUpdate } = require('../software-update');
|
|
34
|
+
const { followForShape } = require('../../../scripts/bongos/update-channel.js');
|
|
34
35
|
const seams = require('../../module-seams');
|
|
35
36
|
const { loadIdpConfig } = require('../auth-config');
|
|
36
37
|
const upgradeRequest = require('../upgrade-request');
|
|
@@ -88,6 +89,13 @@ function updateDoor({ provisioning, idp, hubUpgradeUrl }) {
|
|
|
88
89
|
return url ? { kind: 'hub', url } : { kind: 'cli', url: null };
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
// WHICH PUBLISHED VERSIONS THIS HALL MAY BE OFFERED (task 1004593, ADR 0361 D5): the hall that
|
|
93
|
+
// runs the door is the platform's own, the one project that takes every candidate; every other
|
|
94
|
+
// project follows releases, as the runner and /deploy offer them. followForShape is the runner's.
|
|
95
|
+
function followFor(door) {
|
|
96
|
+
return followForShape(door && door.kind === 'local' ? 'control-plane' : null);
|
|
97
|
+
}
|
|
98
|
+
|
|
91
99
|
function safeHubUpgradeUrl() {
|
|
92
100
|
try { return require('../../instance-config').resolveEnv('HUB_UPGRADE_URL') || null; } catch { return null; }
|
|
93
101
|
}
|
|
@@ -327,12 +335,12 @@ function buildCoreUpdateRouter({
|
|
|
327
335
|
asyncHandler('GET /software-update', async (req, res) => {
|
|
328
336
|
let running = null;
|
|
329
337
|
try { running = require('../../module-api').CORE_VERSION; } catch { /* version unknown */ }
|
|
338
|
+
const door = updateDoor(doorInputs());
|
|
330
339
|
// canUpdate does not depend on the rule, so it runs beside the rule read, not after it.
|
|
331
340
|
const [update, can] = await Promise.all([
|
|
332
|
-
resolveChannel(selfChannel).then(async ({ channel, source }) => ({ ...(await softwareUpdate({ running, channel })), channel_source: source })),
|
|
341
|
+
resolveChannel(selfChannel).then(async ({ channel, source }) => ({ ...(await softwareUpdate({ running, channel, follow: followFor(door) })), channel_source: source })),
|
|
333
342
|
canUpdate(req),
|
|
334
343
|
]);
|
|
335
|
-
const door = updateDoor(doorInputs());
|
|
336
344
|
const ask = await readAsk({ update, door, deps: askDeps() });
|
|
337
345
|
const held = await safeHold(upgradeHold, { running, offered: update && update.reading === 'ok' ? update.offered : null });
|
|
338
346
|
// The history only for a viewer who holds core.pin.move (see safeMoved's gate note).
|
|
@@ -357,8 +365,8 @@ function buildCoreUpdateRouter({
|
|
|
357
365
|
let running = null;
|
|
358
366
|
try { running = require('../../module-api').CORE_VERSION; } catch { /* version unknown */ }
|
|
359
367
|
const { channel } = await resolveChannel(selfChannel);
|
|
360
|
-
const update = await softwareUpdate({ running, channel });
|
|
361
368
|
const door = updateDoor(doorInputs());
|
|
369
|
+
const update = await softwareUpdate({ running, channel, follow: followFor(door) });
|
|
362
370
|
const deps = askDeps();
|
|
363
371
|
return upgradeRequest.requestUpgrade({
|
|
364
372
|
host: deps.host,
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
// /deploy, via the provisioning.selfUpdateChannel seam — task 1004535), else the runner's
|
|
23
23
|
// default. The banner (core-update.js) is handed the same rule, so the two cannot disagree.
|
|
24
24
|
//
|
|
25
|
+
// ONLY WHAT THIS PROJECT'S FOLLOW ADMITS IS OFFERED (task 1004593, ADR 0361 D5). Merges publish
|
|
26
|
+
// as candidates above the registry's `latest` label; a project that follows releases is offered
|
|
27
|
+
// nothing above it, through `versionsForFollow`, the function the runner and the banner use.
|
|
28
|
+
// Before this the panel offered a candidate that /deploy then said did not exist. The route
|
|
29
|
+
// names the follow: candidates only on the platform's own hall.
|
|
30
|
+
//
|
|
25
31
|
// A READING, NEVER A GUESS. `reading` is 'ok' only when the registry answered; "up to date"
|
|
26
32
|
// is `offered: null` on an ok reading and nothing else. Notes that could not be read say so,
|
|
27
33
|
// and a version whose notes are missing is shown as missing rather than as empty.
|
|
@@ -30,6 +36,8 @@ const {
|
|
|
30
36
|
CORE_PKG,
|
|
31
37
|
DEFAULT_CHANNEL,
|
|
32
38
|
normalizeChannel,
|
|
39
|
+
normalizeFollow,
|
|
40
|
+
versionsForFollow,
|
|
33
41
|
resolveChannelTarget,
|
|
34
42
|
compareSemver,
|
|
35
43
|
} = require('../../scripts/bongos/update-channel.js');
|
|
@@ -62,22 +70,29 @@ function entriesFor(notes, version) {
|
|
|
62
70
|
return out;
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
/** The published versions `follow` admits, oldest first; [] when a release follower has no label. */
|
|
74
|
+
function admittedVersions(follow, registry) {
|
|
75
|
+
return versionsForFollow({ follow, available: registry.versions, released: registry.latest });
|
|
76
|
+
}
|
|
77
|
+
|
|
65
78
|
/**
|
|
66
79
|
* The panel's whole answer, from one registry reading. PURE — no clock, no I/O.
|
|
67
80
|
*
|
|
68
81
|
* `registry` and `notes` are package-registry.js's `readRegistry` result. Versions in the
|
|
69
|
-
* update are the
|
|
82
|
+
* update are the admitted ones above `running` and at or below `offered`, newest first, and
|
|
83
|
+
* `newest` is the newest admitted version, so a candidate is never named to a release follower.
|
|
70
84
|
*/
|
|
71
|
-
function softwareUpdateVerdict({ running, channel, registry, notes, checkedAt }) {
|
|
85
|
+
function softwareUpdateVerdict({ running, channel, follow, registry, notes, checkedAt }) {
|
|
72
86
|
const ch = normalizeChannel(channel == null ? DEFAULT_CHANNEL : channel);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!registry || !registry.ok)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
const fol = normalizeFollow(follow);
|
|
88
|
+
const base = { checked_at: checkedAt, running: running || null, channel: ch, follow: fol };
|
|
89
|
+
const noAnswer = (error) => ({ ...base, reading: 'no_answer', error, offered: null, newest: null, whats_new: null });
|
|
90
|
+
if (!running || !VERSION_RE.test(String(running))) return noAnswer('this project could not name the version it runs');
|
|
91
|
+
if (!registry || !registry.ok) return noAnswer((registry && registry.error) || 'the registry could not be read');
|
|
92
|
+
const admitted = admittedVersions(fol, registry);
|
|
93
|
+
// No label, no answer: the runner moves a release follower on nothing it cannot call released.
|
|
94
|
+
if (!admitted.length) return noAnswer('the registry does not say which version is released');
|
|
95
|
+
const offered = resolveChannelTarget({ installed: running, channel: ch, available: admitted }) || null;
|
|
81
96
|
const published = registry.published || {};
|
|
82
97
|
const answer = {
|
|
83
98
|
...base,
|
|
@@ -85,12 +100,12 @@ function softwareUpdateVerdict({ running, channel, registry, notes, checkedAt })
|
|
|
85
100
|
error: null,
|
|
86
101
|
offered,
|
|
87
102
|
offered_published_at: offered ? published[offered] || null : null,
|
|
88
|
-
newest:
|
|
103
|
+
newest: admitted.reduce((a, v) => (compareSemver(v, a) > 0 ? v : a)),
|
|
89
104
|
whats_new: null,
|
|
90
105
|
};
|
|
91
106
|
if (!offered) return answer;
|
|
92
107
|
|
|
93
|
-
const inUpdate =
|
|
108
|
+
const inUpdate = admitted
|
|
94
109
|
.filter((v) => compareSemver(v, running) > 0 && compareSemver(v, offered) <= 0)
|
|
95
110
|
.sort((a, b) => compareSemver(b, a));
|
|
96
111
|
const shown = inUpdate.slice(0, VERSIONS_MAX);
|
|
@@ -115,14 +130,19 @@ function softwareUpdateVerdict({ running, channel, registry, notes, checkedAt })
|
|
|
115
130
|
* `get`/`now`/`store` pass through to the registry reader, so a test drives the real
|
|
116
131
|
* packument parsing, the real tarball stream and the real cache rather than a stub.
|
|
117
132
|
*/
|
|
118
|
-
async function readSoftwareUpdate({ running, channel, get, now = Date.now, store } = {}) {
|
|
133
|
+
async function readSoftwareUpdate({ running, channel, follow, get, now = Date.now, store } = {}) {
|
|
119
134
|
const t = now();
|
|
135
|
+
const fol = normalizeFollow(follow);
|
|
120
136
|
const { registry, notes } = await readRegistry({
|
|
121
137
|
pkg: CORE_PKG, get, now, store,
|
|
122
|
-
// Nothing to describe when nothing
|
|
123
|
-
haveNotesFor: (
|
|
138
|
+
// Nothing to describe when nothing this project could take is newer: skip the download.
|
|
139
|
+
haveNotesFor: (_newest, facts) => {
|
|
140
|
+
if (!VERSION_RE.test(String(running || ''))) return true;
|
|
141
|
+
const admitted = admittedVersions(fol, facts);
|
|
142
|
+
return !admitted.some((v) => compareSemver(v, running) > 0);
|
|
143
|
+
},
|
|
124
144
|
});
|
|
125
|
-
return softwareUpdateVerdict({ running, channel, registry, notes, checkedAt: new Date(t).toISOString() });
|
|
145
|
+
return softwareUpdateVerdict({ running, channel, follow: fol, registry, notes, checkedAt: new Date(t).toISOString() });
|
|
126
146
|
}
|
|
127
147
|
|
|
128
148
|
module.exports = { readSoftwareUpdate };
|
package/src/module-api.js
CHANGED
|
@@ -81,7 +81,7 @@ const { sleep } = require('./sleep');
|
|
|
81
81
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
82
82
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
83
83
|
|
|
84
|
-
const CORE_VERSION = '1.24.
|
|
84
|
+
const CORE_VERSION = '1.24.25'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
85
85
|
|
|
86
86
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
87
87
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
|
@@ -39,11 +39,12 @@ const NOTES = {
|
|
|
39
39
|
'1.20.0': [{ id: 200, text: 'The start of a new line.' }],
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
/** A registry that answers the packument and the NEWEST version's tarball.
|
|
43
|
-
|
|
42
|
+
/** A registry that answers the packument and the NEWEST version's tarball. `latest` is the
|
|
43
|
+
* release label (ADR 0361): every version above it is a candidate. */
|
|
44
|
+
function registry({ versions = VERSIONS, notes = NOTES, pkStatus = 200, tgzStatus = 200, tgz, latest } = {}) {
|
|
44
45
|
const newest = versions[versions.length - 1];
|
|
45
46
|
return fakeHttpsGet({
|
|
46
|
-
[PACKUMENT_URL]: { status: pkStatus, body: npmPackument({ versions, latest: newest, times: TIMES }) },
|
|
47
|
+
[PACKUMENT_URL]: { status: pkStatus, body: npmPackument({ versions, latest: latest === undefined ? newest : latest, times: TIMES }) },
|
|
47
48
|
[tgzUrl(newest)]: { status: tgzStatus, body: tgz || npmTarball({ notes }) },
|
|
48
49
|
});
|
|
49
50
|
}
|
|
@@ -148,6 +149,44 @@ test('a project far behind lists the newest forty and counts the rest', async ()
|
|
|
148
149
|
assert.equal(u.whats_new.versions[0].version, '1.19.51');
|
|
149
150
|
});
|
|
150
151
|
|
|
152
|
+
// ---- released vs candidate (task 1004593, ADR 0361 D5) --------------------------------
|
|
153
|
+
// The live defect, 2026-10-06, uattest (1.21.66, patch): npm `latest` was 1.21.66 and 1.21.69
|
|
154
|
+
// sat above it as a candidate. Settings offered 1.21.69; /deploy and the banner offered
|
|
155
|
+
// nothing. A project that follows releases must be offered what the runner would move it to.
|
|
156
|
+
|
|
157
|
+
test('a project that follows releases is offered nothing above the release label', async () => {
|
|
158
|
+
const reg = registry({ latest: '1.19.11' });
|
|
159
|
+
const u = await read('1.19.10', reg);
|
|
160
|
+
assert.equal(u.reading, 'ok');
|
|
161
|
+
assert.equal(u.follow, 'released', 'no follow given: the default, exactly as the runner');
|
|
162
|
+
assert.equal(u.offered, '1.19.11', '1.19.12 and 1.19.13 are candidates, never offered here');
|
|
163
|
+
assert.equal(u.newest, '1.19.11', 'and the newest it reports is the newest it could take, not a candidate');
|
|
164
|
+
assert.deepEqual(u.whats_new.versions.map((v) => v.version), ['1.19.11'], 'what\'s new stops at the offer');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('the uattest case: running the released version with only candidates above it is up to date', async () => {
|
|
168
|
+
const reg = registry({ latest: '1.19.10' });
|
|
169
|
+
const u = await read('1.19.10', reg);
|
|
170
|
+
assert.equal(u.reading, 'ok');
|
|
171
|
+
assert.equal(u.offered, null, 'Settings now agrees with /deploy: nothing it can take');
|
|
172
|
+
assert.equal(u.whats_new, null);
|
|
173
|
+
assert.deepEqual(reg.asked, [PACKUMENT_URL], 'and nothing is downloaded for a version it will never offer');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('the platform\'s own hall follows candidates and is offered them', async () => {
|
|
177
|
+
const u = await read('1.19.10', registry({ latest: '1.19.10' }), { follow: 'candidates' });
|
|
178
|
+
assert.equal(u.follow, 'candidates');
|
|
179
|
+
assert.equal(u.offered, '1.19.13');
|
|
180
|
+
assert.equal(u.newest, '1.20.0');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('a registry with no release label is no answer for a release follower — never "up to date"', async () => {
|
|
184
|
+
const u = await read('1.19.10', registry({ latest: null }));
|
|
185
|
+
assert.equal(u.reading, 'no_answer');
|
|
186
|
+
assert.match(u.error, /released/);
|
|
187
|
+
assert.equal(u.offered, null);
|
|
188
|
+
});
|
|
189
|
+
|
|
151
190
|
test('a second look within minutes asks the registry nothing new', async () => {
|
|
152
191
|
const reg = registry();
|
|
153
192
|
const store = fresh();
|
|
@@ -510,6 +549,25 @@ test('the REAL default reads the provisioning.selfUpdateChannel port — and wit
|
|
|
510
549
|
}
|
|
511
550
|
});
|
|
512
551
|
|
|
552
|
+
test('the route hands the reader the follow of the hall it serves: candidates only where the door runs (task 1004593)', async () => {
|
|
553
|
+
const cases = [
|
|
554
|
+
[{ provisioning: true, idp: null }, 'candidates', 'the platform\'s own hall, the one project that takes every candidate'],
|
|
555
|
+
[{ provisioning: false, idp: { origin: 'https://cloudbongos.com', clientId: 'uattest' } }, 'released', 'a hosted project'],
|
|
556
|
+
[{ provisioning: false, idp: null }, 'released', 'a self-hosted instance'],
|
|
557
|
+
];
|
|
558
|
+
for (const [inputs, want, what] of cases) {
|
|
559
|
+
let seen;
|
|
560
|
+
const r = await drive({ softwareUpdate: async (a) => { seen = a; return STUB_UPDATE; }, canUpdate: async () => true, doorInputs: () => inputs });
|
|
561
|
+
assert.equal(r.status, 200, what);
|
|
562
|
+
assert.equal(seen.follow, want, what);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test('[source] the upgrade request asks with the same follow as the panel (task 1004593)', () => {
|
|
567
|
+
const seg = ROUTE_SRC.slice(ROUTE_SRC.indexOf("'/software-update/request'"), ROUTE_SRC.indexOf("'/project/manage-link'"));
|
|
568
|
+
assert.match(seg, /softwareUpdate\(\{ running, channel, follow: followFor\(door\) \}\)/, 'the version asked for is one the runner would take');
|
|
569
|
+
});
|
|
570
|
+
|
|
513
571
|
test('[source] the port the route reads is the port the provisioning module registers and declares (task 1004535)', () => {
|
|
514
572
|
const port = 'provisioning.selfUpdateChannel';
|
|
515
573
|
const route = fs.readFileSync(path.join(ROOT, 'src/bongos/routes/core-update.js'), 'utf8');
|