Skip to content

Commit fa81470

Browse files
authored
feat!: new environment verification flag
2 parents fed36ec + bae515b commit fa81470

File tree

7 files changed

+203
-6
lines changed

7 files changed

+203
-6
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This action requires that you set the [`CC_TEST_REPORTER_ID`](https://docs.codec
2020
| `coverageLocations` | | Locations to find code coverage as a multiline string.<br>Each line should be of the form `<location>:<type>`.<br>`type` can be any one of `clover, cobertura, coverage.py, excoveralls, gcov, gocov, jacoco, lcov, lcov-json, simplecov, xccov`. See examples below. |
2121
| `prefix` | `undefined` | See [`--prefix`](https://docs.codeclimate.com/docs/configuring-test-coverage) |
2222
| `verifyDownload` | `true` | Verifies the downloaded Code Climate reporter binary's checksum and GPG signature. See [Verifying binaries](https://github.com/codeclimate/test-reporter#verifying-binaries) |
23+
| `verifyEnvironment` | `true` | Verifies the current runtime environment (operating system and CPU architecture) is supported by the Code Climate reporter. See [list of supported platforms](https://github.com/codeclimate/test-reporter#binaries) |
2324

2425
> **Note**
2526
> If you are a Ruby developer using [SimpleCov](https://github.com/simplecov-ruby/simplecov), other users have recommended installing an additional gem – `gem "simplecov_json_formatter"` – this gem fixes `json` error from the default `coverage/.resultset.json` output from SimpleCov.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@actions/exec": "1.1.1",
3737
"@actions/github": "6.0.0",
3838
"@actions/glob": "0.4.0",
39+
"arch": "3.0.0",
3940
"hook-std": "3.0.0",
4041
"node-fetch": "3.3.2",
4142
"openpgp": "5.11.1"

pnpm-lock.yaml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { unlinkSync } from 'node:fs';
2-
import { arch, platform } from 'node:os';
32
import { resolve } from 'node:path';
43
import { chdir } from 'node:process';
54
import { fileURLToPath } from 'node:url';
@@ -11,6 +10,7 @@ import * as glob from '@actions/glob';
1110
import {
1211
downloadToFile,
1312
getOptionalString,
13+
getSupportedEnvironmentInfo,
1414
parsePathAndFormat,
1515
verifyChecksum,
1616
verifySignature,
@@ -36,14 +36,17 @@ export interface ActionArguments {
3636
coveragePrefix?: string;
3737
/** Verifies the downloaded binary with a Code Climate-provided SHA 256 checksum and GPG sinature. @default true */
3838
verifyDownload?: string;
39+
/** Verifies if the current OS and CPU architecture is supported by CodeClimate test reporter. */
40+
verifyEnvironment?: string;
3941
}
4042

41-
const PLATFORM = platform();
43+
const CURRENT_ENVIRONMENT = getSupportedEnvironmentInfo();
44+
const PLATFORM = CURRENT_ENVIRONMENT.platform;
4245
// REFER: https://docs.codeclimate.com/docs/configuring-test-coverage#locations-of-pre-built-binaries
4346
/** Canonical download URL for the official CodeClimate reporter. */
4447
export const DOWNLOAD_URL = `https://codeclimate.com/downloads/test-reporter/test-reporter-latest-${
4548
PLATFORM === 'win32' ? 'windows' : PLATFORM
46-
}-${arch() === 'arm64' ? 'arm64' : 'amd64'}`;
49+
}-${CURRENT_ENVIRONMENT.architecture === 'arm64' ? 'arm64' : 'amd64'}`;
4750
/** Local file name of the CodeClimate reporter. */
4851
export const EXECUTABLE = './cc-reporter';
4952
export const CODECLIMATE_GPG_PUBLIC_KEY_ID =
@@ -55,6 +58,7 @@ const DEFAULT_WORKING_DIRECTORY = '';
5558
const DEFAULT_CODECLIMATE_DEBUG = 'false';
5659
const DEFAULT_COVERAGE_LOCATIONS = '';
5760
const DEFAULT_VERIFY_DOWNLOAD = 'true';
61+
const DEFAULT_VERIFY_ENVIRONMENT = 'true';
5862

5963
const SUPPORTED_GITHUB_EVENTS = [
6064
// Regular PRs.
@@ -204,10 +208,24 @@ export async function run({
204208
coverageLocationsParam = DEFAULT_COVERAGE_LOCATIONS,
205209
coveragePrefix,
206210
verifyDownload = DEFAULT_VERIFY_DOWNLOAD,
211+
verifyEnvironment = DEFAULT_VERIFY_ENVIRONMENT,
207212
}: ActionArguments = {}): Promise<void> {
208213
let lastExitCode = 1;
214+
if (verifyEnvironment === 'true') {
215+
debug('ℹ️ Verifying environment...');
216+
const { supported, platform, architecture } = getSupportedEnvironmentInfo();
217+
if (!supported) {
218+
const errorMessage = `Unsupported platform and architecture! CodeClimate Test Reporter currently is not available for ${architecture} on ${platform} OS`;
219+
error(errorMessage);
220+
setFailed('🚨 Environment verification failed!');
221+
throw new Error(errorMessage);
222+
}
223+
lastExitCode = 0;
224+
debug('✅ Environment verification completed...');
225+
}
226+
209227
if (workingDirectory) {
210-
debug(`Changing working directory to ${workingDirectory}`);
228+
debug(`ℹ️ Changing working directory to ${workingDirectory}`);
211229
try {
212230
chdir(workingDirectory);
213231
lastExitCode = 0;
@@ -410,6 +428,11 @@ if (isThisFileBeingRunViaCLI) {
410428
'verifyDownload',
411429
DEFAULT_VERIFY_DOWNLOAD,
412430
);
431+
const verifyEnvironment = getOptionalString(
432+
'verifyEnvironment',
433+
DEFAULT_VERIFY_ENVIRONMENT,
434+
);
435+
413436
try {
414437
run({
415438
downloadUrl: DOWNLOAD_URL,
@@ -420,6 +443,7 @@ if (isThisFileBeingRunViaCLI) {
420443
coverageLocationsParam: coverageLocations,
421444
coveragePrefix,
422445
verifyDownload,
446+
verifyEnvironment,
423447
});
424448
} finally {
425449
// Finally clean up all artifacts that we downloaded.

src/utils.ts

+35
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createWriteStream, readFile } from 'node:fs';
33
import { platform } from 'node:os';
44
import { promisify } from 'node:util';
55
import { getInput } from '@actions/core';
6+
import arch from 'arch';
67
import fetch from 'node-fetch';
78
import {
89
type VerificationResult,
@@ -15,6 +16,18 @@ import {
1516
const readFileAsync = promisify(readFile);
1617
type ReadFileAsyncOptions = Omit<Parameters<typeof readFileAsync>[1], 'string'>;
1718

19+
/** List of environments not supported by the CodeClimate test reporter. */
20+
// REFER: https://github.com/codeclimate/test-reporter#download
21+
export const UNSUPPORTED_ENVIRONMENTS: Array<{
22+
platform: ReturnType<typeof platform>;
23+
architecture: ReturnType<typeof arch>;
24+
}> = [
25+
{
26+
platform: 'darwin',
27+
architecture: 'arm64',
28+
},
29+
];
30+
1831
/**
1932
* Parses GitHub Action input and returns the optional value as a string.
2033
*
@@ -249,3 +262,25 @@ export function parsePathAndFormat(coverageConfigLine: string): {
249262
const pattern = lineParts.slice(0, -1)[0] as string;
250263
return { format, pattern };
251264
}
265+
266+
/**
267+
* Reads information about the current operating system and the CPU architecture
268+
* and tells if the CodeClimate test reporter supports it.
269+
*/
270+
export function getSupportedEnvironmentInfo() {
271+
const currentEnvironment = {
272+
platform: platform(),
273+
architecture: arch(),
274+
};
275+
276+
return {
277+
supported: !UNSUPPORTED_ENVIRONMENTS.some((e) => {
278+
return (
279+
e.architecture === currentEnvironment.architecture &&
280+
e.platform === currentEnvironment.platform
281+
);
282+
}),
283+
platform: currentEnvironment.platform,
284+
architecture: currentEnvironment.architecture,
285+
};
286+
}

test/integration.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { unlinkSync } from 'node:fs';
2-
import { EOL, arch, platform } from 'node:os';
2+
import { EOL, platform } from 'node:os';
3+
import arch from 'arch';
34
import { hookStd } from 'hook-std';
45
import t from 'tap';
56
import {

0 commit comments

Comments
 (0)