From 3f2461da820066604fa788083f60c43191a80a34 Mon Sep 17 00:00:00 2001 From: rafaelscosta Date: Mon, 18 May 2026 08:17:20 -0300 Subject: [PATCH] fix(ci): use require.resolve() instead of require() in smoke_test_exports [#755] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #755: Node 24 was surfacing ERR_USE_AFTER_CLOSE on readline close in non-TTY GitHub runners. The CLI loads fine — banner ("Installer v5.2.7") prints before the close fires — but the after-close error kills the exit code, making the job report a false positive. The intent of smoke_test_exports is to validate that `bin/aiox.js` is reachable through the package-exports gate, not to execute the wizard. require.resolve() triggers the same gate (ERR_PACKAGE_PATH_NOT_EXPORTED on exports drift) without loading the module, so the readline lifecycle never runs. Closes #755 Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/npm-publish.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index b09cc32464..0f16de59b7 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -511,7 +511,7 @@ jobs: echo "❌ ${CORE_SPEC} not visible after 90s — cannot run exports smoke" exit 1 - - name: Force require() resolution to trigger exports gate + - name: Force require.resolve() to trigger exports gate env: CORE_SPEC: '@aiox-squads/core@${{ needs.build.outputs.version }}' run: | @@ -520,13 +520,16 @@ jobs: cd "${SMOKE_DIR}" npm init -y >/dev/null 2>&1 npm install "${CORE_SPEC}" 2>&1 | tail -3 - # External require() forces Node's package-exports gate. If bin/* - # is not declared in exports, this fails with ERR_PACKAGE_PATH_NOT_EXPORTED. + # External require.resolve() forces Node's package-exports gate. If + # bin/* is not declared in exports, this fails with ERR_PACKAGE_PATH_NOT_EXPORTED. + # Uses resolve() instead of require() to avoid loading the CLI's wizard + # in non-TTY runners (Node 24 surfaced ERR_USE_AFTER_CLOSE on readline + # close in non-interactive contexts — false positive, not exports drift). # set -o pipefail above ensures node's exit status survives the head pipe. - if node -e "require('@aiox-squads/core/bin/aiox.js')" 2>&1 | head -20; then - echo "✅ require('@aiox-squads/core/bin/aiox.js') succeeds on Node ${{ matrix.node }}" + if node -e "require.resolve('@aiox-squads/core/bin/aiox.js')" 2>&1 | head -20; then + echo "✅ require.resolve('@aiox-squads/core/bin/aiox.js') succeeds on Node ${{ matrix.node }}" else - echo "❌ REGRESSION: require() blocked by exports field on Node ${{ matrix.node }}" + echo "❌ REGRESSION: require.resolve() blocked by exports field on Node ${{ matrix.node }}" echo "❌ Issue #734 has returned — check exports field in package.json" exit 1 fi