@netlify/build 29.38.0 → 29.38.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core/feature_flags.js +1 -0
- package/lib/plugins/compatibility.d.ts +5 -1
- package/lib/plugins/compatibility.js +49 -7
- package/lib/plugins/compatibility.test.js +270 -165
- package/lib/plugins/expected_version.d.ts +2 -1
- package/lib/plugins/expected_version.js +14 -4
- package/lib/plugins/resolve.js +1 -0
- package/package.json +5 -5
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { PackageJson } from 'read-pkg-up';
|
|
2
|
+
import { FeatureFlags } from '../core/feature_flags.js';
|
|
3
|
+
import { SystemLogger } from '../plugins_core/types.js';
|
|
2
4
|
import { PluginVersion } from './list.js';
|
|
3
5
|
/**
|
|
4
6
|
* Retrieve the `expectedVersion` of a plugin:
|
|
@@ -11,7 +13,7 @@ import { PluginVersion } from './list.js';
|
|
|
11
13
|
* - This is only used to print a warning message when the `compatibleVersion`
|
|
12
14
|
* is older than the currently used version.
|
|
13
15
|
*/
|
|
14
|
-
export declare const getExpectedVersion: ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, }: {
|
|
16
|
+
export declare const getExpectedVersion: ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, featureFlags, systemLog, }: {
|
|
15
17
|
versions: PluginVersion[];
|
|
16
18
|
/** The package.json of the repository */
|
|
17
19
|
packageJson: PackageJson;
|
|
@@ -19,6 +21,8 @@ export declare const getExpectedVersion: ({ versions, nodeVersion, packageJson,
|
|
|
19
21
|
buildDir: string;
|
|
20
22
|
nodeVersion: string;
|
|
21
23
|
pinnedVersion?: string | undefined;
|
|
24
|
+
featureFlags?: FeatureFlags | undefined;
|
|
25
|
+
systemLog: SystemLogger;
|
|
22
26
|
}) => Promise<{
|
|
23
27
|
version: string;
|
|
24
28
|
compatWarning: string;
|
|
@@ -15,7 +15,7 @@ const pEvery = _pEvery;
|
|
|
15
15
|
* - This is only used to print a warning message when the `compatibleVersion`
|
|
16
16
|
* is older than the currently used version.
|
|
17
17
|
*/
|
|
18
|
-
export const getExpectedVersion = async function ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, }) {
|
|
18
|
+
export const getExpectedVersion = async function ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, featureFlags, systemLog, }) {
|
|
19
19
|
const { version, conditions = [] } = await getCompatibleEntry({
|
|
20
20
|
versions,
|
|
21
21
|
nodeVersion,
|
|
@@ -23,6 +23,8 @@ export const getExpectedVersion = async function ({ versions, nodeVersion, packa
|
|
|
23
23
|
packagePath,
|
|
24
24
|
buildDir,
|
|
25
25
|
pinnedVersion,
|
|
26
|
+
featureFlags,
|
|
27
|
+
systemLog,
|
|
26
28
|
});
|
|
27
29
|
// Retrieve warning message shown when using an older version with `compatibility`
|
|
28
30
|
const compatWarning = conditions.map(({ type, condition }) => CONDITIONS[type].warning(condition)).join(', ');
|
|
@@ -44,12 +46,17 @@ export const getExpectedVersion = async function ({ versions, nodeVersion, packa
|
|
|
44
46
|
* - If there is a `pinnedVersion`, use it unless `latestVersion` matches it
|
|
45
47
|
* - Otherwise, use `latestVersion`
|
|
46
48
|
*/
|
|
47
|
-
const getCompatibleEntry = async function ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, }) {
|
|
49
|
+
const getCompatibleEntry = async function ({ versions, nodeVersion, packageJson, packagePath, buildDir, pinnedVersion, featureFlags, systemLog, }) {
|
|
48
50
|
const compatibleEntry = await pLocate(versions, async ({ version, overridePinnedVersion, conditions }) => {
|
|
49
|
-
//
|
|
51
|
+
// When there's a `pinnedVersion`, we typically pick the first version that
|
|
52
|
+
// matches that range. The exception is if `overridePinnedVersion` is also
|
|
53
|
+
// present. This property says that if the pinned version is within a given
|
|
54
|
+
// range, the entry that has this property can be used instead, even if its
|
|
55
|
+
// own version doesn't satisfy the pinned version.
|
|
50
56
|
const overridesPin = Boolean(pinnedVersion && overridePinnedVersion && semver.intersects(overridePinnedVersion, pinnedVersion));
|
|
51
|
-
//
|
|
52
|
-
|
|
57
|
+
// If there's a pinned version and this entry doesn't satisfy that range,
|
|
58
|
+
// discard it. The exception is if this entry overrides the pinned version.
|
|
59
|
+
if (pinnedVersion && !overridesPin && !semver.satisfies(version, pinnedVersion, { includePrerelease: true })) {
|
|
53
60
|
return false;
|
|
54
61
|
}
|
|
55
62
|
// no conditions means nothing to filter
|
|
@@ -58,6 +65,41 @@ const getCompatibleEntry = async function ({ versions, nodeVersion, packageJson,
|
|
|
58
65
|
}
|
|
59
66
|
return await pEvery(conditions, async ({ type, condition }) => CONDITIONS[type].test(condition, { nodeVersion, packageJson, packagePath, buildDir }));
|
|
60
67
|
});
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
if (compatibleEntry) {
|
|
69
|
+
return compatibleEntry;
|
|
70
|
+
}
|
|
71
|
+
if (pinnedVersion) {
|
|
72
|
+
return { version: pinnedVersion, conditions: [] };
|
|
73
|
+
}
|
|
74
|
+
const legacyFallback = { version: versions[0].version, conditions: [] };
|
|
75
|
+
const fallback = await getFirstCompatibleEntry({ versions, nodeVersion, packageJson, packagePath, buildDir });
|
|
76
|
+
if (featureFlags?.netlify_build_updated_plugin_compatibility) {
|
|
77
|
+
if (legacyFallback.version !== fallback.version) {
|
|
78
|
+
systemLog(`Detected mismatch in selected version for plugin '${packageJson?.name}': used new version of '${fallback.version}' over legacy version '${legacyFallback.version}'`);
|
|
79
|
+
}
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
if (legacyFallback.version !== fallback.version) {
|
|
83
|
+
systemLog(`Detected mismatch in selected version for plugin '${packageJson?.name}': used legacy version '${legacyFallback.version}' over new version '${fallback.version}'`);
|
|
84
|
+
}
|
|
85
|
+
return legacyFallback;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Takes a list of plugin versions and returns the first entry that satisfies
|
|
89
|
+
* the conditions (if any), without taking into account the pinned version.
|
|
90
|
+
*/
|
|
91
|
+
const getFirstCompatibleEntry = async function ({ versions, nodeVersion, packageJson, packagePath, buildDir, }) {
|
|
92
|
+
const compatibleEntry = await pLocate(versions, async ({ conditions }) => {
|
|
93
|
+
if (conditions.length === 0) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return await pEvery(conditions, async ({ type, condition }) => CONDITIONS[type].test(condition, { nodeVersion, packageJson, packagePath, buildDir }));
|
|
97
|
+
});
|
|
98
|
+
if (compatibleEntry) {
|
|
99
|
+
return compatibleEntry;
|
|
100
|
+
}
|
|
101
|
+
// We should never get here, because it means there are no plugin versions
|
|
102
|
+
// that we can install. We're keeping this here because it has been the
|
|
103
|
+
// default behavior for a long time, but we should look to remove it.
|
|
104
|
+
return { version: versions[0].version, conditions: [] };
|
|
63
105
|
};
|
|
@@ -1,177 +1,282 @@
|
|
|
1
|
-
import { expect, test } from 'vitest';
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
2
|
import { getExpectedVersion } from './compatibility.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
const noopSystemLog = () => {
|
|
4
|
+
// no-op
|
|
5
|
+
};
|
|
6
|
+
describe(`getExpectedVersion`, () => {
|
|
7
|
+
test('should ignore the new major version if the version is pinned', async () => {
|
|
8
|
+
const versions = [
|
|
9
|
+
{ version: '5.0.0', conditions: [] },
|
|
10
|
+
{ version: '4.41.2', conditions: [] },
|
|
11
|
+
];
|
|
12
|
+
const { version } = await getExpectedVersion({
|
|
13
|
+
versions,
|
|
14
|
+
nodeVersion: '18.19.0',
|
|
15
|
+
packageJson: {},
|
|
16
|
+
buildDir: '/some/path',
|
|
17
|
+
pinnedVersion: '4',
|
|
18
|
+
systemLog: noopSystemLog,
|
|
19
|
+
});
|
|
20
|
+
expect(version).toBe('4.41.2');
|
|
14
21
|
});
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
{ version:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
test('matches prerelease versions', async () => {
|
|
23
|
+
const versions = [
|
|
24
|
+
{ version: '5.0.0', conditions: [] },
|
|
25
|
+
{ version: '4.42.0-alpha.1', conditions: [] },
|
|
26
|
+
{ version: '4.41.2', conditions: [] },
|
|
27
|
+
];
|
|
28
|
+
const { version: version1 } = await getExpectedVersion({
|
|
29
|
+
versions,
|
|
30
|
+
nodeVersion: '18.19.0',
|
|
31
|
+
packageJson: {},
|
|
32
|
+
buildDir: '/some/path',
|
|
33
|
+
systemLog: noopSystemLog,
|
|
34
|
+
});
|
|
35
|
+
const { version: version2 } = await getExpectedVersion({
|
|
36
|
+
versions,
|
|
37
|
+
nodeVersion: '18.19.0',
|
|
38
|
+
packageJson: {},
|
|
39
|
+
buildDir: '/some/path',
|
|
40
|
+
pinnedVersion: '4',
|
|
41
|
+
systemLog: noopSystemLog,
|
|
42
|
+
});
|
|
43
|
+
expect(version1).toBe('5.0.0');
|
|
44
|
+
expect(version2).toBe('4.42.0-alpha.1');
|
|
28
45
|
});
|
|
29
|
-
|
|
30
|
-
versions
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
46
|
+
test('should retrieve a new major version if the overridePinnedVersion is specified', async () => {
|
|
47
|
+
const versions = [
|
|
48
|
+
{ version: '5.0.0', conditions: [], overridePinnedVersion: '>=4.0.0' },
|
|
49
|
+
{ version: '4.41.2', conditions: [] },
|
|
50
|
+
];
|
|
51
|
+
const { version } = await getExpectedVersion({
|
|
52
|
+
versions,
|
|
53
|
+
nodeVersion: '18.19.0',
|
|
54
|
+
packageJson: {},
|
|
55
|
+
buildDir: '/some/path',
|
|
56
|
+
pinnedVersion: '4',
|
|
57
|
+
systemLog: noopSystemLog,
|
|
58
|
+
});
|
|
59
|
+
expect(version).toBe('5.0.0');
|
|
35
60
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
test('should retrieve the plugin based on the condition of a nodeVersion', async () => {
|
|
62
|
+
const versions = [
|
|
63
|
+
{
|
|
64
|
+
version: '4.42.0',
|
|
65
|
+
conditions: [{ type: 'nodeVersion', condition: '>=18.0.0' }],
|
|
66
|
+
},
|
|
67
|
+
{ version: '4.41.2', conditions: [] },
|
|
68
|
+
];
|
|
69
|
+
const { version } = await getExpectedVersion({
|
|
70
|
+
versions,
|
|
71
|
+
nodeVersion: '17.19.0',
|
|
72
|
+
packageJson: {},
|
|
73
|
+
buildDir: '/some/path',
|
|
74
|
+
pinnedVersion: '4',
|
|
75
|
+
systemLog: noopSystemLog,
|
|
76
|
+
});
|
|
77
|
+
expect(version).toBe('4.41.2');
|
|
50
78
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
test('should retrieve the plugin based on conditions and feature flag due to pinned version', async () => {
|
|
80
|
+
const versions = [
|
|
81
|
+
{
|
|
82
|
+
version: '5.0.0-beta.1',
|
|
83
|
+
conditions: [
|
|
84
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
85
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
86
|
+
],
|
|
87
|
+
overridePinnedVersion: '>=4.0.0',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
version: '4.42.0',
|
|
91
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '>=10.0.9' } }],
|
|
92
|
+
},
|
|
93
|
+
{ version: '4.41.2', conditions: [] },
|
|
94
|
+
{
|
|
95
|
+
version: '3.9.2',
|
|
96
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
const { version: version1 } = await getExpectedVersion({
|
|
100
|
+
versions,
|
|
101
|
+
nodeVersion: '17.19.0',
|
|
102
|
+
packageJson: { dependencies: { next: '10.0.8' } },
|
|
103
|
+
buildDir: '/some/path',
|
|
104
|
+
pinnedVersion: '3',
|
|
105
|
+
systemLog: noopSystemLog,
|
|
106
|
+
});
|
|
107
|
+
expect(version1).toBe('3.9.2');
|
|
108
|
+
const { version: version2 } = await getExpectedVersion({
|
|
109
|
+
versions,
|
|
110
|
+
nodeVersion: '17.19.0',
|
|
111
|
+
packageJson: { dependencies: { next: '11.0.0' } },
|
|
112
|
+
buildDir: '/some/path',
|
|
113
|
+
pinnedVersion: '4',
|
|
114
|
+
systemLog: noopSystemLog,
|
|
115
|
+
});
|
|
116
|
+
expect(version2).toBe('4.42.0');
|
|
117
|
+
const { version: version3 } = await getExpectedVersion({
|
|
118
|
+
versions,
|
|
119
|
+
nodeVersion: '18.19.0',
|
|
120
|
+
packageJson: { dependencies: { next: '13.5.0' } },
|
|
121
|
+
buildDir: '/some/path',
|
|
122
|
+
pinnedVersion: '4',
|
|
123
|
+
systemLog: noopSystemLog,
|
|
124
|
+
});
|
|
125
|
+
expect(version3).toBe('5.0.0-beta.1');
|
|
67
126
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
127
|
+
test('should work with rc versions inside the siteDependencies constraints', async () => {
|
|
128
|
+
const versions = [
|
|
129
|
+
{
|
|
130
|
+
version: '5.0.0-beta.1',
|
|
131
|
+
conditions: [
|
|
132
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
133
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
134
|
+
],
|
|
135
|
+
overridePinnedVersion: '>=4.0.0',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
version: '4.42.0',
|
|
139
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '>=10.0.9' } }],
|
|
140
|
+
},
|
|
141
|
+
{ version: '4.41.2', conditions: [] },
|
|
142
|
+
{
|
|
143
|
+
version: '3.9.2',
|
|
144
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
const { version } = await getExpectedVersion({
|
|
148
|
+
versions,
|
|
149
|
+
nodeVersion: '18.19.0',
|
|
150
|
+
packageJson: { dependencies: { next: '14.1.1-canary.36' } },
|
|
151
|
+
buildDir: '/some/path',
|
|
152
|
+
pinnedVersion: '4',
|
|
153
|
+
systemLog: noopSystemLog,
|
|
154
|
+
});
|
|
155
|
+
expect(version).toBe('5.0.0-beta.1');
|
|
96
156
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
157
|
+
test('should retrieve the plugin based on conditions and feature flag due to pinned version', async () => {
|
|
158
|
+
const versions = [
|
|
159
|
+
{
|
|
160
|
+
version: '5.0.0-beta.1',
|
|
161
|
+
conditions: [
|
|
162
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
163
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
164
|
+
],
|
|
165
|
+
overridePinnedVersion: '>=4.0.0',
|
|
166
|
+
},
|
|
167
|
+
{ version: '4.41.2', conditions: [] },
|
|
168
|
+
{
|
|
169
|
+
version: '3.9.2',
|
|
170
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
const { version: version1 } = await getExpectedVersion({
|
|
174
|
+
versions,
|
|
175
|
+
nodeVersion: '20.0.0',
|
|
176
|
+
packageJson: { dependencies: { next: '14.0.0' } },
|
|
177
|
+
buildDir: '/some/path',
|
|
178
|
+
pinnedVersion: '4',
|
|
179
|
+
systemLog: noopSystemLog,
|
|
180
|
+
});
|
|
181
|
+
expect(version1).toBe('5.0.0-beta.1');
|
|
182
|
+
// out of range
|
|
183
|
+
const { version: version2 } = await getExpectedVersion({
|
|
184
|
+
versions,
|
|
185
|
+
nodeVersion: '20.0.0',
|
|
186
|
+
packageJson: { dependencies: { next: '13.0.0' } },
|
|
187
|
+
buildDir: '/some/path',
|
|
188
|
+
pinnedVersion: '4',
|
|
189
|
+
systemLog: noopSystemLog,
|
|
190
|
+
});
|
|
191
|
+
expect(version2).toBe('4.41.2');
|
|
104
192
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
193
|
+
test('matches the first entry that satisfies the constraints, even if it also matches another entry further down with more specific constraints', async () => {
|
|
194
|
+
const versions = [
|
|
195
|
+
{ version: '4.41.2', conditions: [] },
|
|
196
|
+
{
|
|
197
|
+
version: '5.0.0-beta.1',
|
|
198
|
+
conditions: [
|
|
199
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
200
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
201
|
+
],
|
|
202
|
+
overridePinnedVersion: '>=4.0.0',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
version: '3.9.2',
|
|
206
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
const { version } = await getExpectedVersion({
|
|
210
|
+
versions,
|
|
211
|
+
nodeVersion: '20.0.0',
|
|
212
|
+
packageJson: { dependencies: { next: '14.0.0' } },
|
|
213
|
+
buildDir: '/some/path',
|
|
214
|
+
pinnedVersion: '4',
|
|
215
|
+
systemLog: noopSystemLog,
|
|
216
|
+
});
|
|
217
|
+
expect(version).toBe('4.41.2');
|
|
112
218
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
expect(version).toBe('5.0.0-beta.1');
|
|
143
|
-
});
|
|
144
|
-
test('`getExpectedVersion` should retrieve the plugin based on conditions and feature flag due to pinned version', async () => {
|
|
145
|
-
const versions = [
|
|
146
|
-
{
|
|
147
|
-
version: '5.0.0-beta.1',
|
|
148
|
-
conditions: [
|
|
149
|
-
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
150
|
-
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
151
|
-
],
|
|
152
|
-
overridePinnedVersion: '>=4.0.0',
|
|
153
|
-
},
|
|
154
|
-
{ version: '4.41.2', conditions: [] },
|
|
155
|
-
{
|
|
156
|
-
version: '3.9.2',
|
|
157
|
-
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
158
|
-
},
|
|
159
|
-
];
|
|
160
|
-
const { version: version1 } = await getExpectedVersion({
|
|
161
|
-
versions,
|
|
162
|
-
nodeVersion: '20.0.0',
|
|
163
|
-
packageJson: { dependencies: { next: '14.0.0' } },
|
|
164
|
-
buildDir: '/some/path',
|
|
165
|
-
pinnedVersion: '4',
|
|
219
|
+
test('if no pinned version is set, it matches the first version regardless of whether its requirements match the conditions (legacy behavior)', async () => {
|
|
220
|
+
const versions = [
|
|
221
|
+
{
|
|
222
|
+
version: '5.0.0-beta.1',
|
|
223
|
+
conditions: [
|
|
224
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
225
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
226
|
+
],
|
|
227
|
+
overridePinnedVersion: '>=4.0.0',
|
|
228
|
+
},
|
|
229
|
+
{ version: '4.41.2', conditions: [] },
|
|
230
|
+
{
|
|
231
|
+
version: '3.9.2',
|
|
232
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
233
|
+
},
|
|
234
|
+
];
|
|
235
|
+
const logMessages = [];
|
|
236
|
+
const { version } = await getExpectedVersion({
|
|
237
|
+
versions,
|
|
238
|
+
nodeVersion: '20.0.0',
|
|
239
|
+
packageJson: { name: '@netlify/a-cool-plugin', dependencies: { next: '12.0.0' } },
|
|
240
|
+
buildDir: '/some/path',
|
|
241
|
+
systemLog: (message) => {
|
|
242
|
+
logMessages.push(message);
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
expect(logMessages.length).toBe(1);
|
|
246
|
+
expect(logMessages[0]).toBe(`Detected mismatch in selected version for plugin '@netlify/a-cool-plugin': used legacy version '5.0.0-beta.1' over new version '4.41.2'`);
|
|
247
|
+
expect(version).toBe('5.0.0-beta.1');
|
|
166
248
|
});
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
249
|
+
test('if no pinned version is set, it matches the first version whose requirements match the conditions', async () => {
|
|
250
|
+
const versions = [
|
|
251
|
+
{
|
|
252
|
+
version: '5.0.0-beta.1',
|
|
253
|
+
conditions: [
|
|
254
|
+
{ type: 'nodeVersion', condition: '>= 18.0.0' },
|
|
255
|
+
{ type: 'siteDependencies', condition: { next: '>=13.5.0' } },
|
|
256
|
+
],
|
|
257
|
+
overridePinnedVersion: '>=4.0.0',
|
|
258
|
+
},
|
|
259
|
+
{ version: '4.41.2', conditions: [] },
|
|
260
|
+
{
|
|
261
|
+
version: '3.9.2',
|
|
262
|
+
conditions: [{ type: 'siteDependencies', condition: { next: '<10.0.9' } }],
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
const logMessages = [];
|
|
266
|
+
const { version } = await getExpectedVersion({
|
|
267
|
+
versions,
|
|
268
|
+
nodeVersion: '20.0.0',
|
|
269
|
+
packageJson: { name: '@netlify/a-cool-plugin', dependencies: { next: '12.0.0' } },
|
|
270
|
+
buildDir: '/some/path',
|
|
271
|
+
systemLog: (message) => {
|
|
272
|
+
logMessages.push(message);
|
|
273
|
+
},
|
|
274
|
+
featureFlags: {
|
|
275
|
+
netlify_build_updated_plugin_compatibility: true,
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
expect(logMessages.length).toBe(1);
|
|
279
|
+
expect(logMessages[0]).toBe(`Detected mismatch in selected version for plugin '@netlify/a-cool-plugin': used new version of '4.41.2' over legacy version '5.0.0-beta.1'`);
|
|
280
|
+
expect(version).toBe('4.41.2');
|
|
175
281
|
});
|
|
176
|
-
expect(version2).toBe('4.41.2');
|
|
177
282
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const addExpectedVersions: ({ pluginsOptions, autoPluginsDir, packageJson, packagePath, debug, logs, buildDir, testOpts, featureFlags, }: {
|
|
1
|
+
export declare const addExpectedVersions: ({ pluginsOptions, autoPluginsDir, packageJson, packagePath, debug, logs, buildDir, testOpts, featureFlags, systemLog, }: {
|
|
2
2
|
pluginsOptions: any;
|
|
3
3
|
autoPluginsDir: any;
|
|
4
4
|
packageJson: any;
|
|
@@ -8,4 +8,5 @@ export declare const addExpectedVersions: ({ pluginsOptions, autoPluginsDir, pac
|
|
|
8
8
|
buildDir: any;
|
|
9
9
|
testOpts: any;
|
|
10
10
|
featureFlags: any;
|
|
11
|
+
systemLog: any;
|
|
11
12
|
}) => Promise<any>;
|
|
@@ -7,7 +7,7 @@ import { getPluginsList } from './list.js';
|
|
|
7
7
|
// When using plugins in our official list, those are installed in .netlify/plugins/
|
|
8
8
|
// We ensure that the last version that's been approved is always the one being used.
|
|
9
9
|
// We also ensure that the plugin is our official list.
|
|
10
|
-
export const addExpectedVersions = async function ({ pluginsOptions, autoPluginsDir, packageJson, packagePath, debug, logs, buildDir, testOpts, featureFlags, }) {
|
|
10
|
+
export const addExpectedVersions = async function ({ pluginsOptions, autoPluginsDir, packageJson, packagePath, debug, logs, buildDir, testOpts, featureFlags, systemLog, }) {
|
|
11
11
|
if (!pluginsOptions.some(needsExpectedVersion)) {
|
|
12
12
|
return pluginsOptions;
|
|
13
13
|
}
|
|
@@ -21,10 +21,11 @@ export const addExpectedVersions = async function ({ pluginsOptions, autoPlugins
|
|
|
21
21
|
buildDir,
|
|
22
22
|
featureFlags,
|
|
23
23
|
testOpts,
|
|
24
|
+
systemLog,
|
|
24
25
|
})));
|
|
25
26
|
};
|
|
26
27
|
/** Any `pluginOptions` with `expectedVersion` set will be automatically installed */
|
|
27
|
-
const addExpectedVersion = async function ({ pluginsList, autoPluginsDir, packageJson, packagePath, pluginOptions, pluginOptions: { packageName, pluginPath, loadedFrom, nodeVersion, pinnedVersion }, buildDir, featureFlags, testOpts, }) {
|
|
28
|
+
const addExpectedVersion = async function ({ pluginsList, autoPluginsDir, packageJson, packagePath, pluginOptions, pluginOptions: { packageName, pluginPath, loadedFrom, nodeVersion, pinnedVersion }, buildDir, featureFlags, testOpts, systemLog, }) {
|
|
28
29
|
if (!needsExpectedVersion(pluginOptions)) {
|
|
29
30
|
return pluginOptions;
|
|
30
31
|
}
|
|
@@ -36,8 +37,17 @@ const addExpectedVersion = async function ({ pluginsList, autoPluginsDir, packag
|
|
|
36
37
|
const versions = filterVersions(unfilteredVersions, featureFlags);
|
|
37
38
|
const [{ version: latestVersion, migrationGuide }] = versions;
|
|
38
39
|
const [{ version: expectedVersion }, { version: compatibleVersion, compatWarning }] = await Promise.all([
|
|
39
|
-
getExpectedVersion({
|
|
40
|
-
|
|
40
|
+
getExpectedVersion({
|
|
41
|
+
versions,
|
|
42
|
+
nodeVersion,
|
|
43
|
+
packageJson,
|
|
44
|
+
packagePath,
|
|
45
|
+
buildDir,
|
|
46
|
+
pinnedVersion,
|
|
47
|
+
featureFlags,
|
|
48
|
+
systemLog,
|
|
49
|
+
}),
|
|
50
|
+
getExpectedVersion({ versions, nodeVersion, packageJson, packagePath, buildDir, featureFlags, systemLog }),
|
|
41
51
|
]);
|
|
42
52
|
const isMissing = await isMissingVersion({ autoPluginsDir, packageName, pluginPath, loadedFrom, expectedVersion });
|
|
43
53
|
return {
|
package/lib/plugins/resolve.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/build",
|
|
3
|
-
"version": "29.38.
|
|
3
|
+
"version": "29.38.2",
|
|
4
4
|
"description": "Netlify build module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./lib/index.js",
|
|
@@ -68,17 +68,17 @@
|
|
|
68
68
|
"license": "MIT",
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@bugsnag/js": "^7.0.0",
|
|
71
|
-
"@netlify/blobs": "^7.
|
|
71
|
+
"@netlify/blobs": "^7.3.0",
|
|
72
72
|
"@netlify/cache-utils": "^5.1.5",
|
|
73
73
|
"@netlify/config": "^20.12.1",
|
|
74
74
|
"@netlify/edge-bundler": "11.3.0",
|
|
75
75
|
"@netlify/framework-info": "^9.8.11",
|
|
76
|
-
"@netlify/functions-utils": "^5.2.
|
|
76
|
+
"@netlify/functions-utils": "^5.2.53",
|
|
77
77
|
"@netlify/git-utils": "^5.1.1",
|
|
78
78
|
"@netlify/opentelemetry-utils": "^1.1.0",
|
|
79
79
|
"@netlify/plugins-list": "^6.77.0",
|
|
80
80
|
"@netlify/run-utils": "^5.1.1",
|
|
81
|
-
"@netlify/zip-it-and-ship-it": "9.
|
|
81
|
+
"@netlify/zip-it-and-ship-it": "9.31.1",
|
|
82
82
|
"@sindresorhus/slugify": "^2.0.0",
|
|
83
83
|
"ansi-escapes": "^6.0.0",
|
|
84
84
|
"chalk": "^5.0.0",
|
|
@@ -164,5 +164,5 @@
|
|
|
164
164
|
"engines": {
|
|
165
165
|
"node": "^14.16.0 || >=16.0.0"
|
|
166
166
|
},
|
|
167
|
-
"gitHead": "
|
|
167
|
+
"gitHead": "f172805567a263a78956981106526411a9050644"
|
|
168
168
|
}
|