diff --git a/packages/build/src/plugins_core/functions/utils.js b/packages/build/src/plugins_core/functions/utils.js index 138f011ece..912bd38769 100644 --- a/packages/build/src/plugins_core/functions/utils.js +++ b/packages/build/src/plugins_core/functions/utils.js @@ -16,7 +16,10 @@ const getRelativeFunctionMainFiles = async function ({ featureFlags, functionsSr const zisiFeatureFlags = getZisiFeatureFlags(featureFlags) const functions = await listFunctions(functionsSrc, { featureFlags: zisiFeatureFlags }) - return functions.map(({ mainFile }) => relative(functionsSrc, mainFile)) + const dedupedFunctions = new Map(functions.map((func) => [func.name, func])) + const relativeMainFiles = [...dedupedFunctions.values()].map(({ mainFile }) => relative(functionsSrc, mainFile)) + + return relativeMainFiles } export const getUserAndInternalFunctions = ({ diff --git a/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.js b/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.js new file mode 100644 index 0000000000..767df32b9c --- /dev/null +++ b/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.js @@ -0,0 +1 @@ +export const handler = () => true diff --git a/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.ts b/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.ts new file mode 100644 index 0000000000..767df32b9c --- /dev/null +++ b/packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions/function_one.ts @@ -0,0 +1 @@ +export const handler = () => true diff --git a/packages/build/tests/core/snapshots/tests.js.md b/packages/build/tests/core/snapshots/tests.js.md index d245361e63..930cfdd061 100644 --- a/packages/build/tests/core/snapshots/tests.js.md +++ b/packages/build/tests/core/snapshots/tests.js.md @@ -2276,3 +2276,53 @@ Generated by [AVA](https://avajs.dev). ────────────────────────────────────────────────────────────────␊ ␊ (Netlify Build completed in 1ms)` + +## Removes duplicate function names from the list of processed functions + +> Snapshot 1 + + `␊ + ────────────────────────────────────────────────────────────────␊ + Netlify Build ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + > Version␊ + @netlify/build 1.0.0␊ + ␊ + > Flags␊ + debug: true␊ + repositoryRoot: packages/build/tests/core/fixtures/functions_duplicate_names␊ + testOpts:␊ + pluginsListUrl: test␊ + silentLingeringProcesses: true␊ + ␊ + > Current directory␊ + packages/build/tests/core/fixtures/functions_duplicate_names␊ + ␊ + > Config file␊ + No config file was defined: using default values.␊ + ␊ + > Resolved config␊ + build:␊ + publish: packages/build/tests/core/fixtures/functions_duplicate_names␊ + publishOrigin: default␊ + functionsDirectory: packages/build/tests/core/fixtures/functions_duplicate_names/netlify/functions␊ + ␊ + > Context␊ + production␊ + ␊ + ────────────────────────────────────────────────────────────────␊ + 1. Functions bundling ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + Packaging Functions from netlify/functions directory:␊ + - function_one.js␊ + ␊ + ␊ + (Functions bundling completed in 1ms)␊ + ␊ + ────────────────────────────────────────────────────────────────␊ + Netlify Build Complete ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + (Netlify Build completed in 1ms)` diff --git a/packages/build/tests/core/snapshots/tests.js.snap b/packages/build/tests/core/snapshots/tests.js.snap index 3655f52ca4..abc45936ee 100644 Binary files a/packages/build/tests/core/snapshots/tests.js.snap and b/packages/build/tests/core/snapshots/tests.js.snap differ diff --git a/packages/build/tests/core/tests.js b/packages/build/tests/core/tests.js index fc983707f5..804a22778a 100644 --- a/packages/build/tests/core/tests.js +++ b/packages/build/tests/core/tests.js @@ -476,6 +476,10 @@ test('Bundles functions from the `.netlify/functions-internal` directory even if await runFixture(t, 'functions_user_missing') }) +test('Removes duplicate function names from the list of processed functions', async (t) => { + await runFixture(t, 'functions_duplicate_names') +}) + test.serial('`rustTargetDirectory` is passed to zip-it-and-ship-it only when running in buildbot', async (t) => { const fixtureWithConfig = 'functions_config_1' const fixtureWithoutConfig = 'functions_internal_missing'