@netlify/build 35.7.1 → 35.8.0-1-experimental

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.
Files changed (39) hide show
  1. package/lib/core/build.d.ts +1 -0
  2. package/lib/core/build.js +8 -4
  3. package/lib/core/dev.d.ts +2 -0
  4. package/lib/core/dev.js +3 -2
  5. package/lib/plugins/child/lazy.d.ts +1 -1
  6. package/lib/plugins/child/lazy.js +2 -0
  7. package/lib/plugins/child/run.d.ts +1 -0
  8. package/lib/plugins/child/run.js +3 -2
  9. package/lib/plugins/child/status.d.ts +1 -1
  10. package/lib/plugins/child/status.js +7 -4
  11. package/lib/plugins/child/utils.d.ts +19 -34
  12. package/lib/plugins/child/utils.js +38 -5
  13. package/lib/plugins/error.d.ts +16 -4
  14. package/lib/plugins_core/deploy/buildbot_client.d.ts +12 -6
  15. package/lib/plugins_core/deploy/buildbot_client.js +9 -5
  16. package/lib/plugins_core/deploy/index.d.ts +3 -30
  17. package/lib/plugins_core/deploy/index.js +10 -3
  18. package/lib/plugins_core/pre_cleanup/index.js +2 -2
  19. package/lib/plugins_core/save_artifacts/index.js +1 -0
  20. package/lib/plugins_core/types.d.ts +12 -1
  21. package/lib/steps/core_step.d.ts +2 -1
  22. package/lib/steps/core_step.js +2 -1
  23. package/lib/steps/get.d.ts +1 -1
  24. package/lib/steps/get.js +2 -3
  25. package/lib/steps/plugin.d.ts +2 -0
  26. package/lib/steps/plugin.js +2 -1
  27. package/lib/steps/return.d.ts +3 -1
  28. package/lib/steps/return.js +2 -1
  29. package/lib/steps/run_core_steps.js +2 -2
  30. package/lib/steps/run_step.d.ts +2 -1
  31. package/lib/steps/run_step.js +6 -3
  32. package/lib/steps/run_steps.d.ts +1 -0
  33. package/lib/steps/run_steps.js +6 -2
  34. package/lib/types/options/netlify_plugin_deploy_util.d.ts +9 -0
  35. package/lib/types/options/netlify_plugin_deploy_util.js +1 -0
  36. package/lib/types/options/netlify_plugin_utils.d.ts +5 -3
  37. package/lib/utils/environment.d.ts +1 -0
  38. package/lib/utils/environment.js +42 -0
  39. package/package.json +2 -3
@@ -89,4 +89,5 @@ export declare const runAndReportBuild: ({ pluginsOptions, netlifyConfig, defaul
89
89
  configMutations: never[] | undefined;
90
90
  metrics: never[] | undefined;
91
91
  returnValues: {} | undefined;
92
+ deployEnvVars: never[] | undefined;
92
93
  }>;
package/lib/core/build.js CHANGED
@@ -86,7 +86,7 @@ const tExecBuild = async function ({ config, defaultConfig, cachedConfig, cached
86
86
  const pluginsOptions = addCorePlugins({ netlifyConfig, constants });
87
87
  // `errorParams` is purposely stateful
88
88
  Object.assign(errorParams, { netlifyConfig, pluginsOptions, siteInfo, childEnv, userNodeVersion });
89
- const { pluginsOptions: pluginsOptionsA, netlifyConfig: netlifyConfigA, stepsCount, timers: timersB, configMutations, metrics, returnValues, } = await runAndReportBuild({
89
+ const { pluginsOptions: pluginsOptionsA, netlifyConfig: netlifyConfigA, stepsCount, timers: timersB, configMutations, metrics, returnValues, deployEnvVars, } = await runAndReportBuild({
90
90
  pluginsOptions,
91
91
  netlifyConfig,
92
92
  defaultConfig,
@@ -143,13 +143,14 @@ const tExecBuild = async function ({ config, defaultConfig, cachedConfig, cached
143
143
  configMutations,
144
144
  metrics,
145
145
  returnValues,
146
+ deployEnvVars,
146
147
  };
147
148
  };
148
149
  export const execBuild = measureDuration(tExecBuild, 'total', { parentTag: 'build_site' });
149
150
  // Runs a build then report any plugin statuses
150
151
  export const runAndReportBuild = async function ({ pluginsOptions, netlifyConfig, defaultConfig, configOpts, siteInfo, configPath, outputConfigPath, headersPath, redirectsPath, packagePath, buildDir, repositoryRoot, nodePath, packageJson, userNodeVersion, childEnv, context, branch, buildbotServerSocket, constants, dry, mode, api, token, errorMonitor, deployId, errorParams, logs, debug, systemLog, systemLogFile, verbose, timers, sendStatus, saveConfig, testOpts, featureFlags, timeline, devCommand, quiet, integrations, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, eventHandlers, }) {
151
152
  try {
152
- const { stepsCount, netlifyConfig: netlifyConfigA, statuses, pluginsOptions: pluginsOptionsA, failedPlugins, timers: timersA, configMutations, metrics, returnValues, } = await initAndRunBuild({
153
+ const { stepsCount, netlifyConfig: netlifyConfigA, statuses, pluginsOptions: pluginsOptionsA, failedPlugins, timers: timersA, configMutations, metrics, returnValues, deployEnvVars, } = await initAndRunBuild({
153
154
  pluginsOptions,
154
155
  netlifyConfig,
155
156
  defaultConfig,
@@ -234,6 +235,7 @@ export const runAndReportBuild = async function ({ pluginsOptions, netlifyConfig
234
235
  configMutations,
235
236
  metrics,
236
237
  returnValues,
238
+ deployEnvVars,
237
239
  };
238
240
  }
239
241
  catch (error) {
@@ -306,7 +308,7 @@ const initAndRunBuild = async function ({ pluginsOptions, netlifyConfig, default
306
308
  systemLogFile,
307
309
  });
308
310
  try {
309
- const { stepsCount, netlifyConfig: netlifyConfigA, statuses, failedPlugins, timers: timersC, configMutations, metrics, returnValues, } = await runBuild({
311
+ const { stepsCount, netlifyConfig: netlifyConfigA, statuses, failedPlugins, timers: timersC, configMutations, metrics, returnValues, deployEnvVars, } = await runBuild({
310
312
  childProcesses,
311
313
  pluginsOptions: pluginsOptionsA,
312
314
  netlifyConfig,
@@ -363,6 +365,7 @@ const initAndRunBuild = async function ({ pluginsOptions, netlifyConfig, default
363
365
  configMutations,
364
366
  metrics,
365
367
  returnValues,
368
+ deployEnvVars,
366
369
  };
367
370
  }
368
371
  finally {
@@ -400,7 +403,7 @@ const runBuild = async function ({ childProcesses, pluginsOptions, netlifyConfig
400
403
  await doDryRun({ buildDir, steps, netlifyConfig, constants, buildbotServerSocket, logs, featureFlags });
401
404
  return { netlifyConfig };
402
405
  }
403
- const { stepsCount, netlifyConfig: netlifyConfigA, statuses, failedPlugins, timers: timersB, configMutations, metrics, returnValues, } = await runSteps({
406
+ const { stepsCount, netlifyConfig: netlifyConfigA, statuses, failedPlugins, timers: timersB, configMutations, metrics, returnValues, deployEnvVars, } = await runSteps({
404
407
  steps,
405
408
  buildbotServerSocket,
406
409
  events,
@@ -447,5 +450,6 @@ const runBuild = async function ({ childProcesses, pluginsOptions, netlifyConfig
447
450
  configMutations,
448
451
  metrics,
449
452
  returnValues,
453
+ deployEnvVars,
450
454
  };
451
455
  };
package/lib/core/dev.d.ts CHANGED
@@ -5,6 +5,7 @@ export function startDev(devCommand: any, flags?: {}): Promise<{
5
5
  logs: import("../log/logger.js").Logs | undefined;
6
6
  configMutations: any;
7
7
  generatedFunctions: import("../steps/return_values.js").GeneratedFunction[];
8
+ deployEnvVars: any;
8
9
  error?: undefined;
9
10
  } | {
10
11
  success: boolean;
@@ -14,6 +15,7 @@ export function startDev(devCommand: any, flags?: {}): Promise<{
14
15
  message: string;
15
16
  stack: string;
16
17
  };
18
+ deployEnvVars: never[];
17
19
  netlifyConfig?: undefined;
18
20
  configMutations?: undefined;
19
21
  generatedFunctions?: undefined;
package/lib/core/dev.js CHANGED
@@ -6,7 +6,7 @@ export const startDev = async (devCommand, flags = {}) => {
6
6
  const { errorMonitor, mode, logs, debug, testOpts, ...normalizedFlags } = startBuild(flags);
7
7
  const errorParams = { errorMonitor, mode, logs, debug, testOpts };
8
8
  try {
9
- const { netlifyConfig: netlifyConfigA, configMutations, returnValues, } = await execBuild({
9
+ const { netlifyConfig: netlifyConfigA, configMutations, returnValues, deployEnvVars, } = await execBuild({
10
10
  ...normalizedFlags,
11
11
  errorMonitor,
12
12
  errorParams,
@@ -25,11 +25,12 @@ export const startDev = async (devCommand, flags = {}) => {
25
25
  logs,
26
26
  configMutations,
27
27
  generatedFunctions: getGeneratedFunctions(returnValues),
28
+ deployEnvVars,
28
29
  };
29
30
  }
30
31
  catch (error) {
31
32
  const { severity, message, stack } = await handleBuildError(error, errorParams);
32
33
  const { success, severityCode } = getSeverity(severity);
33
- return { success, severityCode, logs, error: { message, stack } };
34
+ return { success, severityCode, logs, error: { message, stack }, deployEnvVars: [] };
34
35
  }
35
36
  };
@@ -1 +1 @@
1
- export function addLazyProp(object: any, propName: any, getFunc: any): void;
1
+ export declare const addLazyProp: (object: object, propName: string, getFunc: () => unknown) => void;
@@ -2,6 +2,8 @@ import memoizeOne from 'memoize-one';
2
2
  // Add a `object[propName]` whose value is the return value of `getFunc()`, but
3
3
  // is only retrieved when accessed.
4
4
  export const addLazyProp = function (object, propName, getFunc) {
5
+ // @ts-expect-error(ndhoule): dis be angry
6
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
5
7
  const mGetFunc = memoizeOne(getFunc, returnTrue);
6
8
  // Mutation is required due to the usage of `Object.defineProperty()`
7
9
  Object.defineProperty(object, propName, {
@@ -13,6 +13,7 @@ export function run({ event, error, constants, envChanges, featureFlags, netlify
13
13
  packageJson: any;
14
14
  verbose: any;
15
15
  }): Promise<{
16
+ deployEnvVars: any[];
16
17
  newEnvChanges: any;
17
18
  configMutations: any;
18
19
  returnValue: {
@@ -13,8 +13,9 @@ export const run = async function ({ event, error, constants, envChanges, featur
13
13
  const method = methods[event];
14
14
  const runState = {};
15
15
  const generatedFunctions = [];
16
+ const deployEnvVars = [];
16
17
  const systemLog = getSystemLog();
17
- const utils = getUtils({ event, constants, generatedFunctions, runState });
18
+ const utils = getUtils({ event, constants, deployEnvVars, generatedFunctions, runState });
18
19
  const netlifyConfigCopy = cloneNetlifyConfig(netlifyConfig);
19
20
  const runOptions = {
20
21
  utils,
@@ -34,6 +35,6 @@ export const run = async function ({ event, error, constants, envChanges, featur
34
35
  const newEnvChanges = getNewEnvChanges(envBefore, netlifyConfig, netlifyConfigCopy);
35
36
  const configMutations = getConfigMutations(netlifyConfig, netlifyConfigCopy, event);
36
37
  const returnValue = generatedFunctions.length ? { generatedFunctions } : undefined;
37
- return { ...runState, newEnvChanges, configMutations, returnValue };
38
+ return { ...runState, deployEnvVars, newEnvChanges, configMutations, returnValue };
38
39
  });
39
40
  };
@@ -1 +1 @@
1
- export function show(runState: any, showArgs: any): void;
1
+ export declare const show: (runState: Record<string, unknown>, showArgs: Record<string, unknown>) => void;
@@ -17,19 +17,22 @@ const validateShowArgs = function (showArgs) {
17
17
  validateShowArgsExtraData(extraData);
18
18
  }
19
19
  catch (error) {
20
+ if (!(error instanceof Error)) {
21
+ throw error;
22
+ }
20
23
  error.message = `utils.status.show() ${error.message}`;
21
24
  addErrorInfo(error, { type: 'pluginValidation' });
22
25
  throw error;
23
26
  }
24
27
  };
25
- const validateShowArgsObject = function (showArgs) {
28
+ function validateShowArgsObject(showArgs) {
26
29
  if (showArgs === undefined) {
27
30
  throw new Error('requires an argument');
28
31
  }
29
32
  if (!isPlainObj(showArgs)) {
30
33
  throw new Error('argument must be a plain object');
31
34
  }
32
- };
35
+ }
33
36
  const validateShowArgsKeys = function (otherArgs) {
34
37
  const otherKeys = Object.keys(otherArgs).map((arg) => `"${arg}"`);
35
38
  if (otherKeys.length !== 0) {
@@ -42,12 +45,12 @@ const validateStringArg = function ([key, value]) {
42
45
  }
43
46
  };
44
47
  const validateShowArgsSummary = function (summary) {
45
- if (summary === undefined || summary.trim() === '') {
48
+ if (typeof summary !== 'string' || summary.trim() === '') {
46
49
  throw new Error('requires specifying a "summary" property');
47
50
  }
48
51
  };
49
52
  const validateShowArgsExtraData = function (extraData) {
50
- if (extraData !== undefined && Array.isArray(extraData) === false) {
53
+ if (extraData !== undefined && !Array.isArray(extraData)) {
51
54
  throw new TypeError('provided extra data must be an array');
52
55
  }
53
56
  };
@@ -1,34 +1,19 @@
1
- export function getUtils({ event, constants: { FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, CACHE_DIR }, generatedFunctions, runState, }: {
2
- event: any;
3
- constants: {
4
- FUNCTIONS_SRC: any;
5
- INTERNAL_FUNCTIONS_SRC: any;
6
- CACHE_DIR: any;
7
- };
8
- generatedFunctions?: never[] | undefined;
9
- runState: any;
10
- }): {
11
- build: {
12
- failPlugin: (message: any, opts: any) => never;
13
- failBuild: any;
14
- cancelBuild: any;
15
- };
16
- cache: {
17
- save: (paths: any, optsA: any) => Promise<any>;
18
- restore: (paths: any, optsA: any) => Promise<any>;
19
- remove: (paths: any, optsA: any) => Promise<any>;
20
- has: (paths: any, optsA: any) => Promise<any>;
21
- list: (optsA: any) => Promise<string[]>;
22
- getCacheDir: (optsA: any) => string;
23
- };
24
- run: (file: string, args?: string[] | object, options?: import("execa").Options) => import("execa").ExecaChildProcess<string>;
25
- functions: {
26
- add: (src: any) => Promise<void>;
27
- list: any;
28
- listAll: any;
29
- generate: (functionPath: any) => any;
30
- };
31
- status: {
32
- show: any;
33
- };
34
- };
1
+ import type { NetlifyPluginConstants } from '../../core/constants.js';
2
+ import type { ReturnValue } from '../../steps/return_values.ts';
3
+ import type { NetlifyPluginUtils } from '../../types/options/netlify_plugin_utils.js';
4
+ type BuildEvent = 'onPreBuild' | 'onBuild' | 'onPostBuild' | 'onError' | 'onSuccess' | 'onEnd';
5
+ type RunState = Record<string, unknown>;
6
+ type DeployEnvVarsData = {
7
+ key: string;
8
+ value: string;
9
+ isSecret: boolean;
10
+ scopes: string[];
11
+ }[];
12
+ export declare const getUtils: ({ event, constants: { FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, CACHE_DIR }, generatedFunctions, runState, deployEnvVars, }: {
13
+ event: BuildEvent;
14
+ constants: NetlifyPluginConstants;
15
+ generatedFunctions?: ReturnValue["generatedFunctions"];
16
+ runState: RunState;
17
+ deployEnvVars: DeployEnvVarsData;
18
+ }) => NetlifyPluginUtils;
19
+ export {};
@@ -1,22 +1,56 @@
1
1
  import { bindOpts as cacheBindOpts } from '@netlify/cache-utils';
2
2
  import { add as functionsAdd, list as functionsList, listAll as functionsListAll } from '@netlify/functions-utils';
3
3
  import { getGitUtils } from '@netlify/git-utils';
4
- import { run, runCommand } from '@netlify/run-utils';
4
+ import { run as baseRun, runCommand } from '@netlify/run-utils';
5
5
  import { failBuild, failPlugin, cancelBuild, failPluginWithWarning } from '../error.js';
6
6
  import { isSoftFailEvent } from '../events.js';
7
+ import { isReservedEnvironmentVariableKey } from '../../utils/environment.js';
7
8
  import { addLazyProp } from './lazy.js';
8
9
  import { show } from './status.js';
9
10
  // Retrieve the `utils` argument.
10
- export const getUtils = function ({ event, constants: { FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, CACHE_DIR }, generatedFunctions = [], runState, }) {
11
- run.command = runCommand;
11
+ export const getUtils = function ({ event, constants: { FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, CACHE_DIR }, generatedFunctions = [], runState, deployEnvVars = [], }) {
12
+ const run = Object.assign(baseRun, { command: runCommand });
12
13
  const build = getBuildUtils(event);
13
14
  const cache = getCacheUtils(CACHE_DIR);
15
+ const deploy = getDeployUtils({ deployEnvVars });
14
16
  const functions = getFunctionsUtils(FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, generatedFunctions);
15
17
  const status = getStatusUtils(runState);
16
- const utils = { build, cache, run, functions, status };
18
+ const utils = { build, cache, deploy, functions, run, status };
17
19
  addLazyProp(utils, 'git', () => getGitUtils());
18
20
  return utils;
19
21
  };
22
+ const getDeployUtils = ({ deployEnvVars }) => {
23
+ const env = {
24
+ add(key, value, { isSecret = false, scopes = [] } = {}) {
25
+ // Do some basic client-side validation on the injected variables. The build happens long
26
+ // before we attempt to create these environment variables via the Netlify API. We want to
27
+ // give the user as much immediate feedback as possible, so we perform this validation in the
28
+ // build plugin as to direct the user on which build plugin is causing a problem.
29
+ if (isReservedEnvironmentVariableKey(key)) {
30
+ throw new Error(`utils.deploy.env.add() failed: "${key}" is a reserved environment variable in Netlify deployments. Use a different environment variable key.`);
31
+ }
32
+ let normalizedScopes = new Set(...scopes);
33
+ if (normalizedScopes.size === 0) {
34
+ normalizedScopes = new Set(
35
+ // If the user did not specify scopes, we assume they mean all valid scopes. Secrets are
36
+ // not permitted in the post-processing scope.
37
+ isSecret ? ['builds', 'functions', 'runtime'] : ['builds', 'functions', 'post_processing', 'runtime']);
38
+ }
39
+ if (isSecret && normalizedScopes.has('post_processing')) {
40
+ throw new Error(`utils.deploy.env.add() failed: The "post_processing" scope cannot be used with isSecret=true.`);
41
+ }
42
+ const existingDeployEnvVarIdx = deployEnvVars.findIndex((env) => env.key === key);
43
+ if (existingDeployEnvVarIdx !== -1) {
44
+ deployEnvVars[existingDeployEnvVarIdx] = { key, value, isSecret, scopes: Array.from(normalizedScopes) };
45
+ }
46
+ else {
47
+ deployEnvVars.push({ key, value, isSecret, scopes: Array.from(normalizedScopes) });
48
+ }
49
+ return env;
50
+ },
51
+ };
52
+ return Object.freeze({ env: Object.freeze(env) });
53
+ };
20
54
  const getBuildUtils = function (event) {
21
55
  if (isSoftFailEvent(event)) {
22
56
  return {
@@ -36,7 +70,6 @@ const getFunctionsUtils = function (FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, gener
36
70
  const list = functionsList.bind(null, functionsDirectories, { fail: failBuild });
37
71
  const listAll = functionsListAll.bind(null, functionsDirectories, { fail: failBuild });
38
72
  const generate = (functionPath) => generatedFunctions.push({ path: functionPath });
39
- /** @type import('../../types/options/netlify_plugin_functions_util.js').NetlifyPluginFunctionsUtil */
40
73
  return { add, list, listAll, generate };
41
74
  };
42
75
  const getStatusUtils = function (runState) {
@@ -1,4 +1,16 @@
1
- export function failBuild(message: any, opts: any): never;
2
- export function failPlugin(message: any, opts: any): never;
3
- export function cancelBuild(message: any, opts: any): never;
4
- export function failPluginWithWarning(methodName: any, event: any, message: any, opts: any): void;
1
+ export declare const failBuild: (message: string, opts?: {
2
+ error: Error;
3
+ errorMetadata: string[];
4
+ }) => never;
5
+ export declare const failPlugin: (message: string, opts?: {
6
+ error: Error;
7
+ errorMetadata: string[];
8
+ }) => never;
9
+ export declare const cancelBuild: (message: string, opts?: {
10
+ error: Error;
11
+ errorMetadata: string[];
12
+ }) => never;
13
+ export declare const failPluginWithWarning: (methodName: string, event: string, message: string, opts: {
14
+ error: Error;
15
+ errorMetadata: string[];
16
+ }) => void;
@@ -1,4 +1,5 @@
1
1
  import net from 'net';
2
+ import type { NetlifyPluginConstants } from '../../core/constants.js';
2
3
  /**
3
4
  * Creates the Buildbot IPC client we use to initiate the deploy
4
5
  */
@@ -14,10 +15,15 @@ export declare const closeBuildbotClient: (client: net.Socket) => Promise<void>;
14
15
  /**
15
16
  * Initates the deploy with the given buildbot client
16
17
  */
17
- export declare const deploySiteWithBuildbotClient: ({ client, events, buildDir, repositoryRoot, constants }: {
18
- client: any;
19
- events: any;
20
- buildDir: any;
21
- repositoryRoot: any;
22
- constants: any;
18
+ export declare const deploySiteWithBuildbotClient: ({ client, environment, events, buildDir, repositoryRoot, constants, }: {
19
+ client: net.Socket;
20
+ environment: {
21
+ key: string;
22
+ value: string;
23
+ isSecret: boolean;
24
+ }[];
25
+ events: string[];
26
+ buildDir: string;
27
+ repositoryRoot: string;
28
+ constants: NetlifyPluginConstants;
23
29
  }) => Promise<undefined>;
@@ -62,11 +62,15 @@ const getNextParsedResponsePromise = addAsyncErrorMessage(async (buildbotClient)
62
62
  /**
63
63
  * Initates the deploy with the given buildbot client
64
64
  */
65
- export const deploySiteWithBuildbotClient = async function ({ client, events, buildDir, repositoryRoot, constants }) {
66
- const action = shouldWaitForPostProcessing(events) ? Action.DeploySiteAndWait : Action.DeploySite;
67
- const deployDir = getDeployDir({ buildDir, repositoryRoot, constants });
68
- const payload = { action, deployDir };
69
- const [response] = await Promise.all([getNextParsedResponsePromise(client), writePayload(client, payload)]);
65
+ export const deploySiteWithBuildbotClient = async function ({ client, environment, events, buildDir, repositoryRoot, constants, }) {
66
+ const [response] = await Promise.all([
67
+ getNextParsedResponsePromise(client),
68
+ writePayload(client, {
69
+ action: shouldWaitForPostProcessing(events) ? Action.DeploySiteAndWait : Action.DeploySite,
70
+ deployDir: getDeployDir({ buildDir, repositoryRoot, constants }),
71
+ environment,
72
+ }),
73
+ ]);
70
74
  if (!response.succeeded) {
71
75
  const { error, code, error_type } = response?.values || {};
72
76
  return handleDeployError(error, code, error_type);
@@ -1,30 +1,3 @@
1
- export function shouldDeploy({ buildbotServerSocket }: {
2
- buildbotServerSocket: any;
3
- }): boolean;
4
- export namespace deploySite {
5
- export let event: string;
6
- export { coreStep };
7
- export let coreStepId: string;
8
- export let coreStepName: string;
9
- export function coreStepDescription(): string;
10
- export { shouldDeploy as condition };
11
- }
12
- declare function coreStep({ buildDir, configPath, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, featureFlags, context, branch, configMutations, headersPath, redirectsPath, debug, saveConfig, }: {
13
- buildDir: any;
14
- configPath: any;
15
- repositoryRoot: any;
16
- packagePath: any;
17
- constants: any;
18
- buildbotServerSocket: any;
19
- events: any;
20
- logs: any;
21
- featureFlags: any;
22
- context: any;
23
- branch: any;
24
- configMutations: any;
25
- headersPath: any;
26
- redirectsPath: any;
27
- debug: any;
28
- saveConfig: any;
29
- }): Promise<{}>;
30
- export {};
1
+ import type { CoreStep, CoreStepCondition } from '../types.js';
2
+ export declare const shouldDeploy: CoreStepCondition;
3
+ export declare const deploySite: CoreStep;
@@ -1,7 +1,8 @@
1
+ // eslint-disable-next-line n/no-missing-import
1
2
  import { saveUpdatedConfig, restoreUpdatedConfig } from '../../core/config.js';
2
3
  import { logDeploySuccess } from '../../log/messages/plugins.js';
3
4
  import { createBuildbotClient, connectBuildbotClient, closeBuildbotClient, deploySiteWithBuildbotClient, } from './buildbot_client.js';
4
- const coreStep = async function ({ buildDir, configPath, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, featureFlags, context, branch, configMutations, headersPath, redirectsPath, debug, saveConfig, }) {
5
+ const coreStep = async function ({ buildDir, configPath, deployEnvVars, repositoryRoot, constants, buildbotServerSocket, events, logs, featureFlags, context, branch, configMutations, headersPath, redirectsPath, debug, saveConfig, }) {
5
6
  const client = createBuildbotClient(buildbotServerSocket);
6
7
  try {
7
8
  // buildbot will emit logs. Flush the output to preserve the right order.
@@ -10,7 +11,6 @@ const coreStep = async function ({ buildDir, configPath, repositoryRoot, package
10
11
  await saveUpdatedConfig({
11
12
  configMutations,
12
13
  buildDir,
13
- packagePath,
14
14
  repositoryRoot,
15
15
  configPath,
16
16
  headersPath,
@@ -22,7 +22,14 @@ const coreStep = async function ({ buildDir, configPath, repositoryRoot, package
22
22
  debug,
23
23
  saveConfig,
24
24
  });
25
- await deploySiteWithBuildbotClient({ client, events, buildDir, repositoryRoot, constants });
25
+ await deploySiteWithBuildbotClient({
26
+ client,
27
+ environment: deployEnvVars,
28
+ events,
29
+ buildDir,
30
+ repositoryRoot,
31
+ constants,
32
+ });
26
33
  await restoreUpdatedConfig({
27
34
  configMutations,
28
35
  buildDir,
@@ -3,9 +3,9 @@ import { resolve } from 'node:path';
3
3
  import { getBlobsDirs } from '../../utils/blobs.js';
4
4
  import { FRAMEWORKS_API_PATH } from '../../utils/frameworks_api.js';
5
5
  const coreStep = async ({ buildDir, packagePath }) => {
6
- const dirs = [...getBlobsDirs(buildDir, packagePath), resolve(buildDir, packagePath || '', FRAMEWORKS_API_PATH)];
6
+ const paths = [...getBlobsDirs(buildDir, packagePath), resolve(buildDir, packagePath || '', FRAMEWORKS_API_PATH)];
7
7
  try {
8
- await Promise.all(dirs.map((dir) => rm(dir, { recursive: true, force: true })));
8
+ await Promise.all(paths.map((dir) => rm(dir, { recursive: true, force: true })));
9
9
  }
10
10
  catch {
11
11
  // Ignore errors if it fails, we can continue anyway.
@@ -1,4 +1,5 @@
1
1
  import { saveUpdatedConfig } from '../../core/config.js';
2
+ // eslint-disable-next-line n/no-missing-import
2
3
  import { shouldDeploy } from '../deploy/index.js';
3
4
  const coreStep = async function ({ buildDir, configPath, packagePath, outputConfigPath, repositoryRoot, logs, featureFlags, context, branch, configMutations, headersPath, redirectsPath, debug, saveConfig, }) {
4
5
  await saveUpdatedConfig({
@@ -14,6 +14,7 @@ export type CoreStepFunctionArgs = {
14
14
  * `undefined` if none is set.
15
15
  */
16
16
  packagePath?: string;
17
+ repositoryRoot: string;
17
18
  deployId: string;
18
19
  /**
19
20
  * The deploy context (e.g. 'production', 'deploy-preview', 'branch-deploy')
@@ -27,14 +28,24 @@ export type CoreStepFunctionArgs = {
27
28
  constants: NetlifyPluginConstants;
28
29
  quiet?: boolean;
29
30
  debug?: boolean;
31
+ events: string[];
30
32
  logs?: BufferedLogs;
31
33
  systemLog: SystemLogger;
32
34
  edgeFunctionsBootstrapURL?: string;
33
35
  featureFlags?: Record<string, any>;
36
+ headersPath?: string;
37
+ redirectsPath?: string;
38
+ configMutations: unknown[];
39
+ configPath: string;
34
40
  netlifyConfig: NetlifyConfig;
35
41
  explicitSecretKeys: $TSFixme;
36
42
  enhancedSecretScan: boolean;
37
- buildbotServerSocket: $TSFixme;
43
+ deployEnvVars: {
44
+ key: string;
45
+ value: string;
46
+ isSecret: boolean;
47
+ }[];
48
+ buildbotServerSocket?: string;
38
49
  api: DynamicMethods;
39
50
  };
40
51
  export type CoreStepFunction = (args: CoreStepFunctionArgs) => Promise<object>;
@@ -1,4 +1,5 @@
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, defaultConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, outputFlusher, api, returnValues, }: {
1
+ export declare const fireCoreStep: ({ deployEnvVars, coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, outputFlusher, api, returnValues, }: {
2
+ deployEnvVars: any;
2
3
  coreStep: any;
3
4
  coreStepId: any;
4
5
  coreStepName: any;
@@ -3,12 +3,13 @@ import { addErrorInfo, isBuildError } from '../error/info.js';
3
3
  import { addOutputFlusher } from '../log/logger.js';
4
4
  import { updateNetlifyConfig, listConfigSideFiles } from './update_config.js';
5
5
  // Fire a core step
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, defaultConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, outputFlusher, api, returnValues, }) {
6
+ export const fireCoreStep = async function ({ deployEnvVars, coreStep, coreStepId, coreStepName, configPath, outputConfigPath, buildDir, repositoryRoot, packagePath, constants, buildbotServerSocket, events, logs, quiet, nodePath, childEnv, context, branch, envChanges, errorParams, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, featureFlags, debug, systemLog, saveConfig, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, outputFlusher, api, returnValues, }) {
7
7
  const logsA = outputFlusher ? addOutputFlusher(logs, outputFlusher) : logs;
8
8
  try {
9
9
  const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
10
10
  const childEnvA = setEnvChanges(envChanges, { ...childEnv });
11
11
  const { newEnvChanges = {}, configMutations: newConfigMutations = [], tags, metrics, } = await coreStep({
12
+ deployEnvVars,
12
13
  api,
13
14
  configPath,
14
15
  outputConfigPath,
@@ -3,7 +3,7 @@ export declare const getSteps: (steps: any, eventHandlers?: any[]) => {
3
3
  steps: CoreStep[];
4
4
  events: unknown[];
5
5
  };
6
- export declare const getDevSteps: (command: any, steps: any, eventHandlers?: any[]) => {
6
+ export declare const getDevSteps: (command: any, steps: any, eventHandlers: any[]) => {
7
7
  steps: CoreStep[];
8
8
  events: unknown[];
9
9
  };
package/lib/steps/get.js CHANGED
@@ -22,13 +22,12 @@ export const getSteps = function (steps, eventHandlers) {
22
22
  const events = getEvents(stepsB);
23
23
  return { steps: stepsC, events };
24
24
  };
25
- // Get all dev steps
26
25
  export const getDevSteps = function (command, steps, eventHandlers) {
27
26
  const devCommandStep = {
28
27
  event: 'onDev',
29
28
  coreStep: async (args) => {
30
29
  const { constants, event } = args;
31
- const utils = getUtils({ event, constants, runState: {} });
30
+ const utils = getUtils({ event, constants, runState: {}, deployEnvVars: args.deployEnvVars });
32
31
  await command({ utils, ...args });
33
32
  return {};
34
33
  },
@@ -53,7 +52,7 @@ const getEventSteps = function (eventHandlers) {
53
52
  event: event,
54
53
  coreStep: (args) => {
55
54
  const { constants, event } = args;
56
- const utils = getUtils({ event, constants, runState: {} });
55
+ const utils = getUtils({ event, constants, runState: {}, deployEnvVars: args.deployEnvVars });
57
56
  return handler({ utils, ...args });
58
57
  },
59
58
  coreStepId: `options_${event}`,
@@ -26,6 +26,7 @@ export function firePluginStep({ event, childProcess, packageName, packagePath,
26
26
  verbose: any;
27
27
  extensionMetadata: any;
28
28
  }): Promise<{
29
+ deployEnvVars: any;
29
30
  newEnvChanges: any;
30
31
  netlifyConfig: any;
31
32
  configMutations: any;
@@ -36,6 +37,7 @@ export function firePluginStep({ event, childProcess, packageName, packagePath,
36
37
  newError?: undefined;
37
38
  } | {
38
39
  newError: any;
40
+ deployEnvVars?: undefined;
39
41
  newEnvChanges?: undefined;
40
42
  netlifyConfig?: undefined;
41
43
  configMutations?: undefined;
@@ -18,7 +18,7 @@ export const firePluginStep = async function ({ event, childProcess, packageName
18
18
  const logsA = outputFlusher ? addOutputFlusher(logs, outputFlusher) : logs;
19
19
  try {
20
20
  const configSideFiles = await listConfigSideFiles([headersPath, redirectsPath]);
21
- const { newEnvChanges, configMutations: newConfigMutations, returnValue, status, } = await callChild({
21
+ const { configMutations: newConfigMutations, deployEnvVars, newEnvChanges, returnValue, status, } = await callChild({
22
22
  childProcess,
23
23
  eventName: 'run',
24
24
  payload: {
@@ -52,6 +52,7 @@ export const firePluginStep = async function ({ event, childProcess, packageName
52
52
  });
53
53
  const newStatus = getSuccessStatus(status, { steps, event, packageName });
54
54
  return {
55
+ deployEnvVars,
55
56
  newEnvChanges,
56
57
  netlifyConfig: netlifyConfigA,
57
58
  configMutations: configMutationsA,
@@ -1,4 +1,5 @@
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, returnValue, }: {
1
+ export function getStepReturn({ deployEnvVars, 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, returnValue, }: {
2
+ deployEnvVars: any;
2
3
  event: any;
3
4
  packageName: any;
4
5
  newError: any;
@@ -46,6 +47,7 @@ export function getStepReturn({ event, packageName, newError, newEnvChanges, new
46
47
  }> | {
47
48
  newError: any;
48
49
  } | {
50
+ deployEnvVars: any;
49
51
  newEnvChanges: any;
50
52
  netlifyConfig: any;
51
53
  configMutations: any;
@@ -1,7 +1,7 @@
1
1
  import { logTimer } from '../log/messages/core.js';
2
2
  import { handleStepError } from './error.js';
3
3
  // Retrieve the return value of a step
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, returnValue, }) {
4
+ export const getStepReturn = function ({ deployEnvVars, 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, returnValue, }) {
5
5
  if (newError !== undefined) {
6
6
  return handleStepError({
7
7
  event,
@@ -22,6 +22,7 @@ export const getStepReturn = function ({ event, packageName, newError, newEnvCha
22
22
  logTimer(logs, durationNs, timerName, systemLog, outputFlusher);
23
23
  }
24
24
  return {
25
+ deployEnvVars,
25
26
  newEnvChanges,
26
27
  netlifyConfig,
27
28
  configMutations,
@@ -108,7 +108,7 @@ const executeBuildStep = async function ({ config, packagePath, defaultConfig, c
108
108
  }
109
109
  };
110
110
  const runBuildStep = async function ({ defaultConfig, netlifyConfig, buildDir, nodePath, constants, logs, debug, featureFlags, packagePath, childEnv, buildSteps, repositoryRoot, systemLog, edgeFunctionsBootstrapURL, deployId, quiet, }) {
111
- const { netlifyConfig: netlifyConfigA, configMutations } = await runSteps({
111
+ const { netlifyConfig: netlifyConfigA, configMutations, deployEnvVars, } = await runSteps({
112
112
  steps: getBuildSteps(buildSteps),
113
113
  buildDir,
114
114
  nodePath,
@@ -127,5 +127,5 @@ const runBuildStep = async function ({ defaultConfig, netlifyConfig, buildDir, n
127
127
  deployId,
128
128
  quiet,
129
129
  });
130
- return { netlifyConfig: netlifyConfigA, configMutations };
130
+ return { deployEnvVars, netlifyConfig: netlifyConfigA, configMutations };
131
131
  };
@@ -1,4 +1,5 @@
1
- export declare const runStep: ({ event, childProcess, packageName, coreStep, coreStepId, coreStepName, coreStepDescription, coreStepQuiet, pluginPackageJson, loadedFrom, origin, condition, configPath, outputConfigPath, buildDir, packagePath, repositoryRoot, nodePath, index, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, mode, api, errorMonitor, deployId, errorParams, error, failedPlugins, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, extensionMetadata, returnValues, }: {
1
+ export declare const runStep: ({ deployEnvVars, event, childProcess, packageName, coreStep, coreStepId, coreStepName, coreStepDescription, coreStepQuiet, pluginPackageJson, loadedFrom, origin, condition, configPath, outputConfigPath, buildDir, packagePath, repositoryRoot, nodePath, index, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, mode, api, errorMonitor, deployId, errorParams, error, failedPlugins, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, extensionMetadata, returnValues, }: {
2
+ deployEnvVars: any;
2
3
  event: any;
3
4
  childProcess: any;
4
5
  packageName: any;
@@ -11,7 +11,7 @@ import { firePluginStep } from './plugin.js';
11
11
  import { getStepReturn } from './return.js';
12
12
  const tracer = trace.getTracer('steps');
13
13
  // Run a step (core, build command or plugin)
14
- export const runStep = async function ({ event, childProcess, packageName, coreStep, coreStepId, coreStepName, coreStepDescription, coreStepQuiet, pluginPackageJson, loadedFrom, origin, condition, configPath, outputConfigPath, buildDir, packagePath, repositoryRoot, nodePath, index, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, mode, api, errorMonitor, deployId, errorParams, error, failedPlugins, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, extensionMetadata, returnValues, }) {
14
+ export const runStep = async function ({ deployEnvVars, event, childProcess, packageName, coreStep, coreStepId, coreStepName, coreStepDescription, coreStepQuiet, pluginPackageJson, loadedFrom, origin, condition, configPath, outputConfigPath, buildDir, packagePath, repositoryRoot, nodePath, index, childEnv, context, branch, envChanges, constants, steps, buildbotServerSocket, events, mode, api, errorMonitor, deployId, errorParams, error, failedPlugins, configOpts, netlifyConfig, defaultConfig, configMutations, headersPath, redirectsPath, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, extensionMetadata, returnValues, }) {
15
15
  // Add relevant attributes to the upcoming span context
16
16
  const attributes = {
17
17
  'build.execution.step.name': coreStepName,
@@ -62,7 +62,7 @@ export const runStep = async function ({ event, childProcess, packageName, coreS
62
62
  };
63
63
  const outputFlusher = new OutputFlusher(logPluginStart);
64
64
  const fireStep = getFireStep(packageName, coreStepId, event);
65
- const { newEnvChanges, netlifyConfig: netlifyConfigA = netlifyConfig, configMutations: configMutationsA = configMutations, headersPath: headersPathA = headersPath, redirectsPath: redirectsPathA = redirectsPath, newError, newStatus, timers: timersA, durationNs, metrics, returnValue, } = await fireStep({
65
+ const { deployEnvVars: newDeployEnvVars, newEnvChanges, netlifyConfig: netlifyConfigA = netlifyConfig, configMutations: configMutationsA = configMutations, headersPath: headersPathA = headersPath, redirectsPath: redirectsPathA = redirectsPath, newError, newStatus, timers: timersA, durationNs, metrics, returnValue, } = await fireStep({
66
66
  extensionMetadata,
67
67
  defaultConfig,
68
68
  event,
@@ -111,8 +111,10 @@ export const runStep = async function ({ event, childProcess, packageName, coreS
111
111
  deployId,
112
112
  api,
113
113
  returnValues,
114
+ deployEnvVars,
114
115
  });
115
116
  const newValues = await getStepReturn({
117
+ deployEnvVars: newDeployEnvVars,
116
118
  event,
117
119
  packageName,
118
120
  newError,
@@ -206,9 +208,10 @@ const getFireStep = function (packageName, coreStepId, event) {
206
208
  const parentTag = normalizeTagName(packageName);
207
209
  return measureDuration(tFireStep, event, { parentTag, category: 'pluginEvent' });
208
210
  };
209
- const tFireStep = function ({ defaultConfig, 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, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, extensionMetadata, api, returnValues, }) {
211
+ const tFireStep = function ({ deployEnvVars, defaultConfig, 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, enhancedSecretScan, edgeFunctionsBootstrapURL, deployId, extensionMetadata, api, returnValues, }) {
210
212
  if (coreStep !== undefined) {
211
213
  return fireCoreStep({
214
+ deployEnvVars,
212
215
  coreStep,
213
216
  coreStepId,
214
217
  coreStepName,
@@ -44,4 +44,5 @@ export function runSteps({ defaultConfig, steps, buildbotServerSocket, events, c
44
44
  configMutations: never[];
45
45
  metrics: never[];
46
46
  returnValues: {};
47
+ deployEnvVars: never[];
47
48
  }>;
@@ -8,8 +8,9 @@ import { runStep } from './run_step.js';
8
8
  // If an error arises, runs `onError` events.
9
9
  // Runs `onEnd` events at the end, whether an error was thrown or not.
10
10
  export const runSteps = async function ({ defaultConfig, steps, buildbotServerSocket, events, configPath, outputConfigPath, headersPath, redirectsPath, buildDir, packagePath, repositoryRoot, nodePath, childEnv, context, branch, constants, mode, api, errorMonitor, deployId, errorParams, netlifyConfig, configOpts, logs, debug, systemLog, verbose, saveConfig, timers, testOpts, featureFlags, quiet, userNodeVersion, explicitSecretKeys, enhancedSecretScan, edgeFunctionsBootstrapURL, }) {
11
- const { index: stepsCount, error: errorA, netlifyConfig: netlifyConfigC, statuses: statusesB, failedPlugins: failedPluginsA, timers: timersC, configMutations: configMutationsB, metrics: metricsC, returnValues, } = await pReduce(steps, async ({ index, error, failedPlugins, envChanges, netlifyConfig: netlifyConfigA, configMutations, headersPath: headersPathA, redirectsPath: redirectsPathA, statuses, timers: timersA, metrics: metricsA, returnValues, }, { event, childProcess, packageName, extensionMetadata, coreStep, coreStepId, coreStepName, coreStepDescription, pluginPackageJson, loadedFrom, origin, condition, quiet: coreStepQuiet, }) => {
12
- const { newIndex = index, newError = error, failedPlugin = [], newEnvChanges = {}, netlifyConfig: netlifyConfigB = netlifyConfigA, configMutations: configMutationsA = configMutations, headersPath: headersPathB = headersPathA, redirectsPath: redirectsPathB = redirectsPathA, newStatus, timers: timersB = timersA, metrics: metricsB = [], returnValue, } = await runStep({
11
+ const { index: stepsCount, error: errorA, netlifyConfig: netlifyConfigC, statuses: statusesB, failedPlugins: failedPluginsA, timers: timersC, configMutations: configMutationsB, metrics: metricsC, returnValues, deployEnvVars, } = await pReduce(steps, async ({ deployEnvVars, index, error, failedPlugins, envChanges, netlifyConfig: netlifyConfigA, configMutations, headersPath: headersPathA, redirectsPath: redirectsPathA, statuses, timers: timersA, metrics: metricsA, returnValues, }, { event, childProcess, packageName, extensionMetadata, coreStep, coreStepId, coreStepName, coreStepDescription, pluginPackageJson, loadedFrom, origin, condition, quiet: coreStepQuiet, }) => {
12
+ const { newIndex = index, newError = error, deployEnvVars: newDeployEnvVars = [], failedPlugin = [], newEnvChanges = {}, netlifyConfig: netlifyConfigB = netlifyConfigA, configMutations: configMutationsA = configMutations, headersPath: headersPathB = headersPathA, redirectsPath: redirectsPathB = redirectsPathA, newStatus, timers: timersB = timersA, metrics: metricsB = [], returnValue, } = await runStep({
13
+ deployEnvVars,
13
14
  event,
14
15
  childProcess,
15
16
  packageName,
@@ -78,6 +79,7 @@ export const runSteps = async function ({ defaultConfig, steps, buildbotServerSo
78
79
  return {
79
80
  index: newIndex,
80
81
  error: newError,
82
+ deployEnvVars: Array.from([...deployEnvVars, ...newDeployEnvVars].reduce((acc, env) => acc.set(env.key, env), new Map()).values()),
81
83
  failedPlugins: [...failedPlugins, ...failedPlugin],
82
84
  envChanges: { ...envChanges, ...newEnvChanges },
83
85
  netlifyConfig: netlifyConfigB,
@@ -91,6 +93,7 @@ export const runSteps = async function ({ defaultConfig, steps, buildbotServerSo
91
93
  };
92
94
  }, {
93
95
  index: 0,
96
+ deployEnvVars: [],
94
97
  failedPlugins: [],
95
98
  envChanges: {},
96
99
  netlifyConfig,
@@ -117,5 +120,6 @@ export const runSteps = async function ({ defaultConfig, steps, buildbotServerSo
117
120
  configMutations: configMutationsB,
118
121
  metrics: metricsC,
119
122
  returnValues,
123
+ deployEnvVars,
120
124
  };
121
125
  };
@@ -0,0 +1,9 @@
1
+ export interface NetlifyPluginDeployUtilEnv {
2
+ add(key: string, value: string, options?: {
3
+ isSecret?: boolean;
4
+ scopes?: ('builds' | 'functions' | 'post_processing' | 'runtime')[];
5
+ }): this;
6
+ }
7
+ export interface NetlifyPluginDeployUtil {
8
+ readonly env: NetlifyPluginDeployUtilEnv;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,14 +1,16 @@
1
1
  import type { NetlifyPluginBuildUtil } from './netlify_plugin_build_util.js';
2
2
  import type { NetlifyPluginCacheUtil } from './netlify_plugin_cache_util.js';
3
+ import type { NetlifyPluginDeployUtil } from './netlify_plugin_deploy_util.js';
3
4
  import type { NetlifyPluginFunctionsUtil } from './netlify_plugin_functions_util.js';
4
5
  import type { NetlifyPluginGitUtil } from './netlify_plugin_git_util.js';
5
6
  import type { NetlifyPluginRunUtil } from './netlify_plugin_run_util.js';
6
7
  import type { NetlifyPluginStatusUtil } from './netlify_plugin_status_util.js';
7
8
  export interface NetlifyPluginUtils {
8
9
  build: NetlifyPluginBuildUtil;
9
- status: NetlifyPluginStatusUtil;
10
10
  cache: NetlifyPluginCacheUtil;
11
- run: NetlifyPluginRunUtil;
12
- git: NetlifyPluginGitUtil;
11
+ deploy: NetlifyPluginDeployUtil;
13
12
  functions: NetlifyPluginFunctionsUtil;
13
+ git: NetlifyPluginGitUtil;
14
+ run: NetlifyPluginRunUtil;
15
+ status: NetlifyPluginStatusUtil;
14
16
  }
@@ -0,0 +1 @@
1
+ export declare const isReservedEnvironmentVariableKey: (key: string) => boolean;
@@ -0,0 +1,42 @@
1
+ // This is not the final source of truth about which environment variable keys are reserved and
2
+ // which are not; the Netlify API will ultimately reject illegal environment variables when creating
3
+ // a deploy. We do local validation to let a user or plugin developer know as soon as is possible
4
+ // that an injected environment variable will later fail the build.
5
+ const RESERVED_ENV_VAR_KEYS = new Set([
6
+ // AWS-specific env vars
7
+ 'AWS_REGION',
8
+ 'AWS_EXECUTION_ENV',
9
+ 'AWS_LAMBDA_FUNCTION_NAME',
10
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE',
11
+ 'AWS_LAMBDA_FUNCTION_VERSION',
12
+ 'AWS_LAMBDA_LOG_GROUP_NAME',
13
+ 'AWS_LAMBDA_LOG_STREAM_NAME',
14
+ 'AWS_ACCESS_KEY_ID',
15
+ 'AWS_SECRET_ACCESS_KEY',
16
+ 'AWS_SESSION_TOKEN',
17
+ 'AWS_LAMBDA_RUNTIME_API',
18
+ // Build metadata https://docs.netlify.com/configure-builds/environment-variables/#build-metadata
19
+ 'NETLIFY',
20
+ 'BUILD_ID',
21
+ 'CONTEXT',
22
+ // Git metadata https://docs.netlify.com/configure-builds/environment-variables/#git-metadata
23
+ 'REPOSITORY_URL',
24
+ 'BRANCH',
25
+ 'HEAD',
26
+ 'COMMIT_REF',
27
+ 'CACHED_COMMIT_REF',
28
+ 'PULL_REQUEST',
29
+ 'REVIEW_ID',
30
+ // Deploy URLs and metadata// https://docs.netlify.com/configure-builds/environment-variables/#deploy-urls-and-metadata
31
+ 'URL',
32
+ 'DEPLOY_URL',
33
+ 'DEPLOY_PRIME_URL',
34
+ 'DEPLOY_ID',
35
+ 'SITE_NAME',
36
+ 'SITE_ID',
37
+ 'NETLIFY_IMAGES_CDN_DOMAIN',
38
+ 'INCOMING_HOOK_TITLE',
39
+ 'INCOMING_HOOK_URL',
40
+ 'INCOMING_HOOK_BODY',
41
+ ]);
42
+ export const isReservedEnvironmentVariableKey = (key) => RESERVED_ENV_VAR_KEYS.has(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/build",
3
- "version": "35.7.1",
3
+ "version": "35.8.0-1-experimental",
4
4
  "description": "Netlify build module",
5
5
  "type": "module",
6
6
  "exports": "./lib/index.js",
@@ -151,6 +151,5 @@
151
151
  },
152
152
  "engines": {
153
153
  "node": ">=18.14.0"
154
- },
155
- "gitHead": "3916fb7641d4e6fa8c2bede1e72d35ac8b87d8d8"
154
+ }
156
155
  }