Skip to content

Commit

Permalink
feat: support configure egg.revert in package.json (#58)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: drop Node.js 14 support
  • Loading branch information
killagu authored Feb 19, 2024
1 parent 880ad19 commit a294691
Show file tree
Hide file tree
Showing 15 changed files with 419 additions and 318 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
Job:
name: Node.js
uses: artusjs/github-actions/.github/workflows/node-test.yml@v1
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
with:
os: 'ubuntu-latest, macos-latest, windows-latest'
version: '14, 16, 18'
version: '16, 18, 20'
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
release:
name: Node.js
uses: artusjs/github-actions/.github/workflows/node-release.yml@v1
uses: eggjs/github-actions/.github/workflows/node-release.yml@master
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ run/
test/fixtures/ts/app/controller/home.js
test/fixtures/ts-pkg/app/controller/home.js
!test/fixtures/**/node_modules
package-lock.json
60 changes: 42 additions & 18 deletions lib/cmd/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class StartCommand extends Command {
return 'Start server at prod mode';
}

* run(context) {
async run(context) {
context.execArgvObj = context.execArgvObj || {};
const { argv, env, cwd, execArgvObj } = context;
const HOME = homedir();
Expand All @@ -91,12 +91,12 @@ class StartCommand extends Command {

const isDaemon = argv.daemon;

argv.framework = yield this.getFrameworkPath({
argv.framework = await this.getFrameworkPath({
framework: argv.framework,
baseDir,
});

this.frameworkName = yield this.getFrameworkName(argv.framework);
this.frameworkName = await this.getFrameworkName(argv.framework);

const pkgInfo = require(path.join(baseDir, 'package.json'));
argv.title = argv.title || `egg-server-${pkgInfo.name}`;
Expand All @@ -121,7 +121,7 @@ class StartCommand extends Command {
// for alinode
env.ENABLE_NODE_LOG = 'YES';
env.NODE_LOG_DIR = env.NODE_LOG_DIR || path.join(logDir, 'alinode');
yield mkdirp(env.NODE_LOG_DIR);
await mkdirp(env.NODE_LOG_DIR);

// cli argv -> process.env.EGG_SERVER_ENV -> `undefined` then egg will use `prod`
if (argv.env) {
Expand All @@ -132,6 +132,14 @@ class StartCommand extends Command {
// additional execArgv
execArgvObj.deprecation = false; // --no-deprecation
execArgvObj.traceWarnings = true; // --trace-warnings
const eggInfo = pkgInfo.egg || {};
if (eggInfo.revert) {
context.execArgvObj['security-revert'] = context.execArgvObj['security-revert'] || [];
const reverts = Array.isArray(eggInfo.revert) ? eggInfo.revert : [ eggInfo.revert ];
for (const revert of reverts) {
context.execArgvObj['security-revert'].push(revert);
}
}

const command = argv.node || 'node';

Expand All @@ -154,7 +162,10 @@ class StartCommand extends Command {
// whether run in the background.
if (isDaemon) {
this.logger.info(`Save log file to ${logDir}`);
const [ stdout, stderr ] = yield [ getRotatelog(argv.stdout), getRotatelog(argv.stderr) ];
const [ stdout, stderr ] = await Promise.all([
getRotatelog(argv.stdout),
getRotatelog(argv.stderr),
]);
options.stdio = [ 'ignore', stdout, stderr, 'ipc' ];
options.detached = true;

Expand All @@ -173,7 +184,7 @@ class StartCommand extends Command {
});

// check start status
yield this.checkStatus(argv);
await this.checkStatus(argv);
} else {
options.stdio = [ 'inherit', 'inherit', 'inherit', 'ipc' ];
debug('Run spawn `%s %s`', command, eggArgs.join(' '));
Expand All @@ -194,11 +205,24 @@ class StartCommand extends Command {
}
}

* getFrameworkPath(params) {
async getFrameworkPath(params) {
return utils.getFrameworkPath(params);
}

* getFrameworkName(framework) {
async getFrameworkName(framework) {
const pkgPath = path.join(framework, 'package.json');
let name = 'egg';
try {
const pkg = require(pkgPath);
/* istanbul ignore else */
if (pkg.name) name = pkg.name;
} catch (_) {
/* istanbul next */
}
return name;
}

async getRevert(framework) {
const pkgPath = path.join(framework, 'package.json');
let name = 'egg';
try {
Expand All @@ -211,14 +235,14 @@ class StartCommand extends Command {
return name;
}

* checkStatus({ stderr, timeout, 'ignore-stderr': ignoreStdErr }) {
async checkStatus({ stderr, timeout, 'ignore-stderr': ignoreStdErr }) {
let count = 0;
let hasError = false;
let isSuccess = true;
timeout = timeout / 1000;
while (!this.isReady) {
try {
const stat = yield fs.stat(stderr);
const stat = await fs.stat(stderr);
if (stat && stat.size > 0) {
hasError = true;
break;
Expand All @@ -233,15 +257,15 @@ class StartCommand extends Command {
break;
}

yield sleep(1000);
await sleep(1000);
this.logger.log('Wait Start: %d...', ++count);
}

if (hasError) {
try {
const args = [ '-n', '100', stderr ];
this.logger.error('tail %s', args.join(' '));
const [ stdout ] = yield execFile('tail', args);
const [ stdout ] = await execFile('tail', args);
this.logger.error('Got error when startup: ');
this.logger.error(stdout);
} catch (err) {
Expand All @@ -254,23 +278,23 @@ class StartCommand extends Command {

if (!isSuccess) {
this.child.kill('SIGTERM');
yield sleep(1000);
await sleep(1000);
this.exit(1);
}
}
}

function* getRotatelog(logfile) {
yield mkdirp(path.dirname(logfile));
async function getRotatelog(logfile) {
await mkdirp(path.dirname(logfile));

if (yield fs.exists(logfile)) {
if (await fs.exists(logfile)) {
// format style: .20150602.193100
const timestamp = moment().format('.YYYYMMDD.HHmmss');
// Note: rename last log to next start time, not when last log file created
yield fs.rename(logfile, logfile + timestamp);
await fs.rename(logfile, logfile + timestamp);
}

return yield fs.open(logfile, 'a');
return await fs.open(logfile, 'a');
}

function stringify(obj, ignore) {
Expand Down
8 changes: 4 additions & 4 deletions lib/cmd/stop.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ class StopCommand extends Command {
return 'Stop server';
}

* run(context) {
async run(context) {
const { argv } = context;

this.logger.info(`stopping egg application ${argv.title ? `with --title=${argv.title}` : ''}`);

// node /Users/tz/Workspaces/eggjs/egg-scripts/lib/start-cluster {"title":"egg-server","workers":4,"port":7001,"baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg"}
let processList = yield this.helper.findNodeProcess(item => {
let processList = await this.helper.findNodeProcess(item => {
const cmd = item.cmd;
return argv.title ?
cmd.includes('start-cluster') && cmd.includes(util.format(osRelated.titleTemplate, argv.title)) :
Expand All @@ -47,15 +47,15 @@ class StopCommand extends Command {
this.logger.info('got master pid %j', pids);
this.helper.kill(pids);
// wait for 5s to confirm whether any worker process did not kill by master
yield sleep(argv.timeout || '5s');
await sleep(argv.timeout || '5s');
} else {
this.logger.warn('can\'t detect any running egg process');
}


// node --debug-port=5856 /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/agent_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406}
// node /Users/tz/Workspaces/eggjs/test/showcase/node_modules/_egg-cluster@1.8.0@egg-cluster/lib/app_worker.js {"framework":"/Users/tz/Workspaces/eggjs/test/showcase/node_modules/egg","baseDir":"/Users/tz/Workspaces/eggjs/test/showcase","port":7001,"workers":2,"plugins":null,"https":false,"key":"","cert":"","title":"egg-server","clusterPort":52406}
processList = yield this.helper.findNodeProcess(item => {
processList = await this.helper.findNodeProcess(item => {
const cmd = item.cmd;
return argv.title ?
(cmd.includes(osRelated.appWorkerPath) || cmd.includes(osRelated.agentWorkerPath)) && cmd.includes(util.format(osRelated.titleTemplate, argv.title)) :
Expand Down
4 changes: 2 additions & 2 deletions lib/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ const runScript = require('runscript');
const isWin = process.platform === 'win32';
const REGEX = isWin ? /^(.*)\s+(\d+)\s*$/ : /^\s*(\d+)\s+(.*)/;

exports.findNodeProcess = function* (filterFn) {
exports.findNodeProcess = async function(filterFn) {
const command = isWin ?
'wmic Path win32_process Where "Name = \'node.exe\'" Get CommandLine,ProcessId' :
// command, cmd are alias of args, not POSIX standard, so we use args
'ps -wweo "pid,args"';
const stdio = yield runScript(command, { stdio: 'pipe' });
const stdio = await runScript(command, { stdio: 'pipe' });
const processList = stdio.stdout.toString().split('\n')
.reduce((arr, line) => {
if (!!line && !line.includes('/bin/sh') && line.includes('node')) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"await-event": "^2.1.0",
"common-bin": "^2.8.0",
"common-bin": "^3.0.1",
"debug": "^4.1.0",
"egg-utils": "^2.4.1",
"moment": "^2.23.0",
Expand All @@ -36,7 +36,7 @@
"node": ">=6.0.0"
},
"ci": {
"version": "14, 16, 18"
"version": "16, 18, 20"
},
"scripts": {
"contributor": "git-contributor",
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/egg-revert/config/config.default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

exports.keys = '123456';

exports.logger = {
level: 'WARN',
consoleLevel: 'WARN',
};
21 changes: 21 additions & 0 deletions test/fixtures/egg-revert/node_modules/custom-framework/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/fixtures/egg-revert/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "example",
"version": "1.0.0",
"dependencies": {
"egg": "^1.0.0"
},
"egg": {
"framework": "custom-framework",
"revert": "CVE-2023-46809"
}
}
Loading

0 comments on commit a294691

Please sign in to comment.