Skip to content

Commit 60edb5d

Browse files
dmitry-shibanovaparnajyothi-y
andauthoredFeb 7, 2024
Add support for arm64 Windows (#927)
* add support for arm64 Windows * revert 7z to exe * add comment --------- Co-authored-by: aparnajyothi-y <147696841+aparnajyothi-y@users.noreply.github.com>
1 parent d86ebcd commit 60edb5d

File tree

6 files changed

+75
-14
lines changed

6 files changed

+75
-14
lines changed
 

‎__tests__/main.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as core from '@actions/core';
22
import * as exec from '@actions/exec';
33
import * as tc from '@actions/tool-cache';
44
import * as cache from '@actions/cache';
5+
import * as io from '@actions/io';
56

67
import fs from 'fs';
78
import path from 'path';
@@ -24,6 +25,10 @@ describe('main tests', () => {
2425
let startGroupSpy: jest.SpyInstance;
2526
let endGroupSpy: jest.SpyInstance;
2627

28+
let whichSpy: jest.SpyInstance;
29+
30+
let existsSpy: jest.SpyInstance;
31+
2732
let getExecOutputSpy: jest.SpyInstance;
2833

2934
let getNodeVersionFromFileSpy: jest.SpyInstance;
@@ -55,6 +60,8 @@ describe('main tests', () => {
5560
inSpy = jest.spyOn(core, 'getInput');
5661
inSpy.mockImplementation(name => inputs[name]);
5762

63+
whichSpy = jest.spyOn(io, 'which');
64+
5865
getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
5966

6067
findSpy = jest.spyOn(tc, 'find');
@@ -140,6 +147,10 @@ describe('main tests', () => {
140147
return {stdout: obj[command], stderr: '', exitCode: 0};
141148
});
142149

150+
whichSpy.mockImplementation(cmd => {
151+
return `some/${cmd}/path`;
152+
});
153+
143154
await util.printEnvDetailsAndSetOutput();
144155

145156
expect(setOutputSpy).toHaveBeenCalledWith('node-version', obj['node']);

‎__tests__/official-installer.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ describe('setup-node', () => {
248248
const toolPath = path.normalize('/cache/node/12.16.2/x64');
249249
exSpy.mockImplementation(async () => '/some/other/temp/path');
250250
cacheSpy.mockImplementation(async () => toolPath);
251+
whichSpy.mockImplementation(cmd => {
252+
return `some/${cmd}/path`;
253+
});
251254

252255
await main.run();
253256

‎dist/cache-save/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -83336,6 +83336,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
8333683336
exports.unique = exports.printEnvDetailsAndSetOutput = exports.getNodeVersionFromFile = void 0;
8333783337
const core = __importStar(__nccwpck_require__(2186));
8333883338
const exec = __importStar(__nccwpck_require__(1514));
83339+
const io = __importStar(__nccwpck_require__(7436));
8333983340
const fs_1 = __importDefault(__nccwpck_require__(7147));
8334083341
const path_1 = __importDefault(__nccwpck_require__(1017));
8334183342
function getNodeVersionFromFile(versionFilePath) {
@@ -83387,7 +83388,8 @@ function printEnvDetailsAndSetOutput() {
8338783388
return __awaiter(this, void 0, void 0, function* () {
8338883389
core.startGroup('Environment details');
8338983390
const promises = ['node', 'npm', 'yarn'].map((tool) => __awaiter(this, void 0, void 0, function* () {
83390-
const output = yield getToolVersion(tool, ['--version']);
83391+
const pathTool = yield io.which(tool, false);
83392+
const output = pathTool ? yield getToolVersion(tool, ['--version']) : '';
8339183393
return { tool, output };
8339283394
}));
8339383395
const tools = yield Promise.all(promises);

‎dist/setup/index.js

+30-6
Original file line numberDiff line numberDiff line change
@@ -93110,7 +93110,11 @@ class BaseDistribution {
9311093110
const fileName = this.osPlat == 'win32'
9311193111
? `node-v${version}-win-${osArch}`
9311293112
: `node-v${version}-${this.osPlat}-${osArch}`;
93113-
const urlFileName = this.osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`;
93113+
const urlFileName = this.osPlat == 'win32'
93114+
? this.nodeInfo.arch === 'arm64'
93115+
? `${fileName}.zip`
93116+
: `${fileName}.7z`
93117+
: `${fileName}.tar.gz`;
9311493118
const initialUrl = this.getDistributionUrl();
9311593119
const url = `${initialUrl}/v${version}/${urlFileName}`;
9311693120
return {
@@ -93194,10 +93198,23 @@ class BaseDistribution {
9319493198
let extPath;
9319593199
info = info || {}; // satisfy compiler, never null when reaches here
9319693200
if (this.osPlat == 'win32') {
93197-
const _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
93198-
extPath = yield tc.extract7z(downloadPath, undefined, _7zPath);
93201+
const extension = this.nodeInfo.arch === 'arm64' ? '.zip' : '.7z';
93202+
// Rename archive to add extension because after downloading
93203+
// archive does not contain extension type and it leads to some issues
93204+
// on Windows runners without PowerShell Core.
93205+
//
93206+
// For default PowerShell Windows it should contain extension type to unpack it.
93207+
if (extension === '.zip') {
93208+
const renamedArchive = `${downloadPath}.zip`;
93209+
fs_1.default.renameSync(downloadPath, renamedArchive);
93210+
extPath = yield tc.extractZip(renamedArchive);
93211+
}
93212+
else {
93213+
const _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
93214+
extPath = yield tc.extract7z(downloadPath, undefined, _7zPath);
93215+
}
9319993216
// 7z extracts to folder matching file name
93200-
const nestedPath = path.join(extPath, path.basename(info.fileName, '.7z'));
93217+
const nestedPath = path.join(extPath, path.basename(info.fileName, extension));
9320193218
if (fs_1.default.existsSync(nestedPath)) {
9320293219
extPath = nestedPath;
9320393220
}
@@ -93229,7 +93246,12 @@ class BaseDistribution {
9322993246
dataFileName = `osx-${osArch}-tar`;
9323093247
break;
9323193248
case 'win32':
93232-
dataFileName = `win-${osArch}-exe`;
93249+
if (this.nodeInfo.arch === 'arm64') {
93250+
dataFileName = `win-${osArch}-zip`;
93251+
}
93252+
else {
93253+
dataFileName = `win-${osArch}-exe`;
93254+
}
9323393255
break;
9323493256
default:
9323593257
throw new Error(`Unexpected OS '${this.osPlat}'`);
@@ -93783,6 +93805,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
9378393805
exports.unique = exports.printEnvDetailsAndSetOutput = exports.getNodeVersionFromFile = void 0;
9378493806
const core = __importStar(__nccwpck_require__(2186));
9378593807
const exec = __importStar(__nccwpck_require__(1514));
93808+
const io = __importStar(__nccwpck_require__(7436));
9378693809
const fs_1 = __importDefault(__nccwpck_require__(7147));
9378793810
const path_1 = __importDefault(__nccwpck_require__(1017));
9378893811
function getNodeVersionFromFile(versionFilePath) {
@@ -93834,7 +93857,8 @@ function printEnvDetailsAndSetOutput() {
9383493857
return __awaiter(this, void 0, void 0, function* () {
9383593858
core.startGroup('Environment details');
9383693859
const promises = ['node', 'npm', 'yarn'].map((tool) => __awaiter(this, void 0, void 0, function* () {
93837-
const output = yield getToolVersion(tool, ['--version']);
93860+
const pathTool = yield io.which(tool, false);
93861+
const output = pathTool ? yield getToolVersion(tool, ['--version']) : '';
9383893862
return { tool, output };
9383993863
}));
9384093864
const tools = yield Promise.all(promises);

‎src/distributions/base-distribution.ts

+25-5
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ export default abstract class BaseDistribution {
112112
? `node-v${version}-win-${osArch}`
113113
: `node-v${version}-${this.osPlat}-${osArch}`;
114114
const urlFileName: string =
115-
this.osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`;
115+
this.osPlat == 'win32'
116+
? this.nodeInfo.arch === 'arm64'
117+
? `${fileName}.zip`
118+
: `${fileName}.7z`
119+
: `${fileName}.tar.gz`;
116120
const initialUrl = this.getDistributionUrl();
117121
const url = `${initialUrl}/v${version}/${urlFileName}`;
118122

@@ -215,12 +219,24 @@ export default abstract class BaseDistribution {
215219
let extPath: string;
216220
info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
217221
if (this.osPlat == 'win32') {
218-
const _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
219-
extPath = await tc.extract7z(downloadPath, undefined, _7zPath);
222+
const extension = this.nodeInfo.arch === 'arm64' ? '.zip' : '.7z';
223+
// Rename archive to add extension because after downloading
224+
// archive does not contain extension type and it leads to some issues
225+
// on Windows runners without PowerShell Core.
226+
//
227+
// For default PowerShell Windows it should contain extension type to unpack it.
228+
if (extension === '.zip') {
229+
const renamedArchive = `${downloadPath}.zip`;
230+
fs.renameSync(downloadPath, renamedArchive);
231+
extPath = await tc.extractZip(renamedArchive);
232+
} else {
233+
const _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
234+
extPath = await tc.extract7z(downloadPath, undefined, _7zPath);
235+
}
220236
// 7z extracts to folder matching file name
221237
const nestedPath = path.join(
222238
extPath,
223-
path.basename(info.fileName, '.7z')
239+
path.basename(info.fileName, extension)
224240
);
225241
if (fs.existsSync(nestedPath)) {
226242
extPath = nestedPath;
@@ -260,7 +276,11 @@ export default abstract class BaseDistribution {
260276
dataFileName = `osx-${osArch}-tar`;
261277
break;
262278
case 'win32':
263-
dataFileName = `win-${osArch}-exe`;
279+
if (this.nodeInfo.arch === 'arm64') {
280+
dataFileName = `win-${osArch}-zip`;
281+
} else {
282+
dataFileName = `win-${osArch}-exe`;
283+
}
264284
break;
265285
default:
266286
throw new Error(`Unexpected OS '${this.osPlat}'`);

‎src/util.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as core from '@actions/core';
22
import * as exec from '@actions/exec';
3+
import * as io from '@actions/io';
34

45
import fs from 'fs';
56
import path from 'path';
@@ -61,9 +62,9 @@ export function getNodeVersionFromFile(versionFilePath: string): string | null {
6162

6263
export async function printEnvDetailsAndSetOutput() {
6364
core.startGroup('Environment details');
64-
6565
const promises = ['node', 'npm', 'yarn'].map(async tool => {
66-
const output = await getToolVersion(tool, ['--version']);
66+
const pathTool = await io.which(tool, false);
67+
const output = pathTool ? await getToolVersion(tool, ['--version']) : '';
6768

6869
return {tool, output};
6970
});

0 commit comments

Comments
 (0)
Failed to load comments.