From e5968490a5a5403f7d60114b2346cdd072d58158 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 7 Jan 2021 14:51:34 +0100 Subject: [PATCH 1/5] Avoid passing --silent when invoking npm through Node.js script instead of CLI. --- bin/tasks/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/tasks/build.js b/bin/tasks/build.js index 995240bb7..6d87e66ef 100644 --- a/bin/tasks/build.js +++ b/bin/tasks/build.js @@ -29,8 +29,8 @@ export const setSpawnParams = (ctx) => { const isJsPath = typeof npmExecPath === 'string' && /\.m?js/.test(path.extname(npmExecPath)); const isYarn = npmExecPath && path.basename(npmExecPath) === 'yarn.js'; ctx.spawnParams = { - command: isJsPath ? process.execPath : npmExecPath || 'npm', - clientArgs: [isJsPath ? npmExecPath : '', isYarn ? '' : 'run', '--silent'].filter(Boolean), + command: (isJsPath ? process.execPath : npmExecPath) || 'npm', + clientArgs: isJsPath ? [npmExecPath, 'run'] : ['run', '--silent'], scriptArgs: [ ctx.options.buildScriptName, isYarn ? '' : '--', From 9ad77e54d4dafb4dd081bfc15cc9ac42b010480c Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 7 Jan 2021 14:55:29 +0100 Subject: [PATCH 2/5] 5.5.1-dev.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b49a262e4..20c248820 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "5.5.0", + "version": "5.5.1-dev.0", "description": "Visual Testing for Storybook", "homepage": "https://www.chromatic.com", "bugs": { From 32cd0a32030cab7f5db912b1439ca9168fba8125 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 7 Jan 2021 16:12:43 +0100 Subject: [PATCH 3/5] Fail build-storybook after 10 minutes. --- bin/lib/getEnv.js | 4 +++- bin/tasks/build.js | 8 +++++++- bin/tasks/build.test.js | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/bin/lib/getEnv.js b/bin/lib/getEnv.js index 8ba38b445..997d1951a 100644 --- a/bin/lib/getEnv.js +++ b/bin/lib/getEnv.js @@ -9,6 +9,7 @@ const { CHROMATIC_TIMEOUT = 5 * 60 * 1000, CHROMATIC_STORYBOOK_VERSION, LOGGLY_CUSTOMER_TOKEN = 'b5e26204-cdc5-4c78-a9cc-c69eb7fabad3', + STORYBOOK_BUILD_TIMEOUT = 10 * 60 * 1000, } = process.env; const ENVIRONMENT_WHITELIST = [/^GERRIT/, /^TRAVIS/]; @@ -33,7 +34,8 @@ export default () => ({ CHROMATIC_POLL_INTERVAL, CHROMATIC_TIMEOUT, CHROMATIC_STORYBOOK_VERSION, + ENVIRONMENT_WHITELIST, LOGGLY_CUSTOMER_TOKEN, + STORYBOOK_BUILD_TIMEOUT, STORYBOOK_CLI_FLAGS_BY_VERSION, - ENVIRONMENT_WHITELIST, }); diff --git a/bin/tasks/build.js b/bin/tasks/build.js index 6d87e66ef..fcda2fd49 100644 --- a/bin/tasks/build.js +++ b/bin/tasks/build.js @@ -40,6 +40,9 @@ export const setSpawnParams = (ctx) => { }; }; +const timeoutAfter = (ms) => + new Promise((resolve, reject) => setTimeout(reject, ms, new Error(`Operation timed out`))); + export const buildStorybook = async (ctx) => { ctx.buildLogFile = path.resolve('./build-storybook.log'); const logFile = fs.createWriteStream(ctx.buildLogFile); @@ -50,7 +53,10 @@ export const buildStorybook = async (ctx) => { try { const { command, clientArgs, scriptArgs } = ctx.spawnParams; - await execa(command, [...clientArgs, ...scriptArgs], { stdio: [null, logFile, logFile] }); + await Promise.race([ + execa(command, [...clientArgs, ...scriptArgs], { stdio: [null, logFile, logFile] }), + timeoutAfter(ctx.env.STORYBOOK_BUILD_TIMEOUT), + ]); } catch (e) { const buildLog = fs.readFileSync(ctx.buildLogFile, 'utf8'); ctx.log.error(buildFailed(ctx, e, buildLog)); diff --git a/bin/tasks/build.test.js b/bin/tasks/build.test.js index 0949807c3..ad98b77ea 100644 --- a/bin/tasks/build.test.js +++ b/bin/tasks/build.test.js @@ -51,6 +51,7 @@ describe('buildStorybook', () => { clientArgs: ['--client-args'], scriptArgs: ['--script-args'], }, + env: { STORYBOOK_BUILD_TIMEOUT: 1000 }, }; await buildStorybook(ctx); expect(ctx.buildLogFile).toMatch(/build-storybook\.log$/); @@ -60,4 +61,20 @@ describe('buildStorybook', () => { expect.objectContaining({ stdio: expect.any(Array) }) ); }); + + it('fails when build times out', async () => { + const ctx = { + spawnParams: { + command: 'build:storybook', + clientArgs: ['--client-args'], + scriptArgs: ['--script-args'], + }, + options: { buildScriptName: '' }, + env: { STORYBOOK_BUILD_TIMEOUT: 0 }, + log: { error: jest.fn() }, + }; + execa.mockReturnValue(new Promise((resolve) => setTimeout(resolve, 10))); + await expect(buildStorybook(ctx)).rejects.toThrow('Command failed'); + expect(ctx.log.error).toHaveBeenCalledWith(expect.stringContaining('Operation timed out')); + }); }); From 53e650016121f2a8438f0fa497d2094bdfe76a93 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 7 Jan 2021 16:13:00 +0100 Subject: [PATCH 4/5] 5.5.1-dev.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20c248820..1c1362411 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "5.5.1-dev.0", + "version": "5.5.1-dev.1", "description": "Visual Testing for Storybook", "homepage": "https://www.chromatic.com", "bugs": { From 7b80bd5a0ce1123634c6c993da4209ce5921a875 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 7 Jan 2021 16:18:51 +0100 Subject: [PATCH 5/5] Ensure we get integers. --- bin/lib/getEnv.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/lib/getEnv.js b/bin/lib/getEnv.js index 997d1951a..3c1fa9a00 100644 --- a/bin/lib/getEnv.js +++ b/bin/lib/getEnv.js @@ -25,17 +25,17 @@ const CHROMATIC_PROJECT_TOKEN = process.env.CHROMA_APP_CODE; // backwards compatibility export default () => ({ - CHROMATIC_SERVER_PORT, + CHROMATIC_SERVER_PORT: parseInt(CHROMATIC_SERVER_PORT, 10), CHROMATIC_INDEX_URL, CHROMATIC_TUNNEL_URL, CHROMATIC_CREATE_TUNNEL, CHROMATIC_PROJECT_TOKEN, - CHROMATIC_RETRIES, - CHROMATIC_POLL_INTERVAL, - CHROMATIC_TIMEOUT, + CHROMATIC_RETRIES: parseInt(CHROMATIC_RETRIES, 10), + CHROMATIC_POLL_INTERVAL: parseInt(CHROMATIC_POLL_INTERVAL, 10), + CHROMATIC_TIMEOUT: parseInt(CHROMATIC_TIMEOUT, 10), CHROMATIC_STORYBOOK_VERSION, ENVIRONMENT_WHITELIST, LOGGLY_CUSTOMER_TOKEN, - STORYBOOK_BUILD_TIMEOUT, + STORYBOOK_BUILD_TIMEOUT: parseInt(STORYBOOK_BUILD_TIMEOUT, 10), STORYBOOK_CLI_FLAGS_BY_VERSION, });