Skip to content
Snippets Groups Projects
Unverified Commit 16bd0638 authored by Rhys Arkins's avatar Rhys Arkins Committed by GitHub
Browse files

fix: respect latest when selecting tool versions (#15481)

parent cdc359c0
No related branches found
No related tags found
No related merge requests found
...@@ -48,13 +48,14 @@ describe('util/exec/buildpack', () => { ...@@ -48,13 +48,14 @@ describe('util/exec/buildpack', () => {
describe('resolveConstraint()', () => { describe('resolveConstraint()', () => {
beforeEach(() => { beforeEach(() => {
datasource.getPkgReleases.mockResolvedValueOnce({ datasource.getPkgReleases.mockResolvedValue({
releases: [ releases: [
{ version: '1.0.0' }, { version: '1.0.0' },
{ version: '1.1.0' }, { version: '1.1.0' },
{ version: '1.3.0' }, { version: '1.3.0' },
{ version: '2.0.14' }, { version: '2.0.14' },
{ version: '2.1.0' }, { version: '2.1.0' },
{ version: '2.2.0-pre.0' },
], ],
}); });
}); });
...@@ -65,10 +66,36 @@ describe('util/exec/buildpack', () => { ...@@ -65,10 +66,36 @@ describe('util/exec/buildpack', () => {
).toBe('1.1.0'); ).toBe('1.1.0');
}); });
it('returns from latest', async () => { it('returns highest stable', async () => {
expect(await resolveConstraint({ toolName: 'composer' })).toBe('2.1.0'); expect(await resolveConstraint({ toolName: 'composer' })).toBe('2.1.0');
}); });
it('returns highest unstable', async () => {
datasource.getPkgReleases.mockResolvedValue({
releases: [{ version: '2.0.14-b.1' }, { version: '2.1.0-a.1' }],
});
expect(await resolveConstraint({ toolName: 'composer' })).toBe(
'2.1.0-a.1'
);
});
it('respects latest', async () => {
datasource.getPkgReleases.mockResolvedValue({
tags: {
latest: '2.0.14',
},
releases: [
{ version: '1.0.0' },
{ version: '1.1.0' },
{ version: '1.3.0' },
{ version: '2.0.14' },
{ version: '2.1.0' },
{ version: '2.2.0-pre.0' },
],
});
expect(await resolveConstraint({ toolName: 'composer' })).toBe('2.0.14');
});
it('throws for unknown tools', async () => { it('throws for unknown tools', async () => {
datasource.getPkgReleases.mockReset(); datasource.getPkgReleases.mockReset();
datasource.getPkgReleases.mockResolvedValueOnce({ datasource.getPkgReleases.mockResolvedValueOnce({
......
import is from '@sindresorhus/is';
import { quote } from 'shlex'; import { quote } from 'shlex';
import { GlobalConfig } from '../../config/global'; import { GlobalConfig } from '../../config/global';
import { logger } from '../../logger'; import { logger } from '../../logger';
...@@ -100,6 +101,22 @@ export function isDynamicInstall( ...@@ -100,6 +101,22 @@ export function isDynamicInstall(
); );
} }
function isStable(
version: string,
versioning: allVersioning.VersioningApi,
latest?: string
): boolean {
if (!versioning.isStable(version)) {
return false;
}
if (is.string(latest)) {
if (versioning.isGreaterThan(version, latest)) {
return false;
}
}
return true;
}
export async function resolveConstraint( export async function resolveConstraint(
toolConstraint: ToolConstraint toolConstraint: ToolConstraint
): Promise<string> { ): Promise<string> {
...@@ -124,27 +141,51 @@ export async function resolveConstraint( ...@@ -124,27 +141,51 @@ export async function resolveConstraint(
const pkgReleases = await getPkgReleases(toolConfig); const pkgReleases = await getPkgReleases(toolConfig);
const releases = pkgReleases?.releases ?? []; const releases = pkgReleases?.releases ?? [];
const versions = releases.map((r) => r.version);
const resolvedVersion = versions
.filter((v) =>
constraint ? versioning.matches(v, constraint) : versioning.isStable(v)
)
.pop();
if (resolvedVersion) { if (!releases?.length) {
logger.debug({ toolName, constraint, resolvedVersion }, 'Resolved version'); throw new Error('No tool releases found.');
return resolvedVersion;
} }
const latestVersion = versions.filter((v) => versioning.isStable(v)).pop(); const matchingReleases = releases.filter(
if (!latestVersion) { (r) => !constraint || versioning.matches(r.version, constraint)
throw new Error('No tool releases found.'); );
const stableMatchingVersion = matchingReleases
.filter((r) => isStable(r.version, versioning, pkgReleases?.tags?.latest))
.pop()?.version;
if (stableMatchingVersion) {
logger.debug(
{ toolName, constraint, resolvedVersion: stableMatchingVersion },
'Resolved stable matching version'
);
return stableMatchingVersion;
}
const unstableMatchingVersion = matchingReleases.pop()?.version;
if (unstableMatchingVersion) {
logger.debug(
{ toolName, constraint, resolvedVersion: unstableMatchingVersion },
'Resolved unstable matching version'
);
return unstableMatchingVersion;
} }
const stableVersion = releases
.filter((r) => isStable(r.version, versioning, pkgReleases?.tags?.latest))
.pop()?.version;
if (stableVersion) {
logger.warn(
{ toolName, constraint, stableVersion },
'No matching tool versions found for constraint - using latest stable version'
);
}
const highestVersion = releases.pop()!.version;
logger.warn( logger.warn(
{ toolName, constraint, latestVersion }, { toolName, constraint, highestVersion },
'No matching tool versions found for constraint - using latest version' 'No matching or stable tool versions found - using an unstable version'
); );
return latestVersion; return highestVersion;
} }
export async function generateInstallCommands( export async function generateInstallCommands(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment