From 1bfcb7500b84091ca417fcc8e0a9cc69cc18b61f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:48:24 +0000 Subject: [PATCH 1/5] chore(deps): bump actions/upload-artifact from 4 to 7 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test-tools.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test-tools.yml b/.github/workflows/test-tools.yml index ceab4b1ef5..4933199315 100644 --- a/.github/workflows/test-tools.yml +++ b/.github/workflows/test-tools.yml @@ -137,7 +137,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-isolated-tests path: ./tmp/results @@ -203,7 +203,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-0 path: ./tmp/results @@ -268,7 +268,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-1 path: ./tmp/results @@ -341,7 +341,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-2 path: ./tmp/results @@ -406,7 +406,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-3 path: ./tmp/results @@ -471,7 +471,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-4 path: ./tmp/results @@ -537,7 +537,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-5 path: ./tmp/results @@ -602,7 +602,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-6 path: ./tmp/results @@ -667,7 +667,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-7 path: ./tmp/results @@ -732,7 +732,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-8 path: ./tmp/results @@ -797,7 +797,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-9 path: ./tmp/results @@ -862,7 +862,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-10 path: ./tmp/results @@ -927,7 +927,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: junit-group-11 path: ./tmp/results From 809fd362e04a9266aa99953d291792401a43ae5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:48:26 +0000 Subject: [PATCH 2/5] chore(deps): bump actions/github-script from 8 to 9 Bumps [actions/github-script](https://github.com/actions/github-script) from 8 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v8...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/inactive-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/inactive-issues.yml b/.github/workflows/inactive-issues.yml index 620b484db6..f28c24f6e7 100644 --- a/.github/workflows/inactive-issues.yml +++ b/.github/workflows/inactive-issues.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v3 - name: Manage inactive issues - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const script = require('./.github/scripts/inactive-issues.js') From 099fefdbcd3f4b81fe7625b836f15a0f3db6068a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Apr 2026 12:56:24 -0500 Subject: [PATCH 3/5] fix(mongo): make observeChangesAsync callback-error test deterministic --- packages/mongo/tests/mongo_livedata_tests.js | 36 +++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/mongo/tests/mongo_livedata_tests.js b/packages/mongo/tests/mongo_livedata_tests.js index f3e32106a5..e155f2a053 100644 --- a/packages/mongo/tests/mongo_livedata_tests.js +++ b/packages/mongo/tests/mongo_livedata_tests.js @@ -4545,17 +4545,24 @@ Meteor.isServer && testAsyncMulti( { resolverType: 'stub' } ); - let insertId; - await Collection.find({}).observeChangesAsync({ + let observerInsertId; + let resolveObserver; + const observerFired = new Promise((resolve) => { resolveObserver = resolve; }); + + const handle = await Collection.find({}).observeChangesAsync({ async added(_id, fields) { - insertId = _id; + observerInsertId = _id; + resolveObserver(); throw new Error('Test error in async added observeChangesAsync'); }, }); - return Collection.insertAsync({ foo: { bar: 123 } }).finally((id, bad) => { - test.equal(insertId, id); - }) + // insertAsync resolves normally — observer errors are caught and logged, + // not propagated back to the caller (see observe_multiplex `_applyCallback`). + const id = await Collection.insertAsync({ foo: { bar: 123 } }); + await observerFired; + test.equal(observerInsertId, id); + await handle.stop(); }, async (test) => { @@ -4564,17 +4571,22 @@ Meteor.isServer && testAsyncMulti( { resolverType: 'stub' } ); - let insertId; - await Collection.find({}).observeChangesAsync({ + let observerInsertId; + let resolveObserver; + const observerFired = new Promise((resolve) => { resolveObserver = resolve; }); + + const handle = await Collection.find({}).observeChangesAsync({ added(id) { - insertId = _id; + observerInsertId = id; + resolveObserver(); throw new Error('Test error in sync added observeChangesAsync'); }, }); - return Collection.insertAsync({ foo: { bar: 123 } }).finally((id, bad) => { - test.equal(insertId, id); - }) + const id = await Collection.insertAsync({ foo: { bar: 123 } }); + await observerFired; + test.equal(observerInsertId, id); + await handle.stop(); } ] ); From 5eb2df51b79ac4a63566bdbfda629a035396abe8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 23 Apr 2026 09:40:42 -0500 Subject: [PATCH 4/5] re-run checks From 6b877fd87049b72271112a1a5c79934af8961ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Thu, 23 Apr 2026 17:47:03 +0200 Subject: [PATCH 5/5] cherrypick fix on group 5 by simplify environment variable overrides and match assertions --- tools/tests/modern.js | 1011 +++++++++++++++++++++-------------------- 1 file changed, 520 insertions(+), 491 deletions(-) diff --git a/tools/tests/modern.js b/tools/tests/modern.js index 374c219a15..30681d55b7 100644 --- a/tools/tests/modern.js +++ b/tools/tests/modern.js @@ -1,9 +1,33 @@ -var selftest = require('../tool-testing/selftest.js'); +var selftest = require("../tool-testing/selftest.js"); var Sandbox = selftest.Sandbox; -var files = require('../fs/files'); +var files = require("../fs/files"); // No need for a high value since the asserts already wait long enough to pass tests const waitToStart = 5; +// Budget for `meteor build` to fully exit. Doubled on CI where the container +// is resource-constrained and the build can take substantially longer than +// locally. +const buildWaitSecs = process.env.CI ? 90 : 60; + +// Applies env var overrides for the duration of `fn`, then restores them on +// every exit path. Required for retry-compatibility: without the try/finally, +// a mid-body failure would leak the mutated env into the subsequent retry and +// into the Sandbox it spawns, producing a different starting state than the +// first attempt. +async function withEnv(overrides, fn) { + const saved = Object.fromEntries( + Object.keys(overrides).map((k) => [k, process.env[k]]) + ); + Object.assign(process.env, overrides); + try { + return await fn(); + } finally { + for (const [k, v] of Object.entries(saved)) { + if (v === undefined) delete process.env[k]; + else process.env[k] = v; + } + } +} async function writeModernConfig(s, modernConfig) { const json = JSON.parse(s.read("package.json")); @@ -17,360 +41,369 @@ async function writeModernConfig(s, modernConfig) { } selftest.define("modern build stack - legacy", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = 'false'; + await withEnv({ METEOR_MODERN: "false" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); - s.set("METEOR_PROFILE", "0"); + await writeModernConfig(s, false); - await writeModernConfig(s, false); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + const out = run.getMatcherFullBuffer(); - /* check legacy stack */ - await run.match(/Babel\.compile/, false, true); - await run.match(/safeWatcher\.watchLegacy/, false, true); - await run.match(/_findSources for web\.browser.legacy/, false, true); + /* check legacy stack */ + selftest.expectTrue(/Babel\.compile/.test(out)); + selftest.expectTrue(/safeWatcher\.watchLegacy/.test(out)); + selftest.expectTrue(/_findSources for web\.browser\.legacy/.test(out)); - /* check debug stack */ - await run.match(/server\/main\.js:6:22/, false, true); + /* check debug stack */ + selftest.expectTrue(/server\/main\.js:6:22/.test(out)); - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; + await run.stop(); + }); }); selftest.define("modern build stack", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); - s.set("METEOR_PROFILE", "0"); + await writeModernConfig(s, true); - await writeModernConfig(s, true); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + const out = run.getMatcherFullBuffer(); - /* check modern stack */ - await run.match(/SWC\.compile/, false, true); - await run.match(/safeWatcher\.watchModern/, false, true); - await run.match(/_findSources for web\.browser/, false, true); + /* check modern stack */ + selftest.expectTrue(/SWC\.compile/.test(out)); + selftest.expectTrue(/safeWatcher\.watchModern/.test(out)); + selftest.expectTrue(/_findSources for web\.browser/.test(out)); - run.forbid(/Babel\.compile/, false, true); - run.forbid(/_findSources for web\.browser\.legacy/, false, true); + selftest.expectFalse(/Babel\.compile/.test(out)); + selftest.expectFalse(/_findSources for web\.browser\.legacy/.test(out)); - /* check debug stack */ - await run.match(/server\/main\.js:6:22/, false, true); + /* check debug stack */ + selftest.expectTrue(/server\/main\.js:6:22/.test(out)); - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; + await run.stop(); + }); }); selftest.define("modern build stack - disable transpiler", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); - s.set("METEOR_PROFILE", "0"); + await writeModernConfig(s, { transpiler: false }); - await writeModernConfig(s, { transpiler: false }); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + const out = run.getMatcherFullBuffer(); - /* disable transpiler */ - run.forbid(/SWC\.compile/, false, true); - await run.match(/Babel\.compile/, false, true); + /* disable transpiler */ + selftest.expectFalse(/SWC\.compile/.test(out)); + selftest.expectTrue(/Babel\.compile/.test(out)); - /* Keep rest of modern build stack */ - await run.match(/safeWatcher\.watchModern/, false, true); - await run.match(/_findSources for web\.browser/, false, true); - run.forbid(/_findSources for web\.browser\.legacy/, false, true); + /* Keep rest of modern build stack */ + selftest.expectTrue(/safeWatcher\.watchModern/.test(out)); + selftest.expectTrue(/_findSources for web\.browser/.test(out)); + selftest.expectFalse(/_findSources for web\.browser\.legacy/.test(out)); - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; + await run.stop(); + }); }); selftest.define("modern build stack - disable watcher", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); - s.set("METEOR_PROFILE", "0"); + await writeModernConfig(s, { watcher: false }); - await writeModernConfig(s, { watcher: false }); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + const out = run.getMatcherFullBuffer(); - /* disable watcher */ - run.forbid(/safeWatcher\.watchModern/, false, true); - await run.match(/safeWatcher\.watchLegacy/, false, true); + /* disable watcher */ + selftest.expectFalse(/safeWatcher\.watchModern/.test(out)); + selftest.expectTrue(/safeWatcher\.watchLegacy/.test(out)); - /* Keep rest of modern build stack */ - await run.match(/SWC\.compile/, false, true); - await run.match(/_findSources for web\.browser/, false, true); - run.forbid(/_findSources for web\.browser\.legacy/, false, true); + /* Keep rest of modern build stack */ + selftest.expectTrue(/SWC\.compile/.test(out)); + selftest.expectTrue(/_findSources for web\.browser/.test(out)); + selftest.expectFalse(/_findSources for web\.browser\.legacy/.test(out)); - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; + await run.stop(); + }); }); selftest.define("modern build stack - disable webArchOnly", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); - s.set("METEOR_PROFILE", "0"); + await writeModernConfig(s, { webArchOnly: false }); - await writeModernConfig(s, { webArchOnly: false }); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + const out = run.getMatcherFullBuffer(); - /* disable webArchOnly */ - await run.match(/_findSources for web\.browser/, false, true); - await run.match(/_findSources for web\.browser\.legacy/, false, true); + /* disable webArchOnly */ + selftest.expectTrue(/_findSources for web\.browser/.test(out)); + selftest.expectTrue(/_findSources for web\.browser\.legacy/.test(out)); - /* Keep rest of modern build stack */ - await run.match(/safeWatcher\.watchModern/, false, true); - await run.match(/SWC\.compile/, false, true); + /* Keep rest of modern build stack */ + selftest.expectTrue(/safeWatcher\.watchModern/.test(out)); + selftest.expectTrue(/SWC\.compile/.test(out)); - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; + await run.stop(); + }); }); -selftest.define("modern build stack - transpiler boolean-like options", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; +selftest.define( + "modern build stack - transpiler boolean-like options", + async function () { + await withEnv( + { METEOR_MODERN: "", METEOR_DISABLE_COLORS: "true" }, + async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + s.mkdir("config-package"); + s.cd("config-package"); - s.mkdir("config-package"); - s.cd("config-package"); + s.write( + "package.json", + JSON.stringify( + { + name: "config", + version: "1.2.3", + private: true, + main: "index.js", + }, + null, + 2 + ) + "\n" + ); - s.write( - "package.json", - JSON.stringify({ - name: "config", - version: "1.2.3", - "private": true, - main: "index.js" - }, null, 2) + "\n" - ); + s.write("index.js", "exports.id = module.id;\n"); - s.write( - "index.js", - "exports.id = module.id;\n" - ); + s.cd(s.home); - s.cd(s.home); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); - - s.append( - "server/main.js", - `if (require('config')) { + s.append( + "server/main.js", + `if (require('config')) { console.log('Loaded NPM package "config"', require('config').id); -}`); +}` + ); - process.env.METEOR_DISABLE_COLORS = true; + await writeModernConfig(s, { + transpiler: { + verbose: true, + }, + }); - await writeModernConfig(s, { - transpiler: { - verbose: true, - }, - }); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + /* check appended NPM package require */ + await run.match(/Loaded NPM package "config"/, false, true); - /* check appended NPM package require */ - await run.match(/Loaded NPM package "config"/, false, true); + /* check verbose logs */ + await run.match(/SWC Custom Config/, false, true); + await run.match(/Meteor Config/, false, true); - /* check verbose logs */ - await run.match(/SWC Custom Config/, false, true); - await run.match(/Meteor Config/, false, true); + /* check transpiler options */ + await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); + await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); + run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); - /* check transpiler options */ - await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); - await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); - run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); + await writeModernConfig(s, { + transpiler: { + verbose: true, + excludeApp: true, + }, + }); + await run.match(/\[Transpiler] Used Babel.*\(app\)/, false, true); - await writeModernConfig(s, { - transpiler: { - verbose: true, - excludeApp: true, - }, - }); - await run.match(/\[Transpiler] Used Babel.*\(app\)/, false, true); + await writeModernConfig(s, { + transpiler: { + verbose: true, + excludePackages: true, + }, + }); + await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); - await writeModernConfig(s, { - transpiler: { - verbose: true, - excludePackages: true, - }, - }); - await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); + await writeConfig(s, { + modern: { + transpiler: { + verbose: true, + }, + }, + nodeModules: { + recompile: { + config: true, + }, + }, + }); + await run.match( + /\[Transpiler] Used SWC.*\(node_modules\)/, + false, + true + ); - await writeConfig(s, { - modern: { - transpiler: { - verbose: true, - }, - }, - nodeModules: { - recompile: { - config: true, - }, - }, - }); - await run.match(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); + await run.stop(); + } + ); + } +); - await run.stop(); +selftest.define( + "modern build stack - transpiler string-like options", + async function () { + await withEnv( + { METEOR_MODERN: "", METEOR_DISABLE_COLORS: "true" }, + async () => { + const s = new Sandbox(); + await s.init(); - process.env.METEOR_MODERN = currentMeteorModern; -}); + s.mkdir("config-package"); + s.cd("config-package"); -selftest.define("modern build stack - transpiler string-like options", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + s.write( + "package.json", + JSON.stringify( + { + name: "config", + version: "1.2.3", + private: true, + main: "index.js", + }, + null, + 2 + ) + "\n" + ); - const s = new Sandbox(); - await s.init(); + s.write("index.js", "exports.id = module.id;\n"); - s.mkdir("config-package"); - s.cd("config-package"); + s.cd(s.home); - s.write( - "package.json", - JSON.stringify({ - name: "config", - version: "1.2.3", - "private": true, - main: "index.js" - }, null, 2) + "\n" - ); + await s.createApp("modern", "modern"); + await s.cd("modern"); - s.write( - "index.js", - "exports.id = module.id;\n" - ); + s.append( + "server/main.js", + `import { id } from 'config'; +console.log('Loaded NPM package "config"', require('config').id);` + ); - s.cd(s.home); + await writeModernConfig(s, { + transpiler: { + verbose: true, + }, + }); - await s.createApp("modern", "modern"); - await s.cd("modern"); + const run = s.run(); - s.append( - "server/main.js", - `import { id } from 'config'; -console.log('Loaded NPM package "config"', require('config').id);`); + run.waitSecs(waitToStart); + await run.match("App running at"); - process.env.METEOR_DISABLE_COLORS = true; + /* check appended NPM package imported */ + await run.match(/Loaded NPM package "config"/, false, true); - await writeModernConfig(s, { - transpiler: { - verbose: true, - }, - }); + /* check verbose logs */ + await run.match(/SWC Custom Config/, false, true); + await run.match(/Meteor Config/, false, true); - const run = s.run(); + /* check transpiler options */ + await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); + await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); + run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); - run.waitSecs(waitToStart); - await run.match("App running at"); + await writeModernConfig(s, { + transpiler: { + verbose: true, + excludeApp: ["main.js"], + }, + }); + await run.match(/\[Transpiler] Used Babel.*\(app\)/, false, true); - /* check appended NPM package imported */ - await run.match(/Loaded NPM package "config"/, false, true); + await writeModernConfig(s, { + transpiler: { + verbose: true, + excludePackages: ["ejson"], + }, + }); + await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); - /* check verbose logs */ - await run.match(/SWC Custom Config/, false, true); - await run.match(/Meteor Config/, false, true); + await writeConfig(s, { + modern: { + transpiler: { + verbose: true, + }, + }, + nodeModules: { + recompile: { + config: true, + }, + }, + }); + await run.match( + /\[Transpiler] Used SWC.*\(node_modules\)/, + false, + true + ); - /* check transpiler options */ - await run.match(/\[Transpiler] Used SWC.*\(app\)/, false, true); - await run.match(/\[Transpiler] Used SWC.*\(package\)/, false, true); - run.forbid(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); - - await writeModernConfig(s, { - transpiler: { - verbose: true, - excludeApp: ['main.js'], - }, - }); - await run.match(/\[Transpiler] Used Babel.*\(app\)/, false, true); - - await writeModernConfig(s, { - transpiler: { - verbose: true, - excludePackages: ['ejson'], - }, - }); - await run.match(/\[Transpiler] Used Babel.*\(package\)/, false, true); - - await writeConfig(s, { - modern: { - transpiler: { - verbose: true, - }, - }, - nodeModules: { - recompile: { - config: true, - }, - }, - }); - await run.match(/\[Transpiler] Used SWC.*\(node_modules\)/, false, true); - - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; -}); + await run.stop(); + } + ); + } +); async function writeConfig(s, config) { const json = JSON.parse(s.read("package.json")); @@ -398,287 +431,283 @@ async function writeSwcConfigJs(s, config) { s.write("swc.config.js", jsContent); } -selftest.define("modern build stack - transpiler custom .swcrc", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; +selftest.define( + "modern build stack - transpiler custom .swcrc", + async function () { + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/alias.js", + }, + }); - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/alias.js', - }, - }); + const run = s.run(); - const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); - run.waitSecs(waitToStart); - await run.match("App running at"); + /* custom .swcrc and alias resolution */ + await run.match(/alias resolved/, false, true); - /* custom .swcrc and alias resolution */ - await run.match(/alias resolved/, false, true); + await run.stop(); + }); + } +); - await run.stop(); +selftest.define( + "modern build stack - transpiler custom swc.config.js", + async function () { + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - process.env.METEOR_MODERN = currentMeteorModern; -}); + await s.createApp("modern", "modern"); + await s.cd("modern"); -selftest.define("modern build stack - transpiler custom swc.config.js", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + // Remove the .swcrc file to ensure we're using swc.config.js + s.unlink(".swcrc"); - const s = new Sandbox(); - await s.init(); + // Write the swc.config.js file with the same configuration + await writeSwcConfigJs(s, { + jsc: { + baseUrl: "./", + paths: { + "@swcAlias/*": ["swcAlias/*"], + }, + }, + }); - await s.createApp("modern", "modern"); - await s.cd("modern"); + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/alias.js", + }, + }); - // Remove the .swcrc file to ensure we're using swc.config.js - s.unlink(".swcrc"); + const run = s.run(); - // Write the swc.config.js file with the same configuration - await writeSwcConfigJs(s, { - jsc: { - baseUrl: "./", - paths: { - "@swcAlias/*": ["swcAlias/*"] - } - } - }); + run.waitSecs(waitToStart); + await run.match("App running at"); - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/alias.js', - }, - }); + /* custom swc.config.js and alias resolution */ + await run.match(/alias resolved/, false, true); - const run = s.run(); - - run.waitSecs(waitToStart); - await run.match("App running at"); - - /* custom swc.config.js and alias resolution */ - await run.match(/alias resolved/, false, true); - - await run.stop(); - - process.env.METEOR_MODERN = currentMeteorModern; -}); + await run.stop(); + }); + } +); selftest.define("modern build stack - transpiler files", async function () { - process.env.METEOR_MODERN = 'true'; - const s = new Sandbox(); - await s.init(); + await withEnv({ METEOR_MODERN: "true" }, async () => { + const s = new Sandbox(); + await s.init(); - await s.createApp("modern", "modern"); - await s.cd("modern"); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/javascript.js', - }, - }); - - const run = s.run(); - - run.waitSecs(waitToStart); - await run.match("App running at"); - - await run.match(/javascript\.js/, false, true); - - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/javascript-component.jsx', - }, - }); - await run.match(/javascript-component\.jsx/, false, true); - - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/typescript.ts', - }, - }); - await run.match(/typescript\.ts/, false, true); - - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/typescript-component.tsx', - }, - }); - await run.match(/typescript-component\.tsx/, false, true); - - await writeSwcrcConfig(s, { - jsc: { - parser: { - syntax: 'typescript', - tsx: true, - jsx: true, + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/javascript.js", }, - }, - }); - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/custom-component.js', - }, - }); - await run.match(/custom-component\.js/, false, true); + }); - await run.stop(); + const run = s.run(); + run.waitSecs(waitToStart); + await run.match("App running at"); + + await run.match(/javascript\.js/, false, true); + + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/javascript-component.jsx", + }, + }); + await run.match(/javascript-component\.jsx/, false, true); + + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/typescript.ts", + }, + }); + await run.match(/typescript\.ts/, false, true); + + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/typescript-component.tsx", + }, + }); + await run.match(/typescript-component\.tsx/, false, true); + + await writeSwcrcConfig(s, { + jsc: { + parser: { + syntax: "typescript", + tsx: true, + jsx: true, + }, + }, + }); + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/custom-component.js", + }, + }); + await run.match(/custom-component\.js/, false, true); + + await run.stop(); + }); }); selftest.define("modern build stack - test terser minifier", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; - const s = new Sandbox(); - await s.init(); + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const appName = "terser-app"; + const appName = "terser-app"; - await s.createApp(appName, "modern"); - await s.cd(appName); + await s.createApp(appName, "modern"); + await s.cd(appName); - await writeConfig(s, { - modern: false + await writeConfig(s, { + modern: false, + }); + + s.set("NODE_INSPECTOR_IPC", "1"); + + const runTerser = s.run(); + runTerser.waitSecs(waitToStart); + await runTerser.match("App running at"); + await runTerser.stop(); + + const buildTerser = s.run("build", `../${appName}`); + buildTerser.waitSecs(60); + await buildTerser.match("[DEBUG] Minifying using Terser", false, true); + + const terserBuildPath = files.pathJoin(s.cwd, `../${appName}`); + selftest.expectEqual(files.exists(terserBuildPath), true); }); - - s.set("NODE_INSPECTOR_IPC", "1"); - - const runTerser = s.run(); - runTerser.waitSecs(waitToStart); - await runTerser.match("App running at"); - await runTerser.stop(); - - const buildTerser = s.run("build", `../${appName}`); - buildTerser.waitSecs(60); - await buildTerser.match("[DEBUG] Minifying using Terser", false, true); - - const terserBuildPath = files.pathJoin(s.cwd, `../${appName}`); - selftest.expectEqual(files.exists(terserBuildPath), true); - - process.env.METEOR_MODERN = currentMeteorModern; }); selftest.define("modern build stack - test swc minifier", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = 'true'; - const s = new Sandbox(); - await s.init(); + await withEnv({ METEOR_MODERN: "true" }, async () => { + const s = new Sandbox(); + await s.init(); - const appName = "modern-swc"; + const appName = "modern-swc"; - await s.createApp(appName, "modern"); - await s.cd(appName); + await s.createApp(appName, "modern"); + await s.cd(appName); - await writeConfig(s, { - modern: true, - mainModule: { - client: 'client/main.js', - server: 'server/main.js', - }, + await writeConfig(s, { + modern: true, + mainModule: { + client: "client/main.js", + server: "server/main.js", + }, + }); + + s.set("NODE_INSPECTOR_IPC", "1"); + + await writeModernConfig(s, { + minifier: true, + }); + + const runSwc = s.run(); + runSwc.waitSecs(waitToStart); + await runSwc.match("App running at"); + await runSwc.stop(); + + const buildSwc = s.run("build", `../${appName}`); + buildSwc.waitSecs(60); + await buildSwc.match("[DEBUG] Minifying using SWC", false, true); + + // Check what's in the build directory + const swcBuildPath = files.pathJoin(s.cwd, `../${appName}`); + selftest.expectEqual(files.exists(swcBuildPath), true); }); - - s.set("NODE_INSPECTOR_IPC", "1"); - - await writeModernConfig(s, { - minifier: true - }); - - const runSwc = s.run(); - runSwc.waitSecs(waitToStart); - await runSwc.match("App running at"); - await runSwc.stop(); - - const buildSwc = s.run("build", `../${appName}`); - buildSwc.waitSecs(60); - await buildSwc.match("[DEBUG] Minifying using SWC", false, true); - - // Check what's in the build directory - const swcBuildPath = files.pathJoin(s.cwd, `../${appName}`); - selftest.expectEqual(files.exists(swcBuildPath), true); - - process.env.METEOR_MODERN = currentMeteorModern; }); selftest.define("modern build stack - enable build", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); + s.set("NODE_INSPECTOR_IPC", "1"); - s.set("METEOR_PROFILE", "0"); - s.set("NODE_INSPECTOR_IPC", "1"); + await writeModernConfig(s, true); - await writeModernConfig(s, true); + const buildSwc = s.run("build", `../modern`); + buildSwc.waitSecs(buildWaitSecs); + await buildSwc.expectExit(0); - const buildSwc = s.run("build", `../modern`); - buildSwc.waitSecs(waitToStart); + const out = buildSwc.getMatcherFullBuffer(); - /* Perserve legacy and modern on build */ - await buildSwc.match(/_findSources for web\.browser/, false, true); - await buildSwc.match(/_findSources for web\.browser\.legacy/, false, true); + /* Perserve legacy and modern on build */ + selftest.expectTrue(/_findSources for web\.browser/.test(out)); + selftest.expectTrue(/_findSources for web\.browser\.legacy/.test(out)); - /* Keep rest of modern build stack */ - await buildSwc.match(/safeWatcher\.watchModern/, false, true); - await buildSwc.match(/SWC\.compile/, false, true); - await buildSwc.match("[DEBUG] Minifying using SWC", false, true); - - process.env.METEOR_MODERN = currentMeteorModern; + /* Keep rest of modern build stack */ + selftest.expectTrue(/safeWatcher\.watchModern/.test(out)); + selftest.expectTrue(/SWC\.compile/.test(out)); + selftest.expectTrue(out.includes("[DEBUG] Minifying using SWC")); + }); }); selftest.define("modern build stack - disable build", async function () { - const currentMeteorModern = process.env.METEOR_MODERN; - process.env.METEOR_MODERN = ''; + await withEnv({ METEOR_MODERN: "" }, async () => { + const s = new Sandbox(); + await s.init(); - const s = new Sandbox(); - await s.init(); + await s.createApp("modern", "modern"); + await s.cd("modern"); - await s.createApp("modern", "modern"); - await s.cd("modern"); + s.set("METEOR_PROFILE", "0"); + s.set("NODE_INSPECTOR_IPC", "1"); - s.set("METEOR_PROFILE", "0"); - s.set("NODE_INSPECTOR_IPC", "1"); + await writeModernConfig(s, { + watcher: false, + transpiler: false, + minifier: false, + webArchOnly: true, // Even when webArchOnly is true, the legacy build should be built + }); - await writeModernConfig(s, { - watcher: false, - transpiler: false, - minifier: false, - webArchOnly: true, // Even when webArchOnly is true, the legacy build should be built + const buildLegacy = s.run("build", `../modern`); + buildLegacy.waitSecs(buildWaitSecs); + await buildLegacy.expectExit(0); + + const out = buildLegacy.getMatcherFullBuffer(); + + /* Perserve legacy and modern on build */ + selftest.expectTrue(/_findSources for web\.browser/.test(out)); + selftest.expectTrue(/_findSources for web\.browser\.legacy/.test(out)); + + /* Keep rest of modern build stack */ + selftest.expectTrue(/safeWatcher\.watchLegacy/.test(out)); + selftest.expectTrue(/Babel\.compile/.test(out)); + selftest.expectTrue(out.includes("[DEBUG] Minifying using Terser")); }); - - const buildLegacy = s.run("build", `../modern`); - buildLegacy.waitSecs(waitToStart); - - /* Perserve legacy and modern on build */ - await buildLegacy.match(/_findSources for web\.browser/, false, true); - await buildLegacy.match(/_findSources for web\.browser\.legacy/, false, true); - - /* Keep rest of modern build stack */ - await buildLegacy.match(/safeWatcher\.watchLegacy/, false, true); - await buildLegacy.match(/Babel\.compile/, false, true); - await buildLegacy.match("[DEBUG] Minifying using Terser", false, true); - - process.env.METEOR_MODERN = currentMeteorModern; });