@netlify/build 29.41.6 → 29.42.1

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.
@@ -15,5 +15,6 @@ export const DEFAULT_FEATURE_FLAGS = {
15
15
  buildbot_zisi_system_log: false,
16
16
  edge_functions_cache_cli: false,
17
17
  edge_functions_system_logger: false,
18
+ netlify_build_reduced_output: false,
18
19
  netlify_build_updated_plugin_compatibility: false,
19
20
  };
@@ -47,6 +47,7 @@ type EventHandlers = {
47
47
  [K in keyof NetlifyPlugin]: NetlifyPlugin[K] | {
48
48
  handler: NetlifyPlugin[K];
49
49
  description: string;
50
+ quiet?: boolean;
50
51
  };
51
52
  };
52
53
  export type BuildResult = {
@@ -13,7 +13,7 @@ import { addExactDependencies } from './main.js';
13
13
  // their `package.json`.
14
14
  export const installMissingPlugins = async function ({ missingPlugins, autoPluginsDir, mode, logs }) {
15
15
  const packages = missingPlugins.map(getPackage);
16
- logInstallMissingPlugins(logs, packages);
16
+ logInstallMissingPlugins(logs, missingPlugins, packages);
17
17
  if (packages.length === 0) {
18
18
  return;
19
19
  }
@@ -1,7 +1,14 @@
1
+ import { OutputFlusher } from './output_flusher.js';
2
+ export type Logs = BufferedLogs | StreamedLogs;
1
3
  export type BufferedLogs = {
2
4
  stdout: string[];
3
5
  stderr: string[];
6
+ outputFlusher?: OutputFlusher;
4
7
  };
8
+ export type StreamedLogs = {
9
+ outputFlusher?: OutputFlusher;
10
+ };
11
+ export declare const logsAreBuffered: (logs: Logs | undefined) => logs is BufferedLogs;
5
12
  /**
6
13
  * When the `buffer` option is true, we return logs instead of printing them
7
14
  * on the console. The logs are accumulated in a `logs` array variable.
@@ -9,7 +16,7 @@ export type BufferedLogs = {
9
16
  export declare const getBufferLogs: (config: {
10
17
  buffer?: boolean;
11
18
  }) => BufferedLogs | undefined;
12
- export declare const log: (logs: BufferedLogs | undefined, string: string, config?: {
19
+ export declare const log: (logs: Logs | undefined, string: string, config?: {
13
20
  indent?: boolean;
14
21
  color?: (string: string) => string;
15
22
  }) => void;
@@ -31,3 +38,4 @@ export declare const reduceLogLines: (lines: any) => any;
31
38
  * the user-facing build logs)
32
39
  */
33
40
  export declare const getSystemLogger: (logs: BufferedLogs | undefined, debug: boolean, systemLogFile?: number) => (...args: any[]) => void;
41
+ export declare const addOutputGate: (logs: Logs, outputFlusher: OutputFlusher) => Logs;
package/lib/log/logger.js CHANGED
@@ -4,6 +4,9 @@ import indentString from 'indent-string';
4
4
  import { getHeader } from './header.js';
5
5
  import { serializeArray, serializeObject } from './serialize.js';
6
6
  import { THEME } from './theme.js';
7
+ export const logsAreBuffered = (logs) => {
8
+ return logs !== undefined && 'stdout' in logs;
9
+ };
7
10
  const INDENT_SIZE = 2;
8
11
  /**
9
12
  * We need to add a zero width space character in empty lines. Otherwise the
@@ -30,7 +33,8 @@ export const log = function (logs, string, config = {}) {
30
33
  const stringA = indent ? indentString(string, INDENT_SIZE) : string;
31
34
  const stringB = String(stringA).replace(EMPTY_LINES_REGEXP, EMPTY_LINE);
32
35
  const stringC = color === undefined ? stringB : color(stringB);
33
- if (logs !== undefined) {
36
+ logs?.outputFlusher?.flush();
37
+ if (logsAreBuffered(logs)) {
34
38
  // `logs` is a stateful variable
35
39
  logs.stdout.push(stringC);
36
40
  return;
@@ -138,3 +142,14 @@ systemLogFile) {
138
142
  });
139
143
  return (...args) => fileDescriptor.write(`${reduceLogLines(args)}\n`);
140
144
  };
145
+ export const addOutputGate = (logs, outputFlusher) => {
146
+ if (logsAreBuffered(logs)) {
147
+ return {
148
+ ...logs,
149
+ outputFlusher,
150
+ };
151
+ }
152
+ return {
153
+ outputFlusher,
154
+ };
155
+ };
@@ -1,4 +1,5 @@
1
1
  import { BufferedLogs } from '../logger.js';
2
+ import { OutputFlusher } from '../output_flusher.js';
2
3
  export declare const logBuildStart: (logs?: BufferedLogs) => void;
3
4
  export declare const logBuildError: ({ error, netlifyConfig, logs, debug }: {
4
5
  error: any;
@@ -7,6 +8,6 @@ export declare const logBuildError: ({ error, netlifyConfig, logs, debug }: {
7
8
  debug: any;
8
9
  }) => void;
9
10
  export declare const logBuildSuccess: (logs: any) => void;
10
- export declare const logTimer: (logs: any, durationNs: any, timerName: any, systemLog: any) => void;
11
+ export declare const logTimer: (logs: any, durationNs: any, timerName: any, systemLog: any, outputFlusher?: OutputFlusher) => void;
11
12
  export declare const logMissingSideFile: (logs: any, sideFile: any, publish: any) => void;
12
13
  export declare const logLingeringProcesses: (logs: any, commands: any) => void;
@@ -24,12 +24,14 @@ export const logBuildError = function ({ error, netlifyConfig, logs, debug }) {
24
24
  };
25
25
  export const logBuildSuccess = function (logs) {
26
26
  logHeader(logs, 'Netlify Build Complete');
27
- logMessage(logs, '');
28
27
  };
29
- export const logTimer = function (logs, durationNs, timerName, systemLog) {
28
+ export const logTimer = function (logs, durationNs, timerName, systemLog, outputFlusher) {
30
29
  const durationMs = roundTimerToMillisecs(durationNs);
31
30
  const duration = prettyMs(durationMs);
32
- log(logs, THEME.dimWords(`(${timerName} completed in ${duration})`));
31
+ if (!outputFlusher || outputFlusher.flushed) {
32
+ log(logs, '');
33
+ log(logs, THEME.dimWords(`(${timerName} completed in ${duration})`));
34
+ }
33
35
  systemLog(`Build step duration: ${timerName} completed in ${durationMs}ms`);
34
36
  };
35
37
  export const logMissingSideFile = function (logs, sideFile, publish) {
@@ -1,4 +1,4 @@
1
- export function logInstallMissingPlugins(logs: any, packages: any): void;
1
+ export function logInstallMissingPlugins(logs: any, missingPlugins: any, packages: any): void;
2
2
  export function logInstallIntegrations(logs: any, integrations: any): void;
3
3
  export function logInstallLocalPluginsDeps(logs: any, localPluginsOptions: any): void;
4
4
  export function logInstallFunctionDependencies(): void;
@@ -1,16 +1,11 @@
1
1
  import { isRuntime } from '../../utils/runtime.js';
2
2
  import { log, logArray, logSubHeader } from '../logger.js';
3
- export const logInstallMissingPlugins = function (logs, packages) {
4
- const runtimes = packages.filter((pkg) => isRuntime(pkg));
5
- const plugins = packages.filter((pkg) => !isRuntime(pkg));
3
+ export const logInstallMissingPlugins = function (logs, missingPlugins, packages) {
4
+ const plugins = missingPlugins.filter((pkg) => !isRuntime(pkg));
6
5
  if (plugins.length !== 0) {
7
6
  logSubHeader(logs, 'Installing plugins');
8
7
  logArray(logs, packages);
9
8
  }
10
- if (runtimes.length !== 0) {
11
- const [nextRuntime] = runtimes;
12
- logSubHeader(logs, `Using Next.js Runtime - v${nextRuntime.pluginPackageJson.version}`);
13
- }
14
9
  };
15
10
  export const logInstallIntegrations = function (logs, integrations) {
16
11
  if (integrations.length === 0) {
@@ -7,4 +7,3 @@ export function logStepStart({ logs, event, packageName, coreStepDescription, er
7
7
  netlifyConfig: any;
8
8
  }): void;
9
9
  export function logBuildCommandStart(logs: any, buildCommand: any): void;
10
- export function logStepSuccess(logs: any): void;
@@ -13,6 +13,3 @@ const getDescription = function ({ coreStepDescription, netlifyConfig, packageNa
13
13
  export const logBuildCommandStart = function (logs, buildCommand) {
14
14
  log(logs, THEME.highlightWords(`$ ${buildCommand}`));
15
15
  };
16
- export const logStepSuccess = function (logs) {
17
- logMessage(logs, '');
18
- };
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { Transform } from 'stream';
3
+ declare const flusherSymbol: unique symbol;
4
+ /**
5
+ * Utility class for conditionally rendering certain output only if additional
6
+ * data flows through. The constructor takes a "buffer" function that renders
7
+ * the optional data. When flushed, that function is called.
8
+ */
9
+ export declare class OutputFlusher {
10
+ private buffer;
11
+ flushed: boolean;
12
+ constructor(bufferFn: () => void);
13
+ flush(): void;
14
+ }
15
+ /**
16
+ * A `Transform` stream that takes an `OutputFlusher` instance and flushes it
17
+ * whenever data flows through, before piping the data to its destination.
18
+ */
19
+ export declare class OutputFlusherTransform extends Transform {
20
+ [flusherSymbol]: OutputFlusher;
21
+ constructor(flusher: OutputFlusher);
22
+ _transform(chunk: any, _: string, callback: () => void): void;
23
+ }
24
+ export {};
@@ -0,0 +1,37 @@
1
+ import { Transform } from 'stream';
2
+ const flusherSymbol = Symbol.for('@netlify/output-gate');
3
+ /**
4
+ * Utility class for conditionally rendering certain output only if additional
5
+ * data flows through. The constructor takes a "buffer" function that renders
6
+ * the optional data. When flushed, that function is called.
7
+ */
8
+ export class OutputFlusher {
9
+ buffer;
10
+ flushed;
11
+ constructor(bufferFn) {
12
+ this.flushed = false;
13
+ this.buffer = bufferFn;
14
+ }
15
+ flush() {
16
+ if (!this.flushed) {
17
+ this.buffer();
18
+ this.flushed = true;
19
+ }
20
+ }
21
+ }
22
+ /**
23
+ * A `Transform` stream that takes an `OutputFlusher` instance and flushes it
24
+ * whenever data flows through, before piping the data to its destination.
25
+ */
26
+ export class OutputFlusherTransform extends Transform {
27
+ [flusherSymbol];
28
+ constructor(flusher) {
29
+ super();
30
+ this[flusherSymbol] = flusher;
31
+ }
32
+ _transform(chunk, _, callback) {
33
+ this[flusherSymbol].flush();
34
+ this.push(chunk);
35
+ callback();
36
+ }
37
+ }
@@ -3,7 +3,7 @@ export function handleBuildCommandOutput({ stdout: commandStdout, stderr: comman
3
3
  stdout: any;
4
4
  stderr: any;
5
5
  }, logs: any): void;
6
- export function pipePluginOutput(childProcess: any, logs: any): void | {
6
+ export function pipePluginOutput(childProcess: any, logs: any, outputFlusher: any): void | {
7
7
  stdoutListener: any;
8
8
  stderrListener: any;
9
9
  };
package/lib/log/stream.js CHANGED
@@ -1,20 +1,22 @@
1
1
  import { stdout, stderr } from 'process';
2
2
  import { promisify } from 'util';
3
+ import { logsAreBuffered } from './logger.js';
4
+ import { OutputFlusherTransform } from './output_flusher.js';
3
5
  // TODO: replace with `timers/promises` after dropping Node < 15.0.0
4
6
  const pSetTimeout = promisify(setTimeout);
5
7
  // We try to use `stdio: inherit` because it keeps `stdout/stderr` as `TTY`,
6
8
  // which solves many problems. However we can only do it in build.command.
7
9
  // Plugins have several events, so need to be switch on and off instead.
8
- // In buffer mode (`logs` not `undefined`), `pipe` is necessary.
10
+ // In buffer mode, `pipe` is necessary.
9
11
  export const getBuildCommandStdio = function (logs) {
10
- if (logs !== undefined) {
12
+ if (logsAreBuffered(logs)) {
11
13
  return 'pipe';
12
14
  }
13
15
  return 'inherit';
14
16
  };
15
17
  // Add build command output
16
18
  export const handleBuildCommandOutput = function ({ stdout: commandStdout, stderr: commandStderr }, logs) {
17
- if (logs === undefined) {
19
+ if (!logsAreBuffered(logs)) {
18
20
  return;
19
21
  }
20
22
  pushBuildCommandOutput(commandStdout, logs.stdout);
@@ -27,23 +29,28 @@ const pushBuildCommandOutput = function (output, logsArray) {
27
29
  logsArray.push(output);
28
30
  };
29
31
  // Start plugin step output
30
- export const pipePluginOutput = function (childProcess, logs) {
31
- if (logs === undefined) {
32
- return streamOutput(childProcess);
32
+ export const pipePluginOutput = function (childProcess, logs, outputFlusher) {
33
+ if (!logsAreBuffered(logs)) {
34
+ return streamOutput(childProcess, outputFlusher);
33
35
  }
34
- return pushOutputToLogs(childProcess, logs);
36
+ return pushOutputToLogs(childProcess, logs, outputFlusher);
35
37
  };
36
38
  // Stop streaming/buffering plugin step output
37
39
  export const unpipePluginOutput = async function (childProcess, logs, listeners) {
38
40
  // Let `childProcess` `stdout` and `stderr` flush before stopping redirecting
39
41
  await pSetTimeout(0);
40
- if (logs === undefined) {
42
+ if (!logsAreBuffered(logs)) {
41
43
  return unstreamOutput(childProcess);
42
44
  }
43
45
  unpushOutputToLogs(childProcess, logs, listeners);
44
46
  };
45
47
  // Usually, we stream stdout/stderr because it is more efficient
46
- const streamOutput = function (childProcess) {
48
+ const streamOutput = function (childProcess, outputFlusher) {
49
+ if (outputFlusher) {
50
+ childProcess.stdout.pipe(new OutputFlusherTransform(outputFlusher)).pipe(stdout);
51
+ childProcess.stderr.pipe(new OutputFlusherTransform(outputFlusher)).pipe(stderr);
52
+ return;
53
+ }
47
54
  childProcess.stdout.pipe(stdout);
48
55
  childProcess.stderr.pipe(stderr);
49
56
  };
@@ -52,14 +59,17 @@ const unstreamOutput = function (childProcess) {
52
59
  childProcess.stderr.unpipe(stderr);
53
60
  };
54
61
  // In tests, we push to the `logs` array instead
55
- const pushOutputToLogs = function (childProcess, logs) {
56
- const stdoutListener = logsListener.bind(null, logs.stdout);
57
- const stderrListener = logsListener.bind(null, logs.stderr);
62
+ const pushOutputToLogs = function (childProcess, logs, outputFlusher) {
63
+ const stdoutListener = logsListener.bind(null, logs.stdout, outputFlusher);
64
+ const stderrListener = logsListener.bind(null, logs.stderr, outputFlusher);
58
65
  childProcess.stdout.on('data', stdoutListener);
59
66
  childProcess.stderr.on('data', stderrListener);
60
67
  return { stdoutListener, stderrListener };
61
68
  };
62
- const logsListener = function (logs, chunk) {
69
+ const logsListener = function (logs, outputFlusher, chunk) {
70
+ if (outputFlusher) {
71
+ outputFlusher.flush();
72
+ }
63
73
  logs.push(chunk.toString().trimEnd());
64
74
  };
65
75
  const unpushOutputToLogs = function (childProcess, logs, { stdoutListener, stderrListener }) {
@@ -4,6 +4,8 @@ import { createBuildbotClient, connectBuildbotClient, closeBuildbotClient, deplo
4
4
  const coreStep = async function ({ buildDir, configPath, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, featureFlags, context, branch, configMutations, headersPath, redirectsPath, debug, saveConfig, }) {
5
5
  const client = createBuildbotClient(buildbotServerSocket);
6
6
  try {
7
+ // buildbot will emit logs. Flush the output to preserve the right order.
8
+ logs?.outputFlusher?.flush();
7
9
  await connectBuildbotClient(client);
8
10
  await saveUpdatedConfig({
9
11
  configMutations,
@@ -18,4 +18,5 @@ export const preCleanup = {
18
18
  coreStepName: 'Pre cleanup',
19
19
  coreStepDescription: () => 'Cleaning up leftover files from previous builds',
20
20
  condition: blobsPresent,
21
+ quiet: true,
21
22
  };
@@ -53,4 +53,5 @@ export const preDevCleanup = {
53
53
  coreStepName: 'Pre Dev cleanup',
54
54
  coreStepDescription: () => 'Cleaning up leftover files from previous builds',
55
55
  condition,
56
+ quiet: true,
56
57
  };
@@ -1,4 +1,4 @@
1
- export declare const fireCoreStep: ({ coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, }: {
1
+ export declare const fireCoreStep: ({ coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, outputFlusher, }: {
2
2
  coreStep: any;
3
3
  coreStepId: any;
4
4
  coreStepName: any;
@@ -31,6 +31,7 @@ export declare const fireCoreStep: ({ coreStep, coreStepId, coreStepName, config
31
31
  explicitSecretKeys: any;
32
32
  edgeFunctionsBootstrapURL: any;
33
33
  deployId: any;
34
+ outputFlusher: any;
34
35
  }) => Promise<{
35
36
  newEnvChanges: any;
36
37
  netlifyConfig: any;
@@ -1,8 +1,10 @@
1
1
  import { setEnvChanges } from '../env/changes.js';
2
2
  import { addErrorInfo, isBuildError } from '../error/info.js';
3
+ import { addOutputGate } from '../log/logger.js';
3
4
  import { updateNetlifyConfig, listConfigSideFiles } from './update_config.js';
4
5
  // Fire a core step
5
- export const fireCoreStep = async function ({ coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, }) {
6
+ export const fireCoreStep = async function ({ coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, outputFlusher, }) {
7
+ const logsA = addOutputGate(logs, outputFlusher);
6
8
  try {
7
9
  const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
8
10
  const childEnvA = setEnvChanges(envChanges, { ...childEnv });
@@ -15,7 +17,7 @@ export const fireCoreStep = async function ({ coreStep, coreStepId, coreStepName
15
17
  packagePath,
16
18
  buildbotServerSocket,
17
19
  events,
18
- logs,
20
+ logs: logsA,
19
21
  quiet,
20
22
  context,
21
23
  branch,
@@ -43,7 +45,7 @@ export const fireCoreStep = async function ({ coreStep, coreStepId, coreStepName
43
45
  newConfigMutations,
44
46
  configSideFiles,
45
47
  errorParams,
46
- logs,
48
+ logs: logsA,
47
49
  systemLog,
48
50
  debug,
49
51
  });
package/lib/steps/get.js CHANGED
@@ -55,6 +55,7 @@ const getEventSteps = function (eventHandlers) {
55
55
  coreStepId: `options_${event}`,
56
56
  coreStepName: `options.${event}`,
57
57
  coreStepDescription: () => description,
58
+ quiet: eventHandler.quiet,
58
59
  };
59
60
  });
60
61
  };
@@ -1,5 +1,5 @@
1
1
  export function isTrustedPlugin(packageName: any): any;
2
- export function firePluginStep({ event, childProcess, packageName, packagePath, pluginPackageJson, loadedFrom, origin, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, constants, steps, error, logs, systemLog, featureFlags, debug, verbose, }: {
2
+ export function firePluginStep({ event, childProcess, packageName, packagePath, pluginPackageJson, loadedFrom, origin, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, constants, steps, error, logs, outputFlusher, systemLog, featureFlags, debug, verbose, }: {
3
3
  event: any;
4
4
  childProcess: any;
5
5
  packageName: any;
@@ -18,6 +18,7 @@ export function firePluginStep({ event, childProcess, packageName, packagePath,
18
18
  steps: any;
19
19
  error: any;
20
20
  logs: any;
21
+ outputFlusher: any;
21
22
  systemLog: any;
22
23
  featureFlags: any;
23
24
  debug: any;
@@ -1,5 +1,6 @@
1
1
  import { context, propagation } from '@opentelemetry/api';
2
2
  import { addErrorInfo } from '../error/info.js';
3
+ import { addOutputGate } from '../log/logger.js';
3
4
  import { logStepCompleted } from '../log/messages/ipc.js';
4
5
  import { pipePluginOutput, unpipePluginOutput } from '../log/stream.js';
5
6
  import { callChild } from '../plugins/ipc.js';
@@ -8,10 +9,11 @@ import { getPluginErrorType } from './error.js';
8
9
  import { updateNetlifyConfig, listConfigSideFiles } from './update_config.js';
9
10
  export const isTrustedPlugin = (packageName) => packageName?.startsWith('@netlify/');
10
11
  // Fire a plugin step
11
- export const firePluginStep = async function ({ event, childProcess, packageName, packagePath, pluginPackageJson, loadedFrom, origin, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, constants, steps, error, logs, systemLog, featureFlags, debug, verbose, }) {
12
- const listeners = pipePluginOutput(childProcess, logs);
12
+ export const firePluginStep = async function ({ event, childProcess, packageName, packagePath, pluginPackageJson, loadedFrom, origin, envChanges, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, constants, steps, error, logs, outputFlusher, systemLog, featureFlags, debug, verbose, }) {
13
+ const listeners = pipePluginOutput(childProcess, logs, outputFlusher);
13
14
  const otelCarrier = {};
14
15
  propagation.inject(context.active(), otelCarrier);
16
+ const logsA = addOutputGate(logs, outputFlusher);
15
17
  try {
16
18
  const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
17
19
  const { newEnvChanges, configMutations: newConfigMutations, status, } = await callChild({
@@ -39,7 +41,7 @@ export const firePluginStep = async function ({ event, childProcess, packageName
39
41
  newConfigMutations,
40
42
  configSideFiles,
41
43
  errorParams,
42
- logs,
44
+ logs: logsA,
43
45
  systemLog,
44
46
  debug,
45
47
  source: packageName,
@@ -1,4 +1,4 @@
1
- export function getStepReturn({ event, packageName, newError, newEnvChanges, newStatus, coreStep, coreStepName: timerName, childEnv, mode, api, errorMonitor, deployId, netlifyConfig, configMutations, headersPath, redirectsPath, logs, debug, timers, durationNs, testOpts, systemLog, quiet, metrics, }: {
1
+ export function getStepReturn({ event, packageName, newError, newEnvChanges, newStatus, coreStep, coreStepName: timerName, childEnv, mode, api, errorMonitor, deployId, netlifyConfig, configMutations, headersPath, redirectsPath, logs, outputFlusher, debug, timers, durationNs, testOpts, systemLog, quiet, metrics, }: {
2
2
  event: any;
3
3
  packageName: any;
4
4
  newError: any;
@@ -16,6 +16,7 @@ export function getStepReturn({ event, packageName, newError, newEnvChanges, new
16
16
  headersPath: any;
17
17
  redirectsPath: any;
18
18
  logs: any;
19
+ outputFlusher: any;
19
20
  debug: any;
20
21
  timers: any;
21
22
  durationNs: any;
@@ -1,8 +1,7 @@
1
1
  import { logTimer } from '../log/messages/core.js';
2
- import { logStepSuccess } from '../log/messages/steps.js';
3
2
  import { handleStepError } from './error.js';
4
3
  // Retrieve the return value of a step
5
- export const getStepReturn = function ({ event, packageName, newError, newEnvChanges, newStatus, coreStep, coreStepName: timerName = `${packageName} ${event}`, childEnv, mode, api, errorMonitor, deployId, netlifyConfig, configMutations, headersPath, redirectsPath, logs, debug, timers, durationNs, testOpts, systemLog, quiet, metrics, }) {
4
+ export const getStepReturn = function ({ event, packageName, newError, newEnvChanges, newStatus, coreStep, coreStepName: timerName = `${packageName} ${event}`, childEnv, mode, api, errorMonitor, deployId, netlifyConfig, configMutations, headersPath, redirectsPath, logs, outputFlusher, debug, timers, durationNs, testOpts, systemLog, quiet, metrics, }) {
6
5
  if (newError !== undefined) {
7
6
  return handleStepError({
8
7
  event,
@@ -20,8 +19,7 @@ export const getStepReturn = function ({ event, packageName, newError, newEnvCha
20
19
  });
21
20
  }
22
21
  if (!quiet) {
23
- logStepSuccess(logs);
24
- logTimer(logs, durationNs, timerName, systemLog);
22
+ logTimer(logs, durationNs, timerName, systemLog, outputFlusher);
25
23
  }
26
24
  return { newEnvChanges, netlifyConfig, configMutations, headersPath, redirectsPath, newStatus, timers, metrics };
27
25
  };
@@ -2,6 +2,7 @@ import { setMultiSpanAttributes } from '@netlify/opentelemetry-utils';
2
2
  import { trace } from '@opentelemetry/api';
3
3
  import { addMutableConstants } from '../core/constants.js';
4
4
  import { logStepStart } from '../log/messages/steps.js';
5
+ import { OutputFlusher } from '../log/output_flusher.js';
5
6
  import { runsAlsoOnBuildFailure, runsOnlyOnBuildFailure } from '../plugins/events.js';
6
7
  import { normalizeTagName } from '../report/statsd.js';
7
8
  import { measureDuration } from '../time/main.js';
@@ -52,8 +53,17 @@ export const runStep = async function ({ event, childProcess, packageName, coreS
52
53
  span.end();
53
54
  return {};
54
55
  }
55
- if (!quiet && !coreStepQuiet) {
56
- logStepStart({ logs, event, packageName, coreStepDescription, error, netlifyConfig });
56
+ const logPluginStart = !quiet && !coreStepQuiet
57
+ ? () => logStepStart({ logs, event, packageName, coreStepDescription, error, netlifyConfig })
58
+ : () => {
59
+ // no-op
60
+ };
61
+ let outputFlusher;
62
+ if (featureFlags.netlify_build_reduced_output) {
63
+ outputFlusher = new OutputFlusher(logPluginStart);
64
+ }
65
+ else {
66
+ logPluginStart();
57
67
  }
58
68
  const fireStep = getFireStep(packageName, coreStepId, event);
59
69
  const { newEnvChanges, netlifyConfig: netlifyConfigA = netlifyConfig, configMutations: configMutationsA = configMutations, headersPath: headersPathA = headersPath, redirectsPath: redirectsPathA = redirectsPath, newError, newStatus, timers: timersA, durationNs, metrics, } = await fireStep({
@@ -62,6 +72,7 @@ export const runStep = async function ({ event, childProcess, packageName, coreS
62
72
  packageName,
63
73
  pluginPackageJson,
64
74
  loadedFrom,
75
+ outputFlusher,
65
76
  origin,
66
77
  coreStep,
67
78
  coreStepId,
@@ -118,6 +129,7 @@ export const runStep = async function ({ event, childProcess, packageName, coreS
118
129
  headersPath: headersPathA,
119
130
  redirectsPath: redirectsPathA,
120
131
  logs,
132
+ outputFlusher,
121
133
  debug,
122
134
  timers: timersA,
123
135
  durationNs,
@@ -190,7 +202,7 @@ const getFireStep = function (packageName, coreStepId, event) {
190
202
  const parentTag = normalizeTagName(packageName);
191
203
  return measureDuration(tFireStep, event, { parentTag, category: 'pluginEvent' });
192
204
  };
193
- const tFireStep = function ({ event, childProcess, packageName, pluginPackageJson, loadedFrom, origin, coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, nodePath, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, error, logs, debug, quiet, systemLog, verbose, saveConfig, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, }) {
205
+ const tFireStep = function ({ event, childProcess, packageName, pluginPackageJson, loadedFrom, outputFlusher, origin, coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, nodePath, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, error, logs, debug, quiet, systemLog, verbose, saveConfig, errorParams, configOpts, netlifyConfig, configMutations, headersPath, redirectsPath, featureFlags, userNodeVersion, explicitSecretKeys, edgeFunctionsBootstrapURL, deployId, }) {
194
206
  if (coreStep !== undefined) {
195
207
  return fireCoreStep({
196
208
  coreStep,
@@ -205,6 +217,7 @@ const tFireStep = function ({ event, childProcess, packageName, pluginPackageJso
205
217
  buildbotServerSocket,
206
218
  events,
207
219
  logs,
220
+ outputFlusher,
208
221
  quiet,
209
222
  nodePath,
210
223
  childEnv,
@@ -234,6 +247,7 @@ const tFireStep = function ({ event, childProcess, packageName, pluginPackageJso
234
247
  packagePath,
235
248
  pluginPackageJson,
236
249
  loadedFrom,
250
+ outputFlusher,
237
251
  origin,
238
252
  envChanges,
239
253
  errorParams,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "29.41.6",
3
+ "version": "29.42.1",
4
4
  "description": "Netlify build module",
5
5
  "type": "module",
6
6
  "exports": "./lib/index.js",
@@ -165,5 +165,5 @@
165
165
  "engines": {
166
166
  "node": "^14.16.0 || >=16.0.0"
167
167
  },
168
- "gitHead": "46a7e2c1584acccb57a7c67e4133bbe35af96f9b"
168
+ "gitHead": "466e98c2767fbd956a7de2c085bb390d75ddb22c"
169
169
  }