Skip to content

Commit 05b2f19

Browse files
committed
Merge remote-tracking branch 'origin/main' into static-fixes
2 parents f2cbb66 + 92c0e50 commit 05b2f19

File tree

8 files changed

+232
-53
lines changed

8 files changed

+232
-53
lines changed

.evergreen.yml

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
exec_timeout_secs: 10800
2+
3+
functions:
4+
checkout:
5+
- command: git.get_project
6+
params:
7+
directory: src
8+
install_node:
9+
- command: shell.exec
10+
params:
11+
working_dir: src
12+
shell: bash
13+
script: |
14+
set -e
15+
set -x
16+
17+
export NODE_VERSION=20.5.0
18+
bash .evergreen/install-node.sh
19+
install:
20+
- command: shell.exec
21+
params:
22+
working_dir: src
23+
shell: bash
24+
script: |
25+
set -e
26+
set -x
27+
28+
. .evergreen/use-node.sh
29+
npm install
30+
check:
31+
- command: shell.exec
32+
params:
33+
working_dir: src
34+
shell: bash
35+
script: |
36+
set -e
37+
set -x
38+
39+
. .evergreen/use-node.sh
40+
npm run build
41+
npm run lint
42+
test:
43+
- command: shell.exec
44+
params:
45+
working_dir: src
46+
shell: bash
47+
env:
48+
TEST_NODE_VERSION: ${node_version}
49+
OKTA_TEST_CONFIG: ${okta_test_config}
50+
OKTA_TEST_CREDENTIALS: ${okta_test_credentials}
51+
AZURE_TEST_CONFIG: ${azure_test_config}
52+
AZURE_TEST_CREDENTIALS: ${azure_test_credentials}
53+
DISTRO_ID: ${distro_id}
54+
script: |
55+
set -e
56+
set -x
57+
58+
rm -rf /tmp/m && mkdir -pv /tmp/m # Node.js compilation can fail on long path prefixes
59+
trap "rm -rf /tmp/m" EXIT
60+
export TMP=/tmp/m
61+
export TMPDIR=/tmp/m
62+
63+
# The CI machines we have for Windows and x64 macOS are not
64+
# able to compile OpenSSL with assembly support,
65+
# so we revert back to the slower version.
66+
if [ "$OS" == "Windows_NT" ]; then
67+
export PATH="/cygdrive/c/python/Python310/Scripts:/cygdrive/c/python/Python310:/cygdrive/c/Python310/Scripts:/cygdrive/c/Python310:$PATH"
68+
export BOXEDNODE_CONFIGURE_ARGS='openssl-no-asm'
69+
elif uname -a | grep -q 'Darwin.*x86_64'; then
70+
export BOXEDNODE_CONFIGURE_ARGS='--openssl-no-asm'
71+
fi
72+
73+
. .evergreen/use-node.sh
74+
npm run build
75+
TEST_NODE_VERSION="$TEST_NODE_VERSION" npm run test-ci
76+
77+
tasks:
78+
- name: test_n14
79+
commands:
80+
- func: checkout
81+
- func: install_node
82+
- func: install
83+
- func: test
84+
vars:
85+
node_version: "14.21.3"
86+
- name: test_n16
87+
commands:
88+
- func: checkout
89+
- func: install_node
90+
- func: install
91+
- func: test
92+
vars:
93+
node_version: "16.20.1"
94+
- name: test_n18
95+
commands:
96+
- func: checkout
97+
- func: install_node
98+
- func: install
99+
- func: test
100+
vars:
101+
node_version: "18.17.0"
102+
- name: test_n20
103+
commands:
104+
- func: checkout
105+
- func: install_node
106+
- func: install
107+
- func: test
108+
vars:
109+
node_version: "20.5.0"
110+
- name: check
111+
commands:
112+
- func: checkout
113+
- func: install_node
114+
- func: install
115+
- func: check
116+
117+
buildvariants:
118+
- name: ubuntu_x64_test
119+
display_name: 'Ubuntu 20.04 x64'
120+
run_on: ubuntu2004-large
121+
tasks:
122+
- test_n14
123+
- test_n16
124+
- test_n18
125+
- test_n20
126+
- check
127+
- name: macos_x64_test
128+
display_name: 'macOS 11.00 x64'
129+
run_on: macos-1100
130+
tasks:
131+
- test_n14
132+
- test_n16
133+
- test_n18
134+
- test_n20
135+
- name: macos_arm64_test
136+
display_name: 'macOS 11.00 arm64'
137+
run_on: macos-1100-arm64
138+
tasks:
139+
- test_n14
140+
- test_n16
141+
- test_n18
142+
- test_n20
143+
- name: windows_x64_test
144+
display_name: 'Windows x64'
145+
run_on: windows-vsCurrent-xlarge
146+
tasks:
147+
- test_n14
148+
- test_n16
149+
- test_n18
150+
- test_n20

.evergreen/install-node.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# adapted from the Node.js driver's script for installing Node.js
3+
set -e
4+
set -x
5+
6+
export BASEDIR="$PWD"
7+
mkdir -p .deps
8+
cd .deps
9+
10+
NVM_URL="https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh"
11+
12+
# this needs to be explicitly exported for the nvm install below
13+
export NVM_DIR="$PWD/nvm"
14+
export XDG_CONFIG_HOME=$PWD
15+
16+
# install Node.js on Windows
17+
if [[ "$OS" == "Windows_NT" ]]; then
18+
curl -o node.zip "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-win-x64.zip"
19+
unzip node.zip
20+
mkdir -p node/bin
21+
mv -v node-v$NODE_VERSION-win-x64/* node/bin
22+
chmod a+x node/bin/*
23+
export PATH="$PWD/node/bin:$PATH"
24+
# install Node.js on Linux/MacOS
25+
else
26+
curl -o- $NVM_URL | bash
27+
set +x
28+
[ -s "${NVM_DIR}/nvm.sh" ] && source "${NVM_DIR}/nvm.sh"
29+
nvm install --no-progress "$NODE_VERSION"
30+
fi
31+
32+
which node && node -v || echo "node not found, PATH=$PATH"
33+
which npm && npm -v || echo "npm not found, PATH=$PATH"

.evergreen/use-node.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
if [[ "$OS" == "Windows_NT" ]]; then
2+
export PATH="$PWD/.deps/node/bin:$PATH"
3+
else
4+
export NVM_DIR="$PWD/.deps/nvm"
5+
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
6+
fi
7+
8+
echo "updated PATH=$PATH"

.github/workflows/nodejs.yml

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
on: [push, pull_request]
1+
on: [pull_request]
22

33
name: CI
44

@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
os: [ubuntu-latest, macos-latest]
15+
os: [ubuntu-latest]
1616
node-version: [14.x, 16.x, 18.x, 19.x]
1717
runs-on: ${{ matrix.os }}
1818
steps:
@@ -29,36 +29,3 @@ jobs:
2929
run: npm install
3030
- name: Test
3131
run: npm test
32-
33-
test-windows:
34-
name: Windows tests
35-
strategy:
36-
fail-fast: false
37-
matrix:
38-
node-version: [14.x, 16.x, 18.x, 19.x]
39-
shard: [1, 2, 3, 4, 5]
40-
runs-on: windows-latest
41-
steps:
42-
- uses: actions/checkout@v2
43-
- name: Install python
44-
uses: actions/setup-python@v2
45-
with:
46-
python-version: '3.10'
47-
- name: Install Node.js build deps
48-
run: choco install nasm
49-
- name: Install developer command prompt
50-
uses: ilammy/msvc-dev-cmd@v1
51-
- name: Use Node.js ${{ matrix.node-version }}
52-
uses: actions/setup-node@v2
53-
with:
54-
check-latest: true
55-
node-version: ${{ matrix.node-version }}
56-
- name: Install npm@8.x
57-
if: ${{ matrix.node-version == '14.x' }}
58-
run: npm install -g npm@8.x
59-
- name: Install Dependencies
60-
run: npm install
61-
- name: Sharded tests
62-
run: npm test -- -g "shard ${{ matrix.shard }}"
63-
- name: Unsharded tests
64-
run: npm test -- -g "shard [1-5]" -i

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@ src/
22
test/
33
.nyc_output/
44
.github/
5+
.evergreen/
6+
.evergreen.yml
57
tsconfig.json
68
.eslintrc

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "boxednode",
3-
"version": "2.0.1",
3+
"version": "2.1.1",
44
"description": "Create a shippable binary from a JS file",
55
"main": "lib/index.js",
66
"exports": {
@@ -15,7 +15,8 @@
1515
},
1616
"scripts": {
1717
"lint": "eslint **/*.ts bin/*.js",
18-
"test": "npm run lint && npm run build && nyc mocha --colors -r ts-node/register test/*.ts",
18+
"test": "npm run lint && npm run build && npm run test-ci",
19+
"test-ci": "nyc mocha --colors -r ts-node/register test/*.ts",
1920
"build": "npm run compile-ts && gen-esm-wrapper . ./.esm-wrapper.mjs",
2021
"prepack": "npm run build",
2122
"compile-ts": "tsc -p tsconfig.json"

src/index.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ async function compileJSFileAsBinaryImpl (options: CompilationOptions, logger: L
288288

289289
const nodeSourcePath = await getNodeSourceForVersion(
290290
options.nodeVersionRange, options.tmpdir, logger);
291+
const nodeVersion = await getNodeVersionFromSourceDirectory(nodeSourcePath);
291292

292293
const requireMappings: [RegExp, string][] = [];
293294
const extraJSSourceFiles: string[] = [];
@@ -329,7 +330,6 @@ async function compileJSFileAsBinaryImpl (options: CompilationOptions, logger: L
329330
}
330331

331332
logger.stepStarting('Inserting custom code into Node.js source');
332-
await fs.mkdir(path.join(nodeSourcePath, 'lib', namespace), { recursive: true });
333333
let entryPointTrampolineSource = await fs.readFile(
334334
path.join(__dirname, '..', 'resources', 'entry-point-trampoline.js'), 'utf8');
335335
entryPointTrampolineSource = entryPointTrampolineSource.replace(
@@ -338,10 +338,30 @@ async function compileJSFileAsBinaryImpl (options: CompilationOptions, logger: L
338338
requireMappings: requireMappings.map(([re, linked]) => [re.source, re.flags, linked]),
339339
enableBindingsPatch
340340
}));
341-
await fs.writeFile(
342-
path.join(nodeSourcePath, 'lib', namespace, `${namespace}.js`),
343-
entryPointTrampolineSource);
344-
extraJSSourceFiles.push(`./lib/${namespace}/${namespace}.js`);
341+
342+
/**
343+
* Since Node 20.x, external source code linked from `lib` directory started
344+
* failing the Node.js build process because of the file being linked multiple
345+
* times which is why we do not link the external files anymore from `lib`
346+
* directory and instead from a different directory, `lib-boxednode`. This
347+
* however does not work for any node version < 20 which is why we are
348+
* conditionally generating the entry point and configure params here based on
349+
* Node version.
350+
*/
351+
const { customCodeSource, customCodeConfigureParam, customCodeEntryPoint } = nodeVersion[0] >= 20
352+
? {
353+
customCodeSource: path.join(nodeSourcePath, 'lib-boxednode', `${namespace}.js`),
354+
customCodeConfigureParam: `./lib-boxednode/${namespace}.js`,
355+
customCodeEntryPoint: `lib-boxednode/${namespace}`
356+
} : {
357+
customCodeSource: path.join(nodeSourcePath, 'lib', namespace, `${namespace}.js`),
358+
customCodeConfigureParam: `./lib/${namespace}/${namespace}.js`,
359+
customCodeEntryPoint: `${namespace}/${namespace}`
360+
};
361+
362+
await fs.mkdir(path.dirname(customCodeSource), { recursive: true });
363+
await fs.writeFile(customCodeSource, entryPointTrampolineSource);
364+
extraJSSourceFiles.push(customCodeConfigureParam);
345365
logger.stepCompleted();
346366

347367
logger.stepStarting('Storing executable metadata');
@@ -372,7 +392,7 @@ async function compileJSFileAsBinaryImpl (options: CompilationOptions, logger: L
372392
let mainSource = await fs.readFile(
373393
path.join(__dirname, '..', 'resources', 'main-template.cc'), 'utf8');
374394
mainSource = mainSource.replace(/\bREPLACE_WITH_ENTRY_POINT\b/g,
375-
JSON.stringify(`${namespace}/${namespace}`));
395+
JSON.stringify(customCodeEntryPoint));
376396
mainSource = mainSource.replace(/\bREPLACE_DECLARE_LINKED_MODULES\b/g,
377397
registerFunctions.map((fn) => `void ${fn}(const void**,const void**);\n`).join(''));
378398
mainSource = mainSource.replace(/\bREPLACE_DEFINE_LINKED_MODULES\b/g,

test/index.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@ import { promises as fs } from 'fs';
1111
const execFile = promisify(childProcess.execFile);
1212
const exeSuffix = process.platform === 'win32' ? '.exe' : '';
1313

14-
// We shard the tests on Windows because compiling isn't cached there.
15-
1614
describe('basic functionality', () => {
1715
// Test the currently running Node.js version. Other versions can be checked
1816
// manually that way, or through the CI matrix.
19-
const version = process.version.slice(1).replace(/-.*$/, '');
17+
const version = process.env.TEST_NODE_VERSION || process.version.slice(1).replace(/-.*$/, '');
2018

2119
describe(`On Node v${version}`, function () {
22-
it('works in a simple case (shard 1)', async function () {
20+
it('works in a simple case', async function () {
2321
this.timeout(2 * 60 * 60 * 1000); // 2 hours
2422
await compileJSFileAsBinary({
2523
nodeVersionRange: version,
@@ -100,7 +98,7 @@ describe('basic functionality', () => {
10098
}
10199
});
102100

103-
it('works with a Nan addon (shard 2)', async function () {
101+
it('works with a Nan addon', async function () {
104102
if (semver.lt(version, '12.19.0')) {
105103
return this.skip(); // no addon support available
106104
}
@@ -127,7 +125,7 @@ describe('basic functionality', () => {
127125
}
128126
});
129127

130-
it('works with a N-API addon (shard 3)', async function () {
128+
it('works with a N-API addon', async function () {
131129
if (semver.lt(version, '14.13.0')) {
132130
return this.skip(); // no N-API addon support available
133131
}
@@ -154,7 +152,7 @@ describe('basic functionality', () => {
154152
}
155153
});
156154

157-
it('passes through env vars and runs the pre-compile hook (shard 3)', async function () {
155+
it('passes through env vars and runs the pre-compile hook', async function () {
158156
this.timeout(2 * 60 * 60 * 1000); // 2 hours
159157
let ranPreCompileHook = false;
160158
async function preCompileHook (nodeSourceTree: string) {
@@ -177,7 +175,7 @@ describe('basic functionality', () => {
177175
throw new Error('unreachable');
178176
});
179177

180-
it('works with code caching support (shard 4)', async function () {
178+
it('works with code caching support', async function () {
181179
this.timeout(2 * 60 * 60 * 1000); // 2 hours
182180
await compileJSFileAsBinary({
183181
nodeVersionRange: version,
@@ -203,10 +201,10 @@ describe('basic functionality', () => {
203201
}
204202
});
205203

206-
it('works with snapshot support (shard 5)', async function () {
204+
it('works with snapshot support', async function () {
207205
this.timeout(2 * 60 * 60 * 1000); // 2 hours
208206
await compileJSFileAsBinary({
209-
nodeVersionRange: 'v20.0.0-nightly202302078e6e215481', // TODO: Update to real version
207+
nodeVersionRange: 'v21.0.0-nightly20230801d396a041f7',
210208
sourceFile: path.resolve(__dirname, 'resources/snapshot-echo-args.js'),
211209
targetFile: path.resolve(__dirname, `resources/snapshot-echo-args${exeSuffix}`),
212210
useNodeSnapshot: true,

0 commit comments

Comments
 (0)