diff --git a/src/commands/deploy.js b/src/commands/deploy.js index 89340943872..48b1da4dff8 100644 --- a/src/commands/deploy.js +++ b/src/commands/deploy.js @@ -1,6 +1,7 @@ const path = require('path') const process = require('process') +const { updateConfig, restoreConfig } = require('@netlify/config') const { flags: flagsLib } = require('@oclif/command') const chalk = require('chalk') const { get } = require('dot-prop') @@ -307,7 +308,7 @@ const runDeploy = async ({ const handleBuild = async ({ context, flags }) => { if (!flags.build) { - return + return {} } const [token] = await getToken() const options = await getBuildOptions({ @@ -315,11 +316,11 @@ const handleBuild = async ({ context, flags }) => { token, flags, }) - const { exitCode, newConfig } = await runBuild(options) + const { exitCode, newConfig, configMutations } = await runBuild(options) if (exitCode !== 0) { context.exit(exitCode) } - return newConfig + return { newConfig, configMutations } } const printResults = ({ flags, results, deployToProduction, exit }) => { @@ -429,7 +430,7 @@ class DeployCommand extends Command { return triggerDeploy({ api, siteId, siteData, error }) } - const newConfig = await handleBuild({ context: this, flags }) + const { newConfig, configMutations = [] } = await handleBuild({ context: this, flags }) const config = newConfig || this.netlify.config const deployFolder = await getDeployFolder({ flags, config, site, siteData }) @@ -450,6 +451,15 @@ class DeployCommand extends Command { error, }) const functionsConfig = normalizeFunctionsConfig({ functionsConfig: config.functions, projectRoot: site.root }) + + const redirectsPath = `${deployFolder}/_redirects` + await updateConfig(configMutations, { + buildDir: deployFolder, + configPath, + redirectsPath, + context: this.netlify.cachedConfig.context, + branch: this.netlify.cachedConfig.branch, + }) const results = await runDeploy({ flags, deployToProduction, @@ -468,6 +478,10 @@ class DeployCommand extends Command { exit, }) + if (configMutations.length !== 0) { + await restoreConfig({ buildDir: deployFolder, configPath, redirectsPath }) + } + printResults({ flags, results, deployToProduction, exit }) if (flags.open) { diff --git a/src/lib/build.js b/src/lib/build.js index 2121d775ab3..32057d41eac 100644 --- a/src/lib/build.js +++ b/src/lib/build.js @@ -25,8 +25,8 @@ const getBuildOptions = ({ }) const runBuild = async (options) => { - const { severityCode: exitCode, netlifyConfig: newConfig } = await build(options) - return { exitCode, newConfig } + const { severityCode: exitCode, netlifyConfig: newConfig, configMutations } = await build(options) + return { exitCode, newConfig, configMutations } } module.exports = { getBuildOptions, runBuild } diff --git a/tests/command.deploy.test.js b/tests/command.deploy.test.js index 4c5cb99a244..c86f44d9222 100644 --- a/tests/command.deploy.test.js +++ b/tests/command.deploy.test.js @@ -1,3 +1,4 @@ +/* eslint-disable require-await */ const process = require('process') const test = require('ava') @@ -399,7 +400,6 @@ if (process.env.NETLIFY_TEST_DISABLE_LIVE !== 'true') { }) test.serial('should deploy functions from internal functions directory', async (t) => { - /* eslint-disable require-await */ await withSiteBuilder('site-with-internal-functions', async (builder) => { await builder .withNetlifyToml({ @@ -451,14 +451,12 @@ if (process.env.NETLIFY_TEST_DISABLE_LIVE !== 'true') { t.is(await got(`${deployUrl}/.netlify/functions/func-1`).text(), 'User 1') t.is(await got(`${deployUrl}/.netlify/functions/func-2`).text(), 'User 2') t.is(await got(`${deployUrl}/.netlify/functions/func-3`).text(), 'Internal 3') - /* eslint-enable require-await */ }) }) test.serial( 'should deploy functions from internal functions directory when setting `base` to a sub-directory', async (t) => { - /* eslint-disable require-await */ await withSiteBuilder('site-with-internal-functions-sub-directory', async (builder) => { await builder .withNetlifyToml({ @@ -487,14 +485,90 @@ if (process.env.NETLIFY_TEST_DISABLE_LIVE !== 'true') { ) t.is(await got(`${deployUrl}/.netlify/functions/func-1`).text(), 'Internal') - /* eslint-enable require-await */ }) }, ) + test.serial('should handle redirects mutated by plugins', async (t) => { + await withSiteBuilder('site-with-public-folder', async (builder) => { + const content = '