Skip to content

Commit 5f44426

Browse files
committed
feat!: run build before deploy
This small change updates the `deploy` command to run the configured `build` command before deployment. Users who prefer the previous behavior can opt out by specifying `--build=false` when running `netlify deploy`.
1 parent 9dc32fe commit 5f44426

File tree

2 files changed

+96
-53
lines changed

2 files changed

+96
-53
lines changed

src/commands/deploy/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Support for package.json's main field, and intrinsic index.js entrypoints are co
109109
'build',
110110
),
111111
)
112-
.option('--build', 'Run build command before deploying', false)
112+
.option('--build', 'Run build command before deploying', true)
113113
.option('--context <context>', 'Context to use when resolving build configuration')
114114
.option(
115115
'--skip-functions-cache',

tests/integration/commands/deploy/deploy.test.ts

+95-52
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
107107

108108
await builder.build()
109109

110-
const deploy = await callCli(['deploy', '--json', '--dir', 'public'], {
110+
const deploy = await callCli(['deploy', '--json', '--build', 'false', '--dir', 'public'], {
111111
cwd: builder.directory,
112112
env: { NETLIFY_SITE_ID: context.siteId },
113113
}).then((output) => JSON.parse(output))
@@ -132,7 +132,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
132132

133133
await builder.build()
134134

135-
const deploy = await callCli(['deploy', '--json', '--site', SITE_NAME], {
135+
const deploy = await callCli(['deploy', '--json', '--build', 'false', '--site', SITE_NAME], {
136136
cwd: builder.directory,
137137
}).then((output) => JSON.parse(output))
138138

@@ -156,7 +156,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
156156

157157
await builder.build()
158158

159-
const deploy = await callCli(['deploy', '--json'], {
159+
const deploy = await callCli(['deploy', '--json', '--build', 'false'], {
160160
cwd: builder.directory,
161161
env: { NETLIFY_SITE_ID: context.siteId },
162162
}).then((output) => JSON.parse(output))
@@ -192,7 +192,9 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
192192
}
193193

194194
await callCli(['build'], options)
195-
const deploy = await callCli(['deploy', '--json'], options).then((output) => JSON.parse(output))
195+
const deploy = await callCli(['deploy', '--json', '--build', 'false'], options).then((output) =>
196+
JSON.parse(output),
197+
)
196198

197199
// give edge functions manifest a couple ticks to propagate
198200
await pause(500)
@@ -236,8 +238,8 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
236238
}
237239

238240
await callCli(['build', '--cwd', pathPrefix], options)
239-
const deploy = await callCli(['deploy', '--json', '--cwd', pathPrefix], options).then((output) =>
240-
JSON.parse(output),
241+
const deploy = await callCli(['deploy', '--json', '--build', 'false', '--cwd', pathPrefix], options).then(
242+
(output) => JSON.parse(output),
241243
)
242244

243245
// give edge functions manifest a couple ticks to propagate
@@ -252,7 +254,73 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
252254
})
253255
})
254256

255-
test('should run build command before deploy when build flag is passed', async (t) => {
257+
test('runs build command before deploy by default', async (t) => {
258+
await withSiteBuilder(t, async (builder) => {
259+
const content = '<h1>⊂◉‿◉つ</h1>'
260+
builder
261+
.withContentFile({
262+
path: 'public/index.html',
263+
content,
264+
})
265+
.withNetlifyToml({
266+
config: {
267+
build: { publish: 'public' },
268+
plugins: [{ package: './plugins/log-env' }],
269+
},
270+
})
271+
.withBuildPlugin({
272+
name: 'log-env',
273+
plugin: {
274+
async onSuccess() {
275+
const { DEPLOY_ID, DEPLOY_URL } = require('process').env
276+
console.log(`DEPLOY_ID: ${DEPLOY_ID}`)
277+
console.log(`DEPLOY_URL: ${DEPLOY_URL}`)
278+
},
279+
},
280+
})
281+
282+
await builder.build()
283+
284+
const output = await callCli(['deploy'], {
285+
cwd: builder.directory,
286+
env: { NETLIFY_SITE_ID: context.siteId },
287+
})
288+
289+
t.expect(output).toContain('Netlify Build completed in')
290+
const [, deployId] = output.match(/DEPLOY_ID: (\w+)/) ?? []
291+
const [, deployURL] = output.match(/DEPLOY_URL: (.+)/) ?? []
292+
293+
t.expect(deployId).not.toEqual('0')
294+
t.expect(deployURL).toContain(`https://${deployId}--`)
295+
})
296+
})
297+
298+
test('should return valid json when --json is passed', async (t) => {
299+
await withSiteBuilder(t, async (builder) => {
300+
const content = '<h1>⊂◉‿◉つ</h1>'
301+
builder
302+
.withContentFile({
303+
path: 'public/index.html',
304+
content,
305+
})
306+
.withNetlifyToml({
307+
config: {
308+
build: { publish: 'public' },
309+
},
310+
})
311+
312+
await builder.build()
313+
314+
const output = await callCli(['deploy', '--json'], {
315+
cwd: builder.directory,
316+
env: { NETLIFY_SITE_ID: context.siteId },
317+
})
318+
319+
expect(() => JSON.parse(output)).not.toThrowError()
320+
})
321+
})
322+
323+
test('does not run build command before deploy when --build=false flag is passed', async (t) => {
256324
await withSiteBuilder(t, async (builder) => {
257325
const content = '<h1>⊂◉‿◉つ</h1>'
258326
builder
@@ -279,12 +347,12 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
279347

280348
await builder.build()
281349

282-
const output = await callCli(['deploy', '--build'], {
350+
const output = await callCli(['deploy', '--build', 'false'], {
283351
cwd: builder.directory,
284352
env: { NETLIFY_SITE_ID: context.siteId },
285353
})
286354

287-
t.expect(output.includes('Netlify Build completed in')).toBe(true)
355+
t.expect(output).not.toContain('Netlify Build completed in')
288356
const [, deployId] = output.match(/DEPLOY_ID: (\w+)/) ?? []
289357
const [, deployURL] = output.match(/DEPLOY_URL: (.+)/) ?? []
290358

@@ -302,7 +370,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
302370
})
303371
await builder.build()
304372

305-
const deploy = await callCli(['deploy', '--json', '--dir', 'public'], {
373+
const deploy = await callCli(['deploy', '--json', '--build', 'false', '--dir', 'public'], {
306374
cwd: builder.directory,
307375
env: { NETLIFY_SITE_ID: context.siteId },
308376
}).then((output) => JSON.parse(output))
@@ -329,7 +397,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
329397
})
330398
await builder.build()
331399

332-
const deploy = await callCli(['deploy', '--json', '--dir', 'public', '--prod'], {
400+
const deploy = await callCli(['deploy', '--json', '--build', 'false', '--dir', 'public', '--prod'], {
333401
cwd: builder.directory,
334402
env: { NETLIFY_SITE_ID: context.siteId },
335403
}).then((output) => JSON.parse(output))
@@ -344,31 +412,6 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
344412
})
345413
})
346414

347-
test('should return valid json when both --build and --json are passed', async (t) => {
348-
await withSiteBuilder(t, async (builder) => {
349-
const content = '<h1>⊂◉‿◉つ</h1>'
350-
builder
351-
.withContentFile({
352-
path: 'public/index.html',
353-
content,
354-
})
355-
.withNetlifyToml({
356-
config: {
357-
build: { publish: 'public' },
358-
},
359-
})
360-
361-
await builder.build()
362-
363-
const output = await callCli(['deploy', '--build', '--json'], {
364-
cwd: builder.directory,
365-
env: { NETLIFY_SITE_ID: context.siteId },
366-
})
367-
368-
JSON.parse(output)
369-
})
370-
})
371-
372415
test('should deploy hidden public folder but ignore hidden/__MACOSX files', { retry: 3 }, async (t) => {
373416
await withSiteBuilder(t, async (builder) => {
374417
builder
@@ -398,7 +441,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
398441

399442
await builder.build()
400443

401-
const deploy = await callCli(['deploy', '--json'], {
444+
const deploy = await callCli(['deploy', '--json', '--build', 'false'], {
402445
cwd: builder.directory,
403446
env: { NETLIFY_SITE_ID: context.siteId },
404447
}).then((output) => JSON.parse(output))
@@ -443,7 +486,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
443486

444487
await builder.build()
445488

446-
const deploy = await callCli(['deploy', '--json'], {
489+
const deploy = await callCli(['deploy', '--json', '--build', 'false'], {
447490
cwd: builder.directory,
448491
env: { NETLIFY_SITE_ID: context.siteId },
449492
}).then((output) => JSON.parse(output))
@@ -478,7 +521,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
478521

479522
await builder.build()
480523

481-
const deploy = await callCli(['deploy', '--json'], {
524+
const deploy = await callCli(['deploy', '--json', '--build', 'false'], {
482525
cwd: builder.directory,
483526
env: { NETLIFY_SITE_ID: context.siteId },
484527
}).then((output) => JSON.parse(output))
@@ -497,7 +540,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
497540
await builder.build()
498541

499542
try {
500-
await callCli(['deploy', '--dir', '.'], {
543+
await callCli(['deploy', '--build', 'false', '--dir', '.'], {
501544
cwd: builder.directory,
502545
env: { NETLIFY_SITE_ID: context.siteId },
503546
})
@@ -507,7 +550,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
507550
})
508551
})
509552

510-
test('should refresh configuration when --build is passed', async (t) => {
553+
test('refreshes configuration when building before deployment', async (t) => {
511554
await withSiteBuilder(t, async (builder) => {
512555
await builder
513556
.withContentFile({
@@ -542,7 +585,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
542585
.build()
543586

544587
const { deploy_url: deployUrl } = (await callCli(
545-
['deploy', '--build', '--json'],
588+
['deploy', '--json'],
546589
{
547590
cwd: builder.directory,
548591
env: { NETLIFY_SITE_ID: context.siteId },
@@ -652,7 +695,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
652695
.build()
653696

654697
const { deploy_url: deployUrl } = (await callCli(
655-
['deploy', '--build', '--json'],
698+
['deploy', '--json'],
656699
{
657700
cwd: builder.directory,
658701
env: { NETLIFY_SITE_ID: context.siteId },
@@ -700,7 +743,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
700743
.build()
701744

702745
const { deploy_url: deployUrl } = (await callCli(
703-
['deploy', '--build', '--json'],
746+
['deploy', '--json'],
704747
{
705748
cwd: builder.directory,
706749
env: { NETLIFY_SITE_ID: context.siteId },
@@ -758,7 +801,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
758801
.build()
759802

760803
const deploy = (await callCli(
761-
['deploy', '--json', '--build'],
804+
['deploy', '--json'],
762805
{
763806
cwd: builder.directory,
764807
env: { NETLIFY_SITE_ID: context.siteId },
@@ -843,7 +886,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
843886
.build()
844887

845888
const { deploy_url: deployUrl } = (await callCli(
846-
['deploy', '--json'],
889+
['deploy', '--json', '--build', 'false'],
847890
{
848891
cwd: builder.directory,
849892
env: { NETLIFY_SITE_ID: context.siteId },
@@ -902,7 +945,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
902945
.build()
903946

904947
const { deploy_url: deployUrl } = (await callCli(
905-
['deploy', '--json', '--skip-functions-cache'],
948+
['deploy', '--json', '--build', 'false', '--skip-functions-cache'],
906949
{
907950
cwd: builder.directory,
908951
env: { NETLIFY_SITE_ID: context.siteId },
@@ -963,7 +1006,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
9631006
.build()
9641007

9651008
const { deploy_url: deployUrl } = (await callCli(
966-
['deploy', '--json'],
1009+
['deploy', '--json', '--build', 'false'],
9671010
{
9681011
cwd: builder.directory,
9691012
env: { NETLIFY_SITE_ID: context.siteId },
@@ -1022,7 +1065,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
10221065

10231066
await execa.command('npm install', { cwd: builder.directory })
10241067
const { deploy_url: deployUrl } = (await callCli(
1025-
['deploy', '--json'],
1068+
['deploy', '--json', '--build', 'false'],
10261069
{
10271070
cwd: builder.directory,
10281071
env: { NETLIFY_SITE_ID: context.siteId },
@@ -1037,13 +1080,13 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
10371080

10381081
setupFixtureTests('next-app-without-config', () => {
10391082
test<FixtureTestContext>(
1040-
'should run deploy with --build without any netlify specific configuration',
1083+
'build without error without any netlify specific configuration',
10411084
{
10421085
timeout: 300_000,
10431086
},
10441087
async ({ fixture }) => {
10451088
const { deploy_url: deployUrl } = (await callCli(
1046-
['deploy', '--build', '--json'],
1089+
['deploy', '--json'],
10471090
{
10481091
cwd: fixture.directory,
10491092
env: { NETLIFY_SITE_ID: context.siteId },
@@ -1064,7 +1107,7 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co
10641107
await withSiteBuilder(t, async (builder) => {
10651108
await builder.build()
10661109
try {
1067-
await callCli(['deploy', '--prod-if-unlocked', '--prod'], {
1110+
await callCli(['deploy', '--build', 'false', '--prod-if-unlocked', '--prod'], {
10681111
cwd: builder.directory,
10691112
env: { NETLIFY_SITE_ID: context.siteId },
10701113
})

0 commit comments

Comments
 (0)