mirror of
https://github.com/actions/setup-dotnet.git
synced 2026-09-30 02:00:38 +00:00
Add check-latest input to reuse a locally installed .NET SDK and skip network calls (#774)
* check-latest-input feature implemented * e2e test update * e2e-tests.yml updated * update documentation * fix: align local SDK matching with the online resolver * implement review comments * implement review comments * implement review comments * implement review comments * implement review comments * implement review comments * implement review comments --------- Co-authored-by: mahabaleshwars <147705296+mahabaleshwars@users.noreply.github.com>
This commit is contained in:
@@ -66,6 +66,7 @@ describe('setup-dotnet tests', () => {
|
||||
const setOutputSpy = core.setOutput as jest.Mock;
|
||||
|
||||
const existsSyncSpy = fs.existsSync as jest.Mock;
|
||||
const readFileSyncSpy = fs.readFileSync as jest.Mock;
|
||||
|
||||
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
||||
|
||||
@@ -85,11 +86,17 @@ describe('setup-dotnet tests', () => {
|
||||
DotnetInstallDir.addToPath = jest.fn();
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
getInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
getBooleanInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
getBooleanInputSpy.mockImplementation(input => {
|
||||
const value = inputs[input as string];
|
||||
return typeof value === 'string'
|
||||
? value.toLowerCase() === 'true'
|
||||
: !!value;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
DotnetInstallDir.addToPath = addToPathOriginal;
|
||||
delete process.env['DOTNET_CHECK_LATEST'];
|
||||
jest.clearAllMocks();
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
@@ -289,6 +296,77 @@ describe('setup-dotnet tests', () => {
|
||||
expect(DotnetInstallDir.addToPath).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should read the 'check-latest' input and pass it to DotnetCoreInstaller", async () => {
|
||||
inputs['dotnet-version'] = ['10.0.101'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
|
||||
let capturedCheckLatest: boolean | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedCheckLatest = this.checkLatest;
|
||||
return Promise.resolve('');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
|
||||
expect(getBooleanInputSpy).toHaveBeenCalledWith('check-latest');
|
||||
expect(installDotnetSpy).toHaveBeenCalledTimes(1);
|
||||
expect(capturedCheckLatest).toBe(false);
|
||||
});
|
||||
|
||||
describe("'check-latest' resolution", () => {
|
||||
const captureCheckLatest = async () => {
|
||||
inputs['dotnet-version'] = ['10.0.101'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['architecture'] = '';
|
||||
|
||||
let capturedCheckLatest: boolean | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedCheckLatest = this.checkLatest;
|
||||
return Promise.resolve('');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
return capturedCheckLatest;
|
||||
};
|
||||
|
||||
it('defaults to true when neither the input nor the environment variable is set', async () => {
|
||||
inputs['check-latest'] = '';
|
||||
|
||||
expect(await captureCheckLatest()).toBe(true);
|
||||
expect(getBooleanInputSpy).not.toHaveBeenCalledWith('check-latest');
|
||||
});
|
||||
|
||||
it.each(['false', 'FALSE', 'False'])(
|
||||
"reads 'check-latest' from the DOTNET_CHECK_LATEST environment variable ('%s')",
|
||||
async envValue => {
|
||||
inputs['check-latest'] = '';
|
||||
process.env['DOTNET_CHECK_LATEST'] = envValue;
|
||||
|
||||
expect(await captureCheckLatest()).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
it('lets an explicit input win over the environment variable', async () => {
|
||||
inputs['check-latest'] = 'true';
|
||||
process.env['DOTNET_CHECK_LATEST'] = 'false';
|
||||
|
||||
expect(await captureCheckLatest()).toBe(true);
|
||||
});
|
||||
|
||||
it('warns and falls back to true when the environment variable is not a boolean', async () => {
|
||||
inputs['check-latest'] = '';
|
||||
process.env['DOTNET_CHECK_LATEST'] = 'yes';
|
||||
|
||||
expect(await captureCheckLatest()).toBe(true);
|
||||
expect(warningSpy).toHaveBeenCalledWith(
|
||||
`Value 'yes' is not supported for the DOTNET_CHECK_LATEST environment variable. Supported values are: true, false. The 'check-latest' option falls back to 'true'.`
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail the action if unsupported architecture is provided', async () => {
|
||||
inputs['dotnet-version'] = ['10.0.101'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
@@ -389,5 +467,241 @@ describe('setup-dotnet tests', () => {
|
||||
`The 'dotnet-channel' input is only supported when 'dotnet-version' is set to 'latest'.`
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass the global.json rollForward minimum version to DotnetCoreInstaller', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({
|
||||
sdk: {version: '8.0.400', rollForward: 'latestFeature'}
|
||||
})
|
||||
);
|
||||
|
||||
let capturedVersion: string | undefined;
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedVersion = this.version;
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
return Promise.resolve('8.0.412');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedVersion).toBe('8.0');
|
||||
expect(capturedMinimumVersion).toBe('8.0.400');
|
||||
});
|
||||
|
||||
it('should pass non-latest rollForward policies to DotnetCoreInstaller', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.100', rollForward: 'feature'}})
|
||||
);
|
||||
|
||||
let capturedVersion: string | undefined;
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedVersion = this.version;
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.200');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedVersion).toBe('8.0.100');
|
||||
expect(capturedMinimumVersion).toBe('8.0.100');
|
||||
expect(capturedRollForward).toBe('feature');
|
||||
});
|
||||
|
||||
it('should default an omitted rollForward to patch', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.100'}})
|
||||
);
|
||||
|
||||
let capturedVersion: string | undefined;
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedVersion = this.version;
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.100');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedVersion).toBe('8.0.100');
|
||||
expect(capturedMinimumVersion).toBe('8.0.100');
|
||||
expect(capturedRollForward).toBe('patch');
|
||||
});
|
||||
|
||||
it('should not default to patch for a prerelease sdk version', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.100-preview.1'}})
|
||||
);
|
||||
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.100-preview.1');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedMinimumVersion).toBeUndefined();
|
||||
expect(capturedRollForward).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not default to patch for a version that is not a full SDK version', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.0'}})
|
||||
);
|
||||
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.0');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedMinimumVersion).toBeUndefined();
|
||||
expect(capturedRollForward).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not roll forward a version pinned by the dotnet-version input', async () => {
|
||||
inputs['dotnet-version'] = ['8.0.100'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.100'}})
|
||||
);
|
||||
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.100');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(installDotnetSpy).toHaveBeenCalledTimes(1);
|
||||
expect(capturedMinimumVersion).toBeUndefined();
|
||||
expect(capturedRollForward).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should keep the global.json floor when a floating dotnet-version matches', async () => {
|
||||
inputs['dotnet-version'] = ['8.0'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({
|
||||
sdk: {version: '8.0.400', rollForward: 'latestFeature'}
|
||||
})
|
||||
);
|
||||
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.400');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(installDotnetSpy).toHaveBeenCalledTimes(1);
|
||||
expect(capturedMinimumVersion).toBe('8.0.400');
|
||||
expect(capturedRollForward).toBe('latestFeature');
|
||||
});
|
||||
|
||||
it('should not set a rollForward policy for disable', async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['dotnet-channel'] = '';
|
||||
inputs['architecture'] = '';
|
||||
inputs['check-latest'] = 'false';
|
||||
inputs['global-json-file'] = 'global.json';
|
||||
|
||||
existsSyncSpy.mockReturnValue(true);
|
||||
readFileSyncSpy.mockReturnValue(
|
||||
JSON.stringify({sdk: {version: '8.0.100', rollForward: 'disable'}})
|
||||
);
|
||||
|
||||
let capturedMinimumVersion: string | undefined;
|
||||
let capturedRollForward: string | undefined;
|
||||
installDotnetSpy.mockImplementation(function (this: any) {
|
||||
capturedMinimumVersion = this.minimumVersion;
|
||||
capturedRollForward = this.rollForward;
|
||||
return Promise.resolve('8.0.100');
|
||||
});
|
||||
|
||||
await setup.run();
|
||||
inputs['global-json-file'] = '';
|
||||
|
||||
expect(capturedMinimumVersion).toBeUndefined();
|
||||
expect(capturedRollForward).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user