From d777e3f6393bcaede36faf135b820b9c49d35ce1 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Tue, 31 Mar 2020 15:11:44 +0200 Subject: [PATCH] Upgrade to latest Netlify build API (#18) --- package-lock.json | 92 +++++++---------------------------------------- package.json | 8 ++++- src/index.js | 75 ++++++++++++++++---------------------- 3 files changed, 51 insertions(+), 124 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3b897838..aa55156e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1845,79 +1845,6 @@ "integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=", "dev": true }, - "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "executable": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", @@ -2390,7 +2317,8 @@ "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true }, "ignore": { "version": "5.1.4", @@ -2590,7 +2518,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isobject": { "version": "4.0.0", @@ -3186,7 +3115,8 @@ "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "merge2": { "version": "1.3.0", @@ -3227,7 +3157,8 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true }, "mimic-response": { "version": "1.0.1", @@ -6955,6 +6886,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -7812,7 +7744,8 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true }, "signale": { "version": "1.4.0", @@ -7993,7 +7926,8 @@ "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true }, "strip-indent": { "version": "2.0.0", diff --git a/package.json b/package.json index 765745c5..73004bc9 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,10 @@ "semantic-release": "semantic-release", "start": "serve public" }, + "keywords": [ + "netlify", + "netlify-plugin" + ], "author": "Gleb Bahmutov ", "files": [ "manifest.yml", @@ -20,7 +24,6 @@ "check-more-types": "2.24.0", "debug": "4.1.1", "ecstatic": "4.1.2", - "execa": "3.4.0", "got": "9.6.0", "lazy-ass": "1.6.0" }, @@ -28,6 +31,9 @@ "type": "git", "url": "https://github.com/cypress-io/netlify-plugin-cypress.git" }, + "bugs": { + "url": "https://github.com/cypress-io/netlify-plugin-cypress/issues" + }, "publishConfig": { "access": "public" }, diff --git a/src/index.js b/src/index.js index bc6b6af4..9f591dfe 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,6 @@ // @ts-check const ecstatic = require('ecstatic') const http = require('http') -const execa = require('execa') const debug = require('debug')('netlify-plugin-cypress') const debugVerbose = require('debug')('netlify-plugin-cypress:verbose') const la = require('lazy-ass') @@ -15,15 +14,14 @@ function serveFolder (folder, port) { return http.createServer(server).listen(port) } -function startServerMaybe (options = {}) { +function startServerMaybe (run, options = {}) { const startCommand = options.start if (!startCommand) { debug('No start command found') return } - const serverProcess = execa(startCommand, { - stdio: 'inherit', + const serverProcess = run(startCommand, { detached: true, shell: true }) @@ -35,7 +33,7 @@ function startServerMaybe (options = {}) { } } -async function waitOnMaybe (options = {}) { +async function waitOnMaybe (failPlugin, options = {}) { const waitOnUrl = options['wait-on'] if (!waitOnUrl) { debug('no wait-on defined') @@ -58,7 +56,7 @@ async function waitOnMaybe (options = {}) { } catch (err) { debug('pinging %s for %d ms failed', waitOnUrl, waitTimeoutMs) debug(err) - throw new Error(err.message) + failPlugin(`Pinging ${waitOnUrl} for ${waitTimeoutMs} failed`, { error: err }) } } @@ -91,22 +89,19 @@ async function runCypressTests (baseUrl, record, spec, group, tag) { }) } -async function onInit() { +async function onInit(arg) { debug('installing Cypress binary just in case') - if (debug.enabled) { - await execa('npx', ['cypress', 'install'], {stdio: 'inherit'}) - } else { - await execa('npx', ['cypress', 'install']) - } + const runOptions = debug.enabled ? {} : {stdio: 'ignore'} + await arg.utils.run('cypress', ['install'], runOptions) } -const processCypressResults = (results, failBuild) => { +const processCypressResults = (results, failPlugin) => { if (results.failures) { // Cypress failed without even running the tests console.error('Problem running Cypress') console.error(results.message) - return failBuild('Problem running Cypress', { + return failPlugin('Problem running Cypress', { error: new Error(results.message) }) } @@ -120,13 +115,13 @@ const processCypressResults = (results, failBuild) => { // results.totalFailed gives total number of failed tests if (results.totalFailed) { - return failBuild('Failed Cypress tests', { + return failPlugin('Failed Cypress tests', { error: new Error(`${results.totalFailed} test(s) failed`) }) } } -async function postBuild({ fullPublishFolder, record, spec, group, tag, failBuild }) { +async function postBuild({ fullPublishFolder, record, spec, group, tag, failPlugin }) { const port = 8080 const server = serveFolder(fullPublishFolder, port) debug('local server listening on port %d', port) @@ -145,21 +140,14 @@ async function postBuild({ fullPublishFolder, record, spec, group, tag, failBuil }) }) - processCypressResults(results, failBuild) + processCypressResults(results, failPlugin) } const hasRecordKey = () => typeof process.env.CYPRESS_RECORD_KEY === 'string' -module.exports = function cypressPlugin (pluginConfig) { - debugVerbose('cypressPlugin config %o', pluginConfig) - - // here we can grab all input settings to isolate Cypress logic - // from reading the inputs - - return { - name: 'cypress netlify plugin', +module.exports = { onInit, - preBuild: async (arg) => { + onPreBuild: async (arg) => { debug('cypress plugin preBuild inputs %o', arg.inputs) const preBuildInputs = arg.inputs && arg.inputs.preBuild if (!preBuildInputs) { @@ -167,8 +155,11 @@ module.exports = function cypressPlugin (pluginConfig) { return } - const closeServer = startServerMaybe(preBuildInputs) - await waitOnMaybe(preBuildInputs) + const failPlugin = arg.utils && arg.utils.build && arg.utils.build.failPlugin + la(is.fn(failPlugin), 'expected failPlugin function inside', arg.utils) + + const closeServer = startServerMaybe(args.utils.run, preBuildInputs) + await waitOnMaybe(failPlugin, preBuildInputs) const baseUrl = preBuildInputs['wait-on'] const record = Boolean(preBuildInputs.record) @@ -192,47 +183,43 @@ module.exports = function cypressPlugin (pluginConfig) { closeServer() } - const failBuild = arg.utils && arg.utils.build && arg.utils.build.failBuild - la(is.fn(failBuild), 'expected failBuild function inside', arg.utils) - - processCypressResults(results, failBuild) + processCypressResults(results, failPlugin) }, - postBuild: async (arg) => { + onPostBuild: async (arg) => { debugVerbose('postBuild arg %o', arg) debug('cypress plugin postBuild inputs %o', arg.inputs) - const fullPublishFolder = arg.netlifyConfig.build.publish + const fullPublishFolder = arg.constants.PUBLISH_DIR debug('folder to publish is "%s"', fullPublishFolder) // only if the user wants to record the tests and has set the record key // then we should attempt recording - const record = hasRecordKey() && Boolean(pluginConfig.record) + const record = hasRecordKey() && Boolean(arg.inputs.record) - const spec = pluginConfig.spec + const spec = arg.inputs.spec let group let tag if (record) { - group = pluginConfig.group || 'postBuild' + group = arg.inputs.group || 'postBuild' - if (pluginConfig.tag) { - tag = pluginConfig.tag + if (arg.inputs.tag) { + tag = arg.inputs.tag } else { tag = process.env.CONTEXT } } - const failBuild = arg.utils && arg.utils.build && arg.utils.build.failBuild - la(is.fn(failBuild), 'expected failBuild function inside', arg.utils) + const failPlugin = arg.utils && arg.utils.build && arg.utils.build.failPlugin + la(is.fn(failPlugin), 'expected failPlugin function inside', arg.utils) - return postBuild({ + await postBuild({ fullPublishFolder, record, spec, group, tag, - failBuild + failPlugin }) } - } }