@netlify/build 20.0.3 → 20.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "20.0.3",
3
+ "version": "20.3.0",
4
4
  "description": "Netlify build module",
5
5
  "main": "src/core/main.js",
6
6
  "types": "types/index.d.ts",
@@ -59,7 +59,7 @@
59
59
  "@netlify/functions-utils": "^3.0.0",
60
60
  "@netlify/git-utils": "^3.0.0",
61
61
  "@netlify/plugin-edge-handlers": "^3.0.0",
62
- "@netlify/plugins-list": "^5.0.0",
62
+ "@netlify/plugins-list": "^6.0.1",
63
63
  "@netlify/run-utils": "^3.0.0",
64
64
  "@netlify/zip-it-and-ship-it": "^5.2.0",
65
65
  "@sindresorhus/slugify": "^1.1.0",
@@ -16,10 +16,12 @@ const getFeatureFlag = function (name) {
16
16
  // Default values for feature flags
17
17
  const DEFAULT_FEATURE_FLAGS = {
18
18
  buildbot_build_go_functions: false,
19
+ buildbot_create_functions_manifest: false,
19
20
  buildbot_es_modules_esbuild: false,
20
21
  buildbot_zisi_trace_nft: false,
21
22
  buildbot_zisi_esbuild_parser: false,
22
23
  buildbot_scheduled_functions: false,
24
+ zisi_parse_isc: false,
23
25
  }
24
26
 
25
27
  module.exports = { normalizeCliFeatureFlags, DEFAULT_FEATURE_FLAGS }
package/src/core/flags.js CHANGED
@@ -134,7 +134,12 @@ Default: false`,
134
134
  },
135
135
  debug: {
136
136
  boolean: true,
137
- describe: 'Print debugging information',
137
+ describe: 'Print user-facing debugging information',
138
+ hidden: true,
139
+ },
140
+ verbose: {
141
+ boolean: true,
142
+ describe: 'Print internal debugging information',
138
143
  hidden: true,
139
144
  },
140
145
  sendStatus: {
package/src/core/main.js CHANGED
@@ -163,6 +163,7 @@ const tExecBuild = async function ({
163
163
  baseRelDir,
164
164
  env: envOpt,
165
165
  debug,
166
+ verbose,
166
167
  nodePath,
167
168
  functionsDistDir,
168
169
  cacheDir,
@@ -273,6 +274,7 @@ const tExecBuild = async function ({
273
274
  errorParams,
274
275
  logs,
275
276
  debug,
277
+ verbose,
276
278
  timers: timersA,
277
279
  sendStatus,
278
280
  saveConfig,
@@ -321,6 +323,7 @@ const runAndReportBuild = async function ({
321
323
  errorParams,
322
324
  logs,
323
325
  debug,
326
+ verbose,
324
327
  timers,
325
328
  sendStatus,
326
329
  saveConfig,
@@ -360,6 +363,7 @@ const runAndReportBuild = async function ({
360
363
  errorParams,
361
364
  logs,
362
365
  debug,
366
+ verbose,
363
367
  timers,
364
368
  sendStatus,
365
369
  saveConfig,
@@ -451,6 +455,7 @@ const initAndRunBuild = async function ({
451
455
  errorParams,
452
456
  logs,
453
457
  debug,
458
+ verbose,
454
459
  sendStatus,
455
460
  saveConfig,
456
461
  timers,
@@ -521,6 +526,7 @@ const initAndRunBuild = async function ({
521
526
  errorParams,
522
527
  logs,
523
528
  debug,
529
+ verbose,
524
530
  saveConfig,
525
531
  timers: timersB,
526
532
  testOpts,
@@ -573,6 +579,7 @@ const runBuild = async function ({
573
579
  errorParams,
574
580
  logs,
575
581
  debug,
582
+ verbose,
576
583
  saveConfig,
577
584
  timers,
578
585
  testOpts,
@@ -583,7 +590,9 @@ const runBuild = async function ({
583
590
  childProcesses,
584
591
  packageJson,
585
592
  timers,
593
+ logs,
586
594
  debug,
595
+ verbose,
587
596
  })
588
597
 
589
598
  const { steps, events } = getSteps(pluginsSteps)
@@ -623,6 +632,7 @@ const runBuild = async function ({
623
632
  configOpts,
624
633
  logs,
625
634
  debug,
635
+ verbose,
626
636
  saveConfig,
627
637
  timers: timersA,
628
638
  testOpts,
@@ -41,6 +41,7 @@ const getDefaultFlags = function ({ env: envOpt = {} }, combinedEnv) {
41
41
  mode: REQUIRE_MODE,
42
42
  offline: false,
43
43
  telemetry: false,
44
+ verbose: Boolean(combinedEnv.NETLIFY_BUILD_DEBUG),
44
45
  functionsDistDir: DEFAULT_FUNCTIONS_DIST,
45
46
  cacheDir: DEFAULT_CACHE_DIR,
46
47
  deployId: combinedEnv.DEPLOY_ID,
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const { log } = require('../logger')
4
+
5
+ const logVerbose = function (logs, verbose, message) {
6
+ if (!verbose) {
7
+ return
8
+ }
9
+
10
+ log(logs, message)
11
+ }
12
+
13
+ const logSendingEventToChild = function (logs, verbose) {
14
+ logVerbose(logs, verbose, 'Step starting.')
15
+ }
16
+
17
+ const logSentEventToChild = function (logs, verbose) {
18
+ logVerbose(logs, verbose, 'Step started.')
19
+ }
20
+
21
+ const logPluginMethodStart = function (verbose) {
22
+ logVerbose(undefined, verbose, 'Plugin logic started.')
23
+ }
24
+
25
+ const logPluginMethodEnd = function (verbose) {
26
+ logVerbose(undefined, verbose, 'Plugin logic ended.')
27
+ }
28
+
29
+ const logSendingEventToParent = function (verbose, error) {
30
+ const message = error instanceof Error ? `Step erroring.\n${error.stack}` : 'Stop closing.'
31
+ logVerbose(undefined, verbose, message)
32
+ }
33
+
34
+ const logReceivedEventFromChild = function (logs, verbose) {
35
+ logVerbose(logs, verbose, 'Step ended.')
36
+ }
37
+
38
+ const logStepCompleted = function (logs, verbose) {
39
+ logVerbose(logs, verbose, 'Step completed.')
40
+ }
41
+
42
+ module.exports = {
43
+ logSendingEventToChild,
44
+ logSentEventToChild,
45
+ logPluginMethodStart,
46
+ logPluginMethodEnd,
47
+ logSendingEventToParent,
48
+ logReceivedEventFromChild,
49
+ logStepCompleted,
50
+ }
@@ -8,11 +8,11 @@ const { normalizeError } = require('../../error/parse/normalize')
8
8
  const { sendEventToParent } = require('../ipc')
9
9
 
10
10
  // Handle any top-level error and communicate it back to parent
11
- const handleError = async function (error) {
11
+ const handleError = async function (error, verbose) {
12
12
  const errorA = normalizeError(error)
13
13
  addDefaultErrorInfo(errorA, { type: 'pluginInternal' })
14
14
  const errorPayload = errorToJson(errorA)
15
- await sendEventToParent('error', errorPayload)
15
+ await sendEventToParent('error', errorPayload, verbose, errorA)
16
16
  }
17
17
 
18
18
  // On uncaught exceptions and unhandled rejections, print the stack trace.
@@ -11,7 +11,7 @@ const { validatePlugin } = require('./validate')
11
11
  // This also validates the plugin.
12
12
  // Do it when parent requests it using the `load` event.
13
13
  // Also figure out the list of plugin steps. This is also passed to the parent.
14
- const load = async function ({ pluginPath, inputs, packageJson }) {
14
+ const load = async function ({ pluginPath, inputs, packageJson, verbose }) {
15
15
  const tsNodeService = registerTypeScript(pluginPath)
16
16
  const logic = await getLogic({ pluginPath, inputs, tsNodeService })
17
17
 
@@ -21,7 +21,7 @@ const load = async function ({ pluginPath, inputs, packageJson }) {
21
21
  const events = Object.keys(methods)
22
22
 
23
23
  // Context passed to every event handler
24
- const context = { methods, inputs, packageJson }
24
+ const context = { methods, inputs, packageJson, verbose }
25
25
 
26
26
  return { events, context }
27
27
  }
@@ -9,33 +9,42 @@ const { run } = require('./run')
9
9
 
10
10
  // Boot plugin child process.
11
11
  const bootPlugin = async function () {
12
+ const state = { context: { verbose: false } }
13
+
12
14
  try {
13
15
  handleProcessErrors()
14
16
  setInspectColors()
15
17
 
16
- const state = {}
17
18
  // We need to fire them in parallel because `process.send()` can be slow
18
19
  // to await, i.e. parent might send `load` event before child `ready` event
19
20
  // returns.
20
- await Promise.all([handleEvents(state), sendEventToParent('ready')])
21
+ await Promise.all([handleEvents(state), sendEventToParent('ready', {}, false)])
21
22
  } catch (error) {
22
- await handleError(error)
23
+ await handleError(error, state.context.verbose)
23
24
  }
24
25
  }
25
26
 
26
27
  // Wait for events from parent to perform plugin methods
27
28
  const handleEvents = async function (state) {
28
- await getEventsFromParent((callId, eventName, payload) => handleEvent(callId, eventName, payload, state))
29
+ await getEventsFromParent((callId, eventName, payload) => handleEvent({ callId, eventName, payload, state }))
29
30
  }
30
31
 
31
32
  // Each event can pass `context` information to the next event
32
- const handleEvent = async function (callId, eventName, payload, state) {
33
+ const handleEvent = async function ({
34
+ callId,
35
+ eventName,
36
+ payload,
37
+ state,
38
+ state: {
39
+ context: { verbose },
40
+ },
41
+ }) {
33
42
  try {
34
43
  const { context, ...response } = await EVENTS[eventName](payload, state.context)
35
44
  state.context = { ...state.context, ...context }
36
- await sendEventToParent(callId, response)
45
+ await sendEventToParent(callId, response, verbose)
37
46
  } catch (error) {
38
- await handleError(error)
47
+ await handleError(error, verbose)
39
48
  }
40
49
  }
41
50
 
@@ -1,12 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const { getNewEnvChanges, setEnvChanges } = require('../../env/changes')
4
+ const { logPluginMethodStart, logPluginMethodEnd } = require('../../log/messages/ipc')
4
5
 
5
6
  const { cloneNetlifyConfig, getConfigMutations } = require('./diff')
6
7
  const { getUtils } = require('./utils')
7
8
 
8
9
  // Run a specific plugin event handler
9
- const run = async function ({ event, error, constants, envChanges, netlifyConfig }, { methods, inputs, packageJson }) {
10
+ const run = async function (
11
+ { event, error, constants, envChanges, netlifyConfig },
12
+ { methods, inputs, packageJson, verbose },
13
+ ) {
10
14
  const method = methods[event]
11
15
  const runState = {}
12
16
  const utils = getUtils({ event, constants, runState })
@@ -14,7 +18,11 @@ const run = async function ({ event, error, constants, envChanges, netlifyConfig
14
18
  const runOptions = { utils, constants, inputs, netlifyConfig: netlifyConfigCopy, packageJson, error }
15
19
 
16
20
  const envBefore = setEnvChanges(envChanges)
21
+
22
+ logPluginMethodStart(verbose)
17
23
  await method(runOptions)
24
+ logPluginMethodEnd(verbose)
25
+
18
26
  const newEnvChanges = getNewEnvChanges(envBefore, netlifyConfig, netlifyConfigCopy)
19
27
 
20
28
  const configMutations = getConfigMutations(netlifyConfig, netlifyConfigCopy, event)
@@ -8,16 +8,23 @@ const { v4: uuidv4 } = require('uuid')
8
8
 
9
9
  const { jsonToError, errorToJson } = require('../error/build')
10
10
  const { addErrorInfo } = require('../error/info')
11
+ const {
12
+ logSendingEventToChild,
13
+ logSentEventToChild,
14
+ logReceivedEventFromChild,
15
+ logSendingEventToParent,
16
+ } = require('../log/messages/ipc')
11
17
 
12
18
  // Send event from child to parent process then wait for response
13
19
  // We need to fire them in parallel because `process.send()` can be slow
14
20
  // to await, i.e. child might send response before parent start listening for it
15
- const callChild = async function (childProcess, eventName, payload) {
21
+ const callChild = async function ({ childProcess, eventName, payload, logs, verbose }) {
16
22
  const callId = uuidv4()
17
23
  const [response] = await Promise.all([
18
24
  getEventFromChild(childProcess, callId),
19
- sendEventToChild(childProcess, callId, eventName, payload),
25
+ sendEventToChild({ childProcess, callId, eventName, payload, logs, verbose }),
20
26
  ])
27
+ logReceivedEventFromChild(logs, verbose)
21
28
  return response
22
29
  }
23
30
 
@@ -84,9 +91,13 @@ Plugin methods should instead:
84
91
  - on failure: call utils.build.failPlugin() or utils.build.failBuild()`
85
92
 
86
93
  // Send event from parent to child process
87
- const sendEventToChild = async function (childProcess, callId, eventName, payload) {
94
+ const sendEventToChild = async function ({ childProcess, callId, eventName, payload, logs, verbose }) {
95
+ logSendingEventToChild(logs, verbose)
96
+
88
97
  const payloadA = serializePayload(payload)
89
98
  await promisify(childProcess.send.bind(childProcess))([callId, eventName, payloadA])
99
+
100
+ logSentEventToChild(logs, verbose)
90
101
  }
91
102
 
92
103
  // Respond to events from parent to child process.
@@ -109,7 +120,8 @@ const getEventsFromParent = function (callback) {
109
120
  }
110
121
 
111
122
  // Send event from child to parent process
112
- const sendEventToParent = async function (callId, payload) {
123
+ const sendEventToParent = async function (callId, payload, verbose, error) {
124
+ logSendingEventToParent(verbose, error)
113
125
  await promisify(process.send.bind(process))([callId, payload])
114
126
  }
115
127
 
@@ -1,9 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const { pluginsList: oldPluginsList, pluginsUrl } = require('@netlify/plugins-list')
4
3
  const got = require('got')
5
4
  const isPlainObj = require('is-plain-obj')
6
5
 
6
+ // TODO: use static `import` after migrating this repository to pure ES modules
7
+ const netlifyPluginsList = import('@netlify/plugins-list')
8
+
7
9
  const { logPluginsList } = require('../log/messages/plugins')
8
10
  const { logPluginsFetchError } = require('../log/messages/plugins')
9
11
 
@@ -16,14 +18,16 @@ const { CONDITIONS } = require('./compatibility')
16
18
  // make this request is somewhat ok (in the 100ms range).
17
19
  // We only fetch this plugins list when needed, i.e. we defer it as much as
18
20
  // possible.
19
- const getPluginsList = async function ({ debug, logs, testOpts: { pluginsListUrl = pluginsUrl } }) {
21
+ const getPluginsList = async function ({ debug, logs, testOpts: { pluginsListUrl } }) {
20
22
  // We try not to mock in integration tests. However, sending a request for
21
23
  // each test would be too slow and make tests unreliable.
22
24
  if (pluginsListUrl === 'test') {
23
25
  return []
24
26
  }
25
27
 
26
- const pluginsList = await fetchPluginsList({ logs, pluginsListUrl })
28
+ const { pluginsUrl } = await netlifyPluginsList
29
+ const pluginsListUrlA = pluginsListUrl === undefined ? pluginsUrl : pluginsListUrl
30
+ const pluginsList = await fetchPluginsList({ logs, pluginsListUrl: pluginsListUrlA })
27
31
  const pluginsListA = normalizePluginsList(pluginsList)
28
32
  logPluginsList({ pluginsList: pluginsListA, debug, logs })
29
33
  return pluginsListA
@@ -46,6 +50,7 @@ const fetchPluginsList = async function ({ logs, pluginsListUrl }) {
46
50
  // buildbot release.
47
51
  } catch (error) {
48
52
  logPluginsFetchError(logs, error.message)
53
+ const { pluginsList: oldPluginsList } = await netlifyPluginsList
49
54
  return oldPluginsList
50
55
  }
51
56
  }
@@ -8,16 +8,16 @@ const { callChild } = require('./ipc')
8
8
 
9
9
  // Retrieve all plugins steps
10
10
  // Can use either a module name or a file path to the plugin.
11
- const loadPlugins = async function ({ pluginsOptions, childProcesses, packageJson, timers, debug }) {
11
+ const loadPlugins = async function ({ pluginsOptions, childProcesses, packageJson, timers, logs, debug, verbose }) {
12
12
  return pluginsOptions.length === 0
13
13
  ? { pluginsSteps: [], timers }
14
- : await loadAllPlugins({ pluginsOptions, childProcesses, packageJson, timers, debug })
14
+ : await loadAllPlugins({ pluginsOptions, childProcesses, packageJson, timers, logs, debug, verbose })
15
15
  }
16
16
 
17
- const tLoadAllPlugins = async function ({ pluginsOptions, childProcesses, packageJson, debug }) {
17
+ const tLoadAllPlugins = async function ({ pluginsOptions, childProcesses, packageJson, logs, debug, verbose }) {
18
18
  const pluginsSteps = await Promise.all(
19
19
  pluginsOptions.map((pluginOptions, index) =>
20
- loadPlugin(pluginOptions, { childProcesses, index, packageJson, debug }),
20
+ loadPlugin(pluginOptions, { childProcesses, index, packageJson, logs, debug, verbose }),
21
21
  ),
22
22
  )
23
23
  const pluginsStepsA = pluginsSteps.flat()
@@ -31,13 +31,19 @@ const loadAllPlugins = measureDuration(tLoadAllPlugins, 'load_plugins')
31
31
  // Do it by executing the plugin `load` event handler.
32
32
  const loadPlugin = async function (
33
33
  { packageName, pluginPackageJson, pluginPackageJson: { version } = {}, pluginPath, inputs, loadedFrom, origin },
34
- { childProcesses, index, packageJson, debug },
34
+ { childProcesses, index, packageJson, logs, debug, verbose },
35
35
  ) {
36
36
  const { childProcess } = childProcesses[index]
37
37
  const loadEvent = 'load'
38
38
 
39
39
  try {
40
- const { events } = await callChild(childProcess, 'load', { pluginPath, inputs, packageJson })
40
+ const { events } = await callChild({
41
+ childProcess,
42
+ eventName: 'load',
43
+ payload: { pluginPath, inputs, packageJson, verbose },
44
+ logs,
45
+ verbose: false,
46
+ })
41
47
  const pluginSteps = events.map((event) => ({
42
48
  event,
43
49
  packageName,
@@ -1,9 +1,11 @@
1
1
  'use strict'
2
2
 
3
3
  const getZisiFeatureFlags = (featureFlags) => ({
4
+ ...featureFlags,
4
5
  buildGoSource: featureFlags.buildbot_build_go_functions,
5
6
  defaultEsModulesToEsbuild: featureFlags.buildbot_es_modules_esbuild,
6
7
  nftTranspile: featureFlags.buildbot_nft_transpile_esm || featureFlags.buildbot_zisi_trace_nft,
8
+ parseISC: featureFlags.zisi_parse_isc,
7
9
  parseWithEsbuild: featureFlags.buildbot_zisi_esbuild_parser,
8
10
  traceWithNft: featureFlags.buildbot_zisi_trace_nft,
9
11
  })
@@ -51,8 +51,8 @@ const getZisiParameters = ({
51
51
  isRunningLocally,
52
52
  repositoryRoot,
53
53
  }) => {
54
- const isManifestEnabled = featureFlags.functionsBundlingManifest === true
55
- const manifest = isManifestEnabled && isRunningLocally ? join(functionsDist, 'manifest.json') : undefined
54
+ const isManifestEnabled = isRunningLocally || featureFlags.buildbot_create_functions_manifest === true
55
+ const manifest = isManifestEnabled ? join(functionsDist, 'manifest.json') : undefined
56
56
  const config = mapObject(functionsConfig, (expression, object) => [
57
57
  expression,
58
58
  normalizeFunctionConfig({ buildDir, featureFlags, functionConfig: object, isRunningLocally }),
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { addErrorInfo } = require('../error/info')
4
+ const { logStepCompleted } = require('../log/messages/ipc')
4
5
  const { pipePluginOutput, unpipePluginOutput } = require('../log/stream')
5
6
  const { callChild } = require('../plugins/ipc')
6
7
  const { getSuccessStatus } = require('../status/success')
@@ -28,6 +29,7 @@ const firePluginStep = async function ({
28
29
  error,
29
30
  logs,
30
31
  debug,
32
+ verbose,
31
33
  }) {
32
34
  const listeners = pipePluginOutput(childProcess, logs)
33
35
 
@@ -37,12 +39,12 @@ const firePluginStep = async function ({
37
39
  newEnvChanges,
38
40
  configMutations: newConfigMutations,
39
41
  status,
40
- } = await callChild(childProcess, 'run', {
41
- event,
42
- error,
43
- envChanges,
44
- netlifyConfig,
45
- constants,
42
+ } = await callChild({
43
+ childProcess,
44
+ eventName: 'run',
45
+ payload: { event, error, envChanges, netlifyConfig, constants },
46
+ logs,
47
+ verbose,
46
48
  })
47
49
  const {
48
50
  netlifyConfig: netlifyConfigA,
@@ -80,6 +82,7 @@ const firePluginStep = async function ({
80
82
  return { newError }
81
83
  } finally {
82
84
  await unpipePluginOutput(childProcess, logs, listeners)
85
+ logStepCompleted(logs, verbose)
83
86
  }
84
87
  }
85
88
 
@@ -50,6 +50,7 @@ const runStep = async function ({
50
50
  redirectsPath,
51
51
  logs,
52
52
  debug,
53
+ verbose,
53
54
  saveConfig,
54
55
  timers,
55
56
  testOpts,
@@ -110,6 +111,7 @@ const runStep = async function ({
110
111
  error,
111
112
  logs,
112
113
  debug,
114
+ verbose,
113
115
  saveConfig,
114
116
  timers,
115
117
  errorParams,
@@ -237,6 +239,7 @@ const tFireStep = function ({
237
239
  error,
238
240
  logs,
239
241
  debug,
242
+ verbose,
240
243
  saveConfig,
241
244
  errorParams,
242
245
  configOpts,
@@ -293,6 +296,7 @@ const tFireStep = function ({
293
296
  error,
294
297
  logs,
295
298
  debug,
299
+ verbose,
296
300
  })
297
301
  }
298
302
 
@@ -36,6 +36,7 @@ const runSteps = async function ({
36
36
  configOpts,
37
37
  logs,
38
38
  debug,
39
+ verbose,
39
40
  saveConfig,
40
41
  timers,
41
42
  testOpts,
@@ -128,6 +129,7 @@ const runSteps = async function ({
128
129
  redirectsPath: redirectsPathA,
129
130
  logs,
130
131
  debug,
132
+ verbose,
131
133
  saveConfig,
132
134
  timers: timersA,
133
135
  testOpts,