Add CI pipeline for Node (#6022)

* chore: linting

* ci: add ci pipeline for Node.js

* ci: add support for Node@25

* Update .github/workflows/ci-node.yml

Co-authored-by: Jon Church <me@jonchurch.com>

---------

Co-authored-by: Jon Church <me@jonchurch.com>
This commit is contained in:
Ulises Gascón
2025-10-27 11:31:52 +01:00
committed by GitHub
parent 20c530121e
commit 4afb725803
4 changed files with 75 additions and 14 deletions

61
.github/workflows/ci-node.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: CI Node.js
on:
push:
branches: [ main ]
pull_request:
jobs:
test:
name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25'
]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
# This is due to bugs in npm 3s handling of newer package formats.
- name: Use npm@3.10.10 for Node@5
if: matrix.node-version == '5'
run: npm install -g npm@3.10.10
- name: Install dependencies
run: npm install
- name: Run Validate
run: npm run validate

2
dist/lodash.js vendored
View File

@@ -3766,7 +3766,7 @@
if (isArray(iteratee)) { if (isArray(iteratee)) {
return function(value) { return function(value) {
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
} };
} }
return iteratee; return iteratee;
}); });

View File

@@ -3766,7 +3766,7 @@
if (isArray(iteratee)) { if (isArray(iteratee)) {
return function(value) { return function(value) {
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
} };
} }
return iteratee; return iteratee;
}); });

View File

@@ -22299,7 +22299,7 @@
QUnit.test('should forbid code injection through the "variable" options', function(assert) { QUnit.test('should forbid code injection through the "variable" options', function(assert) {
assert.expect(1); assert.expect(1);
assert.raises(function () { assert.raises(function() {
_.template('', { 'variable': '){console.log(process.env)}; with(obj' }); _.template('', { 'variable': '){console.log(process.env)}; with(obj' });
}); });
}); });
@@ -22655,7 +22655,7 @@
var actual, var actual,
expected = 'no error'; expected = 'no error';
try { try {
actual = _.template(expected, {'sourceURL': '\u2028\u2029\n!this would err if it was executed!'})(); actual = _.template(expected, {'sourceURL': '\u2028\u2029\n!this would err if it was executed!'})();
} catch (e) {} } catch (e) {}
assert.equal(actual, expected); assert.equal(actual, expected);
@@ -25840,35 +25840,35 @@
}); });
// zipObjectDeep prototype pollution // zipObjectDeep prototype pollution
['__proto__', 'constructor', 'prototype'].forEach(function (keyToTest) { ['__proto__', 'constructor', 'prototype'].forEach(function(keyToTest) {
QUnit.test('zipObjectDeep is not setting ' + keyToTest + ' on global', function (assert) { QUnit.test('zipObjectDeep is not setting ' + keyToTest + ' on global', function(assert) {
assert.expect(1); assert.expect(1);
_.zipObjectDeep([keyToTest + '.a'], ['newValue']); _.zipObjectDeep([keyToTest + '.a'], ['newValue']);
// Can't access plain `a` as it's not defined and test fails // Can't access plain `a` as it's not defined and test fails
assert.notEqual(root['a'], 'newValue'); assert.notEqual(root.a, 'newValue');
}); });
QUnit.test('zipObjectDeep is not overwriting ' + keyToTest + ' on vars', function (assert) { QUnit.test('zipObjectDeep is not overwriting ' + keyToTest + ' on vars', function(assert) {
assert.expect(3); assert.expect(3);
const b = 'oldValue' const b = 'oldValue';
_.zipObjectDeep([keyToTest + '.b'], ['newValue']); _.zipObjectDeep([keyToTest + '.b'], ['newValue']);
assert.equal(b, 'oldValue'); assert.equal(b, 'oldValue');
assert.notEqual(root['b'], 'newValue'); assert.notEqual(root.b, 'newValue');
// ensure nothing was created // ensure nothing was created
assert.notOk(root['b']); assert.notOk(root.b);
}); });
QUnit.test('zipObjectDeep is not overwriting global.' + keyToTest, function (assert) { QUnit.test('zipObjectDeep is not overwriting global.' + keyToTest, function(assert) {
assert.expect(2); assert.expect(2);
_.zipObjectDeep([root + '.' + keyToTest + '.c'], ['newValue']); _.zipObjectDeep([root + '.' + keyToTest + '.c'], ['newValue']);
assert.notEqual(root['c'], 'newValue'); assert.notEqual(root.c, 'newValue');
// ensure nothing was created // ensure nothing was created
assert.notOk(root['c']); assert.notOk(root.c);
}); });
}); });