diff --git a/packages/build/src/plugins/pinned_version.js b/packages/build/src/plugins/pinned_version.js index 8c7508a22c..6cc5b41907 100644 --- a/packages/build/src/plugins/pinned_version.js +++ b/packages/build/src/plugins/pinned_version.js @@ -1,5 +1,5 @@ import { handleBuildError } from '../error/handle.js' -import { getMajorVersion } from '../utils/semver.js' +import { getMajorVersion, isPrerelease } from '../utils/semver.js' // Retrieve plugin's pinned major versions by fetching the latest `PluginRun` // Only applies to `netlify.toml`-only installed plugins. @@ -80,10 +80,17 @@ export const pinPlugins = async function ({ // - the plugin was installed in the UI // - both the build and the plugin succeeded const shouldPinVersion = function ({ - pluginOptions: { packageName, pinnedVersion, loadedFrom, origin }, + pluginOptions: { + packageName, + pinnedVersion, + pluginPackageJson: { version }, + loadedFrom, + origin, + }, failedPlugins, }) { return ( + !isPrerelease(version) && pinnedVersion === undefined && loadedFrom === 'auto_install' && origin === 'ui' && diff --git a/packages/build/src/utils/semver.js b/packages/build/src/utils/semver.js index f7b2b2a4c5..15bb9b0764 100644 --- a/packages/build/src/utils/semver.js +++ b/packages/build/src/utils/semver.js @@ -32,3 +32,7 @@ export const getMajorVersion = function (version) { const patchVersion = semver.patch(version) return `${majorVersion}.${minorVersion}.${patchVersion}` } + +export const isPrerelease = function (version) { + return semver.prerelease(version) +} diff --git a/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/index.js b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/index.js new file mode 100644 index 0000000000..5af9c00980 --- /dev/null +++ b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/index.js @@ -0,0 +1,3 @@ +export const onPreBuild = function () { + console.log('test') +} diff --git a/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/manifest.yml b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/manifest.yml new file mode 100644 index 0000000000..a3512f0259 --- /dev/null +++ b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/manifest.yml @@ -0,0 +1,2 @@ +name: test +inputs: [] diff --git a/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/package.json b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/package.json new file mode 100644 index 0000000000..dbdc68ea41 --- /dev/null +++ b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/node_modules/netlify-plugin-contextual-env/package.json @@ -0,0 +1,8 @@ +{ + "name": "netlify-plugin-contextual-env", + "version": "1.2.3-rc", + "type": "module", + "description": "test", + "license": "MIT", + "repository": "test" +} diff --git a/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/package.json b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/package.json new file mode 100644 index 0000000000..7229c0816f --- /dev/null +++ b/packages/build/tests/plugins_list/fixtures/pin_prerelease/.netlify/plugins/package.json @@ -0,0 +1,12 @@ +{ + "name": "netlify-local-plugins", + "description": "This directory contains Build plugins that have been automatically installed by Netlify.", + "version": "1.0.0", + "type": "module", + "private": true, + "author": "Netlify", + "license": "MIT", + "dependencies": { + "netlify-plugin-contextual-env": "1.2.3-rc" + } +} diff --git a/packages/build/tests/plugins_list/fixtures/pin_prerelease/package.json b/packages/build/tests/plugins_list/fixtures/pin_prerelease/package.json new file mode 100644 index 0000000000..c758eec5f6 --- /dev/null +++ b/packages/build/tests/plugins_list/fixtures/pin_prerelease/package.json @@ -0,0 +1,9 @@ +{ + "name": "module_plugin", + "version": "0.0.1", + "type": "module", + "description": "test", + "license": "MIT", + "repository": "test", + "dependencies": {} +} diff --git a/packages/build/tests/plugins_list/snapshots/tests.js.md b/packages/build/tests/plugins_list/snapshots/tests.js.md index beb3e73d47..44a05e79b1 100644 --- a/packages/build/tests/plugins_list/snapshots/tests.js.md +++ b/packages/build/tests/plugins_list/snapshots/tests.js.md @@ -2641,6 +2641,65 @@ Generated by [AVA](https://avajs.dev). (Netlify Build completed in 1ms)␊ Build step duration: Netlify Build completed in 1ms` +## Do not pin plugin with prerelease versions + +> Snapshot 1 + + `␊ + Netlify Build ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + > Version␊ + @netlify/build 1.0.0␊ + ␊ + > Flags␊ + debug: true␊ + repositoryRoot: packages/build/tests/plugins_list/fixtures/pin_prerelease␊ + sendStatus: true␊ + siteId: test␊ + testOpts:␊ + host: /test/socket␊ + pluginsListUrl: /test/socket␊ + scheme: http␊ + silentLingeringProcesses: true␊ + ␊ + > Current directory␊ + packages/build/tests/plugins_list/fixtures/pin_prerelease␊ + ␊ + > Config file␊ + No config file was defined: using default values.␊ + ␊ + > Resolved config␊ + build:␊ + publish: packages/build/tests/plugins_list/fixtures/pin_prerelease␊ + publishOrigin: default␊ + plugins:␊ + - inputs: {}␊ + origin: ui␊ + package: netlify-plugin-contextual-env␊ + ␊ + > Context␊ + production␊ + ␊ + > Available plugins␊ + ␊ + > Loading plugins␊ + - netlify-plugin-contextual-env 1-2-3-rc from Netlify app (latest 1-2-3-rc, expected 1-2-3-rc, compatible 1-2-3-rc)␊ + ␊ + netlify-plugin-contextual-env (onPreBuild event) ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + test␊ + ␊ + (netlify-plugin-contextual-env onPreBuild completed in 1ms)␊ + Build step duration: netlify-plugin-contextual-env onPreBuild completed in 1ms␊ + ␊ + Netlify Build Complete ␊ + ────────────────────────────────────────────────────────────────␊ + ␊ + (Netlify Build completed in 1ms)␊ + Build step duration: Netlify Build completed in 1ms` + ## Pin netlify.toml-only plugin versions > Snapshot 1 diff --git a/packages/build/tests/plugins_list/snapshots/tests.js.snap b/packages/build/tests/plugins_list/snapshots/tests.js.snap index 3dcaca8228..094b1e70f1 100644 Binary files a/packages/build/tests/plugins_list/snapshots/tests.js.snap and b/packages/build/tests/plugins_list/snapshots/tests.js.snap differ diff --git a/packages/build/tests/plugins_list/tests.js b/packages/build/tests/plugins_list/tests.js index 6e6a47370a..79aa63411e 100644 --- a/packages/build/tests/plugins_list/tests.js +++ b/packages/build/tests/plugins_list/tests.js @@ -411,6 +411,12 @@ test('Pinning plugin versions takes into account the compatibility field', async }) }) +test('Do not pin plugin with prerelease versions', async (t) => { + // By setting the status to 500 we ensure that the endpoint for pinning is + // not being called, otherwise an error would be thrown. + await runWithUpdatePluginMock(t, 'pin_prerelease', { status: 500, testPlugin: { version: '1.2.3-rc' } }) +}) + const runWithPluginRunsMock = async function ( t, fixtureName, diff --git a/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.md b/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.md index 6bb2f6b34f..435ccc1128 100644 --- a/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.md +++ b/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.md @@ -9,17 +9,17 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `Validation of Edge Functions manifest failed␊ - TYPE must be object␊ + TYPE must be object␊ ␊ - > 1 | "json"␊ -   | ^^^^^^ 👈🏽 type must be object` + > 1 | "json"␊ + | ^^^^^^ 👈🏽 type must be object` ## should print error on empty manifest > Snapshot 1 `Validation of Edge Functions manifest failed␊ - REQUIRED must have required property 'bundler_version'␊ + REQUIRED must have required property 'bundler_version'␊ ␊ - > 1 | {}␊ -   | ^ ☹️ bundler_version is missing here!` + > 1 | {}␊ + | ^ ☹️ bundler_version is missing here!` diff --git a/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap b/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap index 493c5159d1..4577a3380c 100644 Binary files a/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap and b/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap differ diff --git a/packages/build/tests/unit/validate_edge_manifest/tests.js b/packages/build/tests/unit/validate_edge_manifest/tests.js index 5e75c64a65..95400edf43 100644 --- a/packages/build/tests/unit/validate_edge_manifest/tests.js +++ b/packages/build/tests/unit/validate_edge_manifest/tests.js @@ -1,6 +1,7 @@ import test from 'ava' import { validateEdgeFunctionsManifest } from '../../../lib/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js' +import { removeErrorColors } from '../../../src/error/colors.js' test('should validate valid manifest', async (t) => { const manifest = { @@ -35,11 +36,15 @@ test('should print error on invalid manifest', async (t) => { const error = await t.throwsAsync(validateEdgeFunctionsManifest(manifest)) + removeErrorColors(error) + t.snapshot(error.message) }) test('should print error on empty manifest', async (t) => { const error = await t.throwsAsync(validateEdgeFunctionsManifest({})) + removeErrorColors(error) + t.snapshot(error.message) })