@bongos/core 1.19.27 → 1.19.28
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 +11 -11
- package/modules/lifecycle/github-push.js +5 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/run-unit-tests.js +18 -3
- package/src/module-api.js +3 -1
- package/tests/gate_approvals.mjs +13 -8
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.28",
|
|
6
|
+
"core_contract": "1.19.28",
|
|
7
|
+
"source_commit": "10e31a3212982a5385e83bec33a5ba12b733929f",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-
|
|
9
|
+
"built_at": "2026-08-11T14:01:24.503Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 285,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1511,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "e1dee62e1e6e30b75671474f69e5e6b97f0ea598c9a66b5ad49867906f85e51d",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -3362,7 +3362,7 @@
|
|
|
3362
3362
|
{
|
|
3363
3363
|
"path": "modules/lifecycle/github-push.js",
|
|
3364
3364
|
"mode": "0000644",
|
|
3365
|
-
"sha256": "
|
|
3365
|
+
"sha256": "60b9338ed47d01e9f38fe3fa9f2f2cde6ff241b8e47efcb8fcf4c4f19d32c766"
|
|
3366
3366
|
},
|
|
3367
3367
|
{
|
|
3368
3368
|
"path": "modules/lifecycle/goal-advisory.js",
|
|
@@ -4002,12 +4002,12 @@
|
|
|
4002
4002
|
{
|
|
4003
4003
|
"path": "package-lock.json",
|
|
4004
4004
|
"mode": "0000644",
|
|
4005
|
-
"sha256": "
|
|
4005
|
+
"sha256": "8ecf54691f56a0579f3d732323aebbe9620b3b46fa6f8711a959f20dac1cffaa"
|
|
4006
4006
|
},
|
|
4007
4007
|
{
|
|
4008
4008
|
"path": "package.json",
|
|
4009
4009
|
"mode": "0000644",
|
|
4010
|
-
"sha256": "
|
|
4010
|
+
"sha256": "d7dcf7da61008463a0e5ddb5da440f85bd845a2a0ea8d8125c2684dad24cdac6"
|
|
4011
4011
|
},
|
|
4012
4012
|
{
|
|
4013
4013
|
"path": "public-docs/index.html",
|
|
@@ -5042,7 +5042,7 @@
|
|
|
5042
5042
|
{
|
|
5043
5043
|
"path": "scripts/gds/run-unit-tests.js",
|
|
5044
5044
|
"mode": "0000644",
|
|
5045
|
-
"sha256": "
|
|
5045
|
+
"sha256": "7f0ad4e54c0e5c251f00c78c7a6065d4a8db7bc88f0492c75bc63f8929108203"
|
|
5046
5046
|
},
|
|
5047
5047
|
{
|
|
5048
5048
|
"path": "scripts/gds/sandbox-stage.js",
|
|
@@ -5627,7 +5627,7 @@
|
|
|
5627
5627
|
{
|
|
5628
5628
|
"path": "src/module-api.js",
|
|
5629
5629
|
"mode": "0000644",
|
|
5630
|
-
"sha256": "
|
|
5630
|
+
"sha256": "b97afd8c79d048c057170fb03010be8d89f051cc8d4c43a2ecb85343785fe194"
|
|
5631
5631
|
},
|
|
5632
5632
|
{
|
|
5633
5633
|
"path": "src/module-loader/loader.js",
|
|
@@ -6357,7 +6357,7 @@
|
|
|
6357
6357
|
{
|
|
6358
6358
|
"path": "tests/gate_approvals.mjs",
|
|
6359
6359
|
"mode": "0000644",
|
|
6360
|
-
"sha256": "
|
|
6360
|
+
"sha256": "df503f198853f6fe3497a2e0317d90bee69cc275f024027ad569ee1cef0155b6"
|
|
6361
6361
|
},
|
|
6362
6362
|
{
|
|
6363
6363
|
"path": "tests/gate_review.mjs",
|
|
@@ -1002,6 +1002,10 @@ async function recheckPullRequest({ number }, deps = {}) {
|
|
|
1002
1002
|
const { owner, repo } = repoInfo;
|
|
1003
1003
|
const doFetch = deps.fetchImpl || fetch;
|
|
1004
1004
|
const reopenDelayMs = Number.isFinite(deps.reopenDelayMs) ? deps.reopenDelayMs : RECHECK_REOPEN_DELAY_MS;
|
|
1005
|
+
// task 1002644: injectable so the unit test pins the sleep's PLACE in the
|
|
1006
|
+
// close→reopen sequence without a real timer — a wall-clock elapsed assertion
|
|
1007
|
+
// around a real sleep flaked the unit lane (the only required merge check).
|
|
1008
|
+
const doSleep = deps.sleepImpl || sleep;
|
|
1005
1009
|
const api = `https://api.github.com/repos/${owner}/${repo}`;
|
|
1006
1010
|
const patchState = async (state) => {
|
|
1007
1011
|
const res = await doFetch(`${api}/pulls/${number}`, {
|
|
@@ -1018,7 +1022,7 @@ async function recheckPullRequest({ number }, deps = {}) {
|
|
|
1018
1022
|
await patchState('closed');
|
|
1019
1023
|
// Let GitHub register the close as a distinct state transition before reopening, so
|
|
1020
1024
|
// the reopen actually dispatches a `pull_request: reopened` event (task 1241).
|
|
1021
|
-
if (reopenDelayMs > 0) await
|
|
1025
|
+
if (reopenDelayMs > 0) await doSleep(reopenDelayMs);
|
|
1022
1026
|
const reopened = await patchState('open');
|
|
1023
1027
|
let autoMerge = false;
|
|
1024
1028
|
try {
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.28",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.28",
|
|
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.19.
|
|
3
|
+
"version": "1.19.28",
|
|
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",
|
|
@@ -184,16 +184,31 @@ function main() {
|
|
|
184
184
|
const runOne = (displayName, filePath) => {
|
|
185
185
|
try {
|
|
186
186
|
execFileSync(process.execPath, [filePath], {
|
|
187
|
-
|
|
187
|
+
// task 1002644: stdout used to be IGNORED, so the failing assertion (test
|
|
188
|
+
// files print their FAIL lines to stdout) was discarded and the only
|
|
189
|
+
// context shown was the last 3 STDERR lines — often stale diagnostic
|
|
190
|
+
// noise from an EARLIER, PASSING test. The live example: gate_approvals'
|
|
191
|
+
// route-catch console.error dump made every failure in that file read as
|
|
192
|
+
// a GraphQL/network outage, and the real flaky assertion was invisible.
|
|
193
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
194
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
188
195
|
timeout: perTestTimeout,
|
|
189
196
|
env: { ...process.env, NODE_ENV: 'test' },
|
|
190
197
|
});
|
|
191
198
|
console.log(` ok ${displayName}`);
|
|
192
199
|
} catch (err) {
|
|
193
200
|
const why = err.killed ? 'TIMEOUT' : `exit ${err.status}`;
|
|
194
|
-
const stderr = (err.stderr ? err.stderr.toString() : '').trim().split('\n').slice(-3).join('\n ');
|
|
195
201
|
console.log(` FAIL ${displayName} (${why})`);
|
|
196
|
-
|
|
202
|
+
const stdoutText = (err.stdout ? err.stdout.toString() : '').trim();
|
|
203
|
+
// The actual failures first: the file's own FAIL lines, then its stdout
|
|
204
|
+
// tail (the last failure's assertion detail + summary), both bounded.
|
|
205
|
+
const failLines = stdoutText ? stdoutText.split('\n').filter((l) => /\bFAIL\b/.test(l)).slice(0, 5) : [];
|
|
206
|
+
for (const l of failLines) console.log(` ${l.trim()}`);
|
|
207
|
+
if (stdoutText) {
|
|
208
|
+
for (const l of stdoutText.split('\n').slice(-5)) console.log(` ${l}`);
|
|
209
|
+
}
|
|
210
|
+
const stderr = (err.stderr ? err.stderr.toString() : '').trim().split('\n').slice(-3).join('\n ');
|
|
211
|
+
if (stderr) console.log(` stderr: ${stderr}`);
|
|
197
212
|
failures.push(displayName);
|
|
198
213
|
}
|
|
199
214
|
};
|
package/src/module-api.js
CHANGED
|
@@ -481,8 +481,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
481
481
|
// landed since 1.19.25 with no explicit bump. run 31495996665. (task 1002620)
|
|
482
482
|
// 1.19.27 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
483
483
|
// landed since 1.19.26 with no explicit bump. run 31497212656. (task 1002620)
|
|
484
|
+
// 1.19.28 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
485
|
+
// landed since 1.19.27 with no explicit bump. run 31499228797. (task 1002620)
|
|
484
486
|
// ---------------------------------------------------------------------------
|
|
485
|
-
const CORE_VERSION = '1.19.
|
|
487
|
+
const CORE_VERSION = '1.19.28'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
486
488
|
|
|
487
489
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
488
490
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
package/tests/gate_approvals.mjs
CHANGED
|
@@ -208,21 +208,26 @@ await t('recheckPullRequest: waits between close and reopen so GitHub fires a di
|
|
|
208
208
|
// into no net change and dispatches no `pull_request: reopened` event, so the
|
|
209
209
|
// gate-review run never re-fires. recheckPullRequest must sleep BETWEEN the close
|
|
210
210
|
// PATCH and the reopen PATCH (deps.reopenDelayMs, default 4s in prod) so the reopen
|
|
211
|
-
// lands as a distinct state transition.
|
|
212
|
-
//
|
|
211
|
+
// lands as a distinct state transition.
|
|
212
|
+
//
|
|
213
|
+
// task 1002644: this used to sleep a REAL 30ms and assert wall-clock elapsed >=
|
|
214
|
+
// 30 — Date.now() truncation + NTP slew on CI runners can read a punctual timer
|
|
215
|
+
// as 29ms, which flaked the unit lane (the ONLY required merge check, ADR 0162).
|
|
216
|
+
// Inject the sleep and assert its PLACE in the event sequence instead — strictly
|
|
217
|
+
// stronger (total elapsed never proved the wait sat BETWEEN the two PATCHes) and
|
|
218
|
+
// fully deterministic.
|
|
213
219
|
const events = [];
|
|
214
|
-
const delayMs =
|
|
220
|
+
const delayMs = 4000; // the prod-default shape — never actually slept (injected)
|
|
215
221
|
const fetchImpl = async (url, opts) => {
|
|
216
222
|
const method = (opts && opts.method) || 'GET';
|
|
217
223
|
if (method === 'PATCH') { events.push('patch:' + JSON.parse(opts.body).state); return jsonRes(200, { node_id: 'N1', state: JSON.parse(opts.body).state }); }
|
|
218
224
|
if (url === 'https://api.github.com/graphql') { events.push('automerge'); return jsonRes(200, { data: { enablePullRequestAutoMerge: {} } }); }
|
|
219
225
|
throw new Error('unexpected ' + url + ' ' + method);
|
|
220
226
|
};
|
|
221
|
-
const
|
|
222
|
-
await gp.recheckPullRequest({ number: 202 }, { token: 'T', repoInfo: REPO, fetchImpl, reopenDelayMs: delayMs });
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
assert.ok(elapsed >= delayMs, `total elapsed (${elapsed}ms) must be at least the configured reopen delay (${delayMs}ms)`);
|
|
227
|
+
const sleepImpl = async (ms) => { events.push(`sleep:${ms}`); };
|
|
228
|
+
await gp.recheckPullRequest({ number: 202 }, { token: 'T', repoInfo: REPO, fetchImpl, sleepImpl, reopenDelayMs: delayMs });
|
|
229
|
+
assert.deepEqual(events, ['patch:closed', `sleep:${delayMs}`, 'patch:open', 'automerge'],
|
|
230
|
+
'the wait happens BETWEEN the close and the reopen — a coalesced close+reopen dispatches no reopened event');
|
|
226
231
|
});
|
|
227
232
|
|
|
228
233
|
// ===========================================================================
|