feat: use wrapper (#1621)

* feat: use wrapper

* fix: submodules

* fix: >>

* fix: container with python

* fix: oidc

* fix: latex

* fix: latex in the container

* fix: no sudo

* fix: container to python

* fix: submodule stuff

* fix: just dont coverage

* fix: apt install git

* fix: no sudo

* fix: apt-get

* fix: use the oidc token

* fix: cut the token

* fix: small changes

* fix: set the token

* fix: add defaults

* fix: bump to latest wrapper

* fix: 0.0.20

* fix: 0.8.0

* Update action.yml

* Update action.yml

* Update action.yml

* Update action.yml

Co-authored-by: Joe Becher <joe.becher@sentry.io>

* Update action.yml

Co-authored-by: Joe Becher <joe.becher@sentry.io>

* Update dist/codecov.sh

* Update action.yml

* feat: use wrapper

fix: submodules

fix: >>

fix: container with python

fix: oidc

fix: latex

fix: latex in the container

fix: no sudo

fix: container to python

fix: submodule stuff

fix: just dont coverage

fix: apt install git

fix: no sudo

fix: apt-get

fix: use the oidc token

fix: cut the token

fix: small changes

fix: set the token

fix: add defaults

fix: bump to latest wrapper

fix: 0.0.20

fix: 0.8.0

* chore(deps): 0.0.21

---------

Co-authored-by: Joe Becher <joe.becher@sentry.io>
This commit is contained in:
Tom Hu
2024-11-11 10:54:09 -05:00
committed by GitHub
parent 1d6059880c
commit bb7467c2bc
30 changed files with 409 additions and 40566 deletions

View File

@@ -1,368 +0,0 @@
import * as github from '@actions/github';
import {
buildCommitExec,
buildGeneralExec,
buildReportExec,
buildUploadExec,
getToken,
} from './buildExec';
const context = github.context;
let OLDOS = process.env.RUNNER_OS;
beforeEach(() => {
jest.resetModules();
OLDOS = process.env.RUNNER_OS;
});
afterAll(() => {
process.env.RUNNER_OS = OLDOS;
});
test('general args', async () => {
const envs = {
codecov_yml_path: 'dev/codecov.yml',
url: 'https://codecov.enterprise.com',
verbose: 't',
};
for (const env of Object.keys(envs)) {
process.env['INPUT_' + env.toUpperCase()] = envs[env];
}
const {args, verbose} = await buildGeneralExec();
expect(args).toEqual(
expect.arrayContaining([
'--codecov-yml-path',
'dev/codecov.yml',
'--enterprise-url',
'https://codecov.enterprise.com',
'-v',
]));
expect(verbose).toBeTruthy();
for (const env of Object.keys(envs)) {
delete process.env['INPUT_' + env.toUpperCase()];
}
});
test('upload args using context', async () => {
const expectedArgs = [
'--git-service',
'github',
];
const {uploadExecArgs, uploadCommand} = await buildUploadExec();
if (context.eventName == 'pull_request') {
expectedArgs.push('-C', `${context.payload.pull_request?.head.sha}`);
}
if (context.eventName == 'pull_request_target') {
expectedArgs.push('-P', `${context.payload.number}`);
}
expect(uploadExecArgs).toEqual(expectedArgs);
expect(uploadCommand).toEqual('do-upload');
});
test('upload args', async () => {
const envs = {
'codecov_yml_path': 'dev/codecov.yml',
'commit_parent': 'fakeparentcommit',
'directory': 'coverage/',
'disable_file_fixes': 'true',
'disable_search': 'true',
'dry_run': 'true',
'env_vars': 'OS,PYTHON',
'exclude': 'node_modules/',
'fail_ci_if_error': 'true',
'file': 'coverage.xml',
'files': 'dir1/coverage.xml,dir2/coverage.xml,',
'flags': 'test,test2',
'git_service': 'github_enterprise',
'handle_no_reports_found': 'true',
'job_code': '32',
'name': 'codecov',
'os': 'macos',
'override_branch': 'thomasrockhu/test',
'override_build': '1',
'override_build_url': 'https://example.com/build/2',
'override_commit': '9caabca5474b49de74ef5667deabaf74cdacc244',
'override_pr': '2',
'network_filter': 'subA/',
'network_prefix': 'forA/',
'plugin': 'xcode',
'plugins': 'pycoverage,compress-pycoverage',
'report_code': 'testCode',
'root_dir': 'root/',
'slug': 'fakeOwner/fakeRepo',
'token': 'd3859757-ab80-4664-924d-aef22fa7557b',
'url': 'https://enterprise.example.com',
'use_legacy_upload_endpoint': 'true',
'verbose': 'true',
'version': '0.1.2',
'working-directory': 'src',
};
for (const env of Object.keys(envs)) {
process.env['INPUT_' + env.toUpperCase()] = envs[env];
}
const {uploadExecArgs, uploadCommand} = await buildUploadExec();
const expectedArgs = [
'--disable-file-fixes',
'--disable-search',
'-d',
'-e',
'OS,PYTHON',
'--exclude',
'node_modules/',
'-Z',
'-f',
'coverage.xml',
'-f',
'dir1/coverage.xml',
'-f',
'dir2/coverage.xml',
'-F',
'test',
'-F',
'test2',
'--git-service',
'github_enterprise',
'--handle-no-reports-found',
'--job-code',
'32',
'-n',
'codecov',
'--network-filter',
'subA/',
'--network-prefix',
'forA/',
'-B',
'thomasrockhu/test',
'-b',
'1',
'--build-url',
'https://example.com/build/2',
'-C',
'9caabca5474b49de74ef5667deabaf74cdacc244',
'-P',
'2',
'--plugin',
'xcode',
'--plugin',
'pycoverage',
'--plugin',
'compress-pycoverage',
'--report-code',
'testCode',
'--network-root-folder',
'root/',
'-s',
'coverage/',
'-r',
'fakeOwner/fakeRepo',
'--legacy',
];
expect(uploadExecArgs).toEqual(expectedArgs);
expect(uploadCommand).toEqual('do-upload');
for (const env of Object.keys(envs)) {
delete process.env['INPUT_' + env.toUpperCase()];
}
});
test('report args', async () => {
const envs = {
git_service: 'github_enterprise',
override_commit: '9caabca5474b49de74ef5667deabaf74cdacc244',
override_pr: 'fakePR',
slug: 'fakeOwner/fakeRepo',
token: 'd3859757-ab80-4664-924d-aef22fa7557b',
fail_ci_if_error: 'true',
};
for (const env of Object.keys(envs)) {
process.env['INPUT_' + env.toUpperCase()] = envs[env];
}
const {reportExecArgs, reportCommand} = await buildReportExec();
const expectedArgs = [
'--git-service',
'github_enterprise',
'-C',
'9caabca5474b49de74ef5667deabaf74cdacc244',
'-P',
'fakePR',
'--slug',
'fakeOwner/fakeRepo',
'-Z',
];
expect(reportExecArgs).toEqual(expectedArgs);
expect(reportCommand).toEqual('create-report');
for (const env of Object.keys(envs)) {
delete process.env['INPUT_' + env.toUpperCase()];
}
});
test('report args using context', async () => {
const envs = {
token: 'd3859757-ab80-4664-924d-aef22fa7557b',
};
for (const env of Object.keys(envs)) {
process.env['INPUT_' + env.toUpperCase()] = envs[env];
}
const expectedArgs: string[] = [
'--git-service',
'github',
];
if (context.eventName == 'pull_request') {
expectedArgs.push('-C', `${context.payload.pull_request?.head.sha}`);
}
const {reportExecArgs, reportCommand} = await buildReportExec();
expect(reportExecArgs).toEqual(expectedArgs);
expect(reportCommand).toEqual('create-report');
for (const env of Object.keys(envs)) {
delete process.env['INPUT_' + env.toUpperCase()];
}
});
test('commit args', async () => {
const envs = {
git_service: 'github_enterprise',
commit_parent: '83231650328f11695dfb754ca0f540516f188d27',
override_branch: 'thomasrockhu/test',
override_commit: '9caabca5474b49de74ef5667deabaf74cdacc244',
override_pr: '2',
slug: 'fakeOwner/fakeRepo',
token: 'd3859757-ab80-4664-924d-aef22fa7557b',
fail_ci_if_error: 'true',
};
for (const env of Object.keys(envs)) {
process.env['INPUT_' + env.toUpperCase()] = envs[env];
}
const {commitExecArgs, commitCommand} = await buildCommitExec();
const expectedArgs = [
'--parent-sha',
'83231650328f11695dfb754ca0f540516f188d27',
'--git-service',
'github_enterprise',
'-B',
'thomasrockhu/test',
'-C',
'9caabca5474b49de74ef5667deabaf74cdacc244',
'--pr',
'2',
'--slug',
'fakeOwner/fakeRepo',
'-Z',
];
expect(commitExecArgs).toEqual(expectedArgs);
expect(commitCommand).toEqual('create-commit');
for (const env of Object.keys(envs)) {
delete process.env['INPUT_' + env.toUpperCase()];
}
});
test('commit args using context', async () => {
const expectedArgs: string[] = [
'--git-service',
'github',
];
const {commitExecArgs, commitCommand} = await buildCommitExec();
if (
(context.eventName == 'pull_request' || context.eventName == 'pull_request_target') &&
context.payload.pull_request?.base.label.split(':')[0] != context.payload.pull_request?.head.label.split(':')[0]
) {
expectedArgs.push('-B', `${context.payload.pull_request?.head.label}`);
}
if (context.eventName == 'pull_request') {
expectedArgs.push('-C', `${context.payload.pull_request?.head.sha}`);
}
if (context.eventName == 'pull_request_target') {
expectedArgs.push('-P', `${context.payload.number}`);
}
expect(commitExecArgs).toEqual(expectedArgs);
expect(commitCommand).toEqual('create-commit');
});
test('commit args using github server url', async () => {
const expectedArgs: string[] = [
'--git-service',
'github_enterprise',
];
process.env.GITHUB_SERVER_URL = 'https://example.com';
const {commitExecArgs, commitCommand} = await buildCommitExec();
if (
(context.eventName == 'pull_request' || context.eventName == 'pull_request_target') &&
context.payload.pull_request?.base.label.split(':')[0] != context.payload.pull_request?.head.label.split(':')[0]
) {
expectedArgs.push('-B', `${context.payload.pull_request?.head.label}`);
}
if (context.eventName == 'pull_request') {
expectedArgs.push('-C', `${context.payload.pull_request?.head.sha}`);
}
if (context.eventName == 'pull_request_target') {
expectedArgs.push('-P', `${context.payload.number}`);
}
expect(commitExecArgs).toEqual(expectedArgs);
expect(commitCommand).toEqual('create-commit');
});
test('build commit args when token arg is unset and from fork', async () => {
context.eventName = 'pull_request';
context.payload.pull_request = {
'number': 1,
'base': {
'label': 'hello:main',
},
'head': {
'label': 'world:feat',
'sha': 'aaaaaa',
},
};
const expectedArgs: string[] = [
'--git-service',
'github_enterprise',
'-B',
'world:feat',
'-C',
`${context.payload.pull_request?.head.sha}`,
];
const {commitExecArgs, commitCommand} = await buildCommitExec();
expect(commitExecArgs).toEqual(expectedArgs);
expect(commitCommand).toEqual('create-commit');
});
test('get token when token arg is unset and from fork', async () => {
context.eventName = 'pull_request';
context.payload.pull_request = {
'number': 1,
'base': {
'label': 'hello:main',
},
'head': {
'label': 'world:feat',
'sha': 'aaaaaa',
},
};
const token = await getToken();
expect(token).toEqual('');
});

View File

@@ -1,420 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as core from '@actions/core';
import * as github from '@actions/github';
import {type PullRequestEvent} from '@octokit/webhooks-types';
import {setFailure} from './helpers';
const context = github.context;
const isTrue = (variable: string): boolean => {
const lowercase = variable.toLowerCase();
return (
lowercase === '1' ||
lowercase === 't' ||
lowercase === 'true' ||
lowercase === 'y' ||
lowercase === 'yes'
);
};
const getGitService = (): string => {
const overrideGitService = core.getInput('git_service');
const serverUrl = process.env.GITHUB_SERVER_URL;
if (overrideGitService) {
return overrideGitService;
} else if (serverUrl !== undefined && serverUrl !== 'https://github.com') {
return 'github_enterprise';
}
return 'github';
};
const isPullRequestFromFork = (): boolean => {
core.info(`eventName: ${context.eventName}`);
if (!['pull_request', 'pull_request_target'].includes(context.eventName)) {
return false;
}
const baseLabel = context.payload.pull_request.base.label;
const headLabel = context.payload.pull_request.head.label;
core.info(`baseRef: ${baseLabel} | headRef: ${headLabel}`);
return baseLabel.split(':')[0] !== headLabel.split(':')[0];
};
const getToken = async (): Promise<string> => {
let token = core.getInput('token');
let url = core.getInput('url');
const useOIDC = isTrue(core.getInput('use_oidc'));
if (useOIDC) {
if (!url) {
url = 'https://codecov.io';
}
try {
token = await core.getIDToken(url);
return Promise.resolve(token);
} catch (err) {
setFailure(
`Codecov: Failed to get OIDC token with url: ${url}. ${err.message}`,
true,
);
}
}
return token;
};
const getOverrideBranch = (token: string): string => {
let overrideBranch = core.getInput('override_branch');
if (!overrideBranch && !token && isPullRequestFromFork()) {
core.info('==> Fork detected, tokenless uploading used');
// backwards compatibility with certain versions of the CLI that expect this
process.env['TOKENLESS'] = context.payload.pull_request.head.label;
overrideBranch =context.payload.pull_request.head.label;
}
return overrideBranch;
};
const buildCommitExec = async (): Promise<{
commitExecArgs: any[];
commitOptions: any;
commitCommand: string;
}> => {
const commitParent = core.getInput('commit_parent');
const gitService = getGitService();
const overrideCommit = core.getInput('override_commit');
const overridePr = core.getInput('override_pr');
const slug = core.getInput('slug');
const token = await getToken();
const overrideBranch = getOverrideBranch(token);
const failCi = isTrue(core.getInput('fail_ci_if_error'));
const workingDir = core.getInput('working-directory');
const commitCommand = 'create-commit';
const commitExecArgs: string[] = [];
const commitOptions: any = {};
commitOptions.env = Object.assign(process.env, {
GITHUB_ACTION: process.env.GITHUB_ACTION,
GITHUB_RUN_ID: process.env.GITHUB_RUN_ID,
GITHUB_REF: process.env.GITHUB_REF,
GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY,
GITHUB_SHA: process.env.GITHUB_SHA,
GITHUB_HEAD_REF: process.env.GITHUB_HEAD_REF || '',
});
if (token) {
commitOptions.env.CODECOV_TOKEN = token;
}
if (commitParent) {
commitExecArgs.push('--parent-sha', commitParent);
}
commitExecArgs.push('--git-service', gitService);
if (overrideBranch) {
commitExecArgs.push('-B', overrideBranch);
}
if (overrideCommit) {
commitExecArgs.push('-C', overrideCommit);
} else if (
['pull_request', 'pull_request_target'].includes(context.eventName)
) {
const payload = context.payload as PullRequestEvent;
commitExecArgs.push('-C', payload.pull_request.head.sha);
}
if (overridePr) {
commitExecArgs.push('--pr', overridePr);
} else if (context.eventName === 'pull_request_target') {
const payload = context.payload as PullRequestEvent;
commitExecArgs.push('--pr', payload.number.toString());
}
if (slug) {
commitExecArgs.push('--slug', slug);
}
if (failCi) {
commitExecArgs.push('-Z');
}
if (workingDir) {
commitOptions.cwd = workingDir;
}
return {commitExecArgs, commitOptions, commitCommand};
};
const buildGeneralExec = (): {
args: any[];
verbose: boolean;
} => {
const codecovYmlPath = core.getInput('codecov_yml_path');
const url = core.getInput('url');
const verbose = isTrue(core.getInput('verbose'));
const args = [];
if (codecovYmlPath) {
args.push('--codecov-yml-path', codecovYmlPath);
}
if (url) {
args.push('--enterprise-url', url);
}
if (verbose) {
args.push('-v');
}
return {args, verbose};
};
const buildReportExec = async (): Promise<{
reportExecArgs: any[];
reportOptions: any;
reportCommand: string;
}> => {
const gitService = getGitService();
const overrideCommit = core.getInput('override_commit');
const overridePr = core.getInput('override_pr');
const slug = core.getInput('slug');
const token = await getToken();
const failCi = isTrue(core.getInput('fail_ci_if_error'));
const workingDir = core.getInput('working-directory');
const reportCommand = 'create-report';
const reportExecArgs: string[] = [];
const reportOptions: any = {};
reportOptions.env = Object.assign(process.env, {
GITHUB_ACTION: process.env.GITHUB_ACTION,
GITHUB_RUN_ID: process.env.GITHUB_RUN_ID,
GITHUB_REF: process.env.GITHUB_REF,
GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY,
GITHUB_SHA: process.env.GITHUB_SHA,
GITHUB_HEAD_REF: process.env.GITHUB_HEAD_REF || '',
});
if (token) {
reportOptions.env.CODECOV_TOKEN = token;
}
reportExecArgs.push('--git-service', gitService);
if (overrideCommit) {
reportExecArgs.push('-C', overrideCommit);
} else if (
['pull_request', 'pull_request_target'].includes(context.eventName)
) {
const payload = context.payload as PullRequestEvent;
reportExecArgs.push('-C', payload.pull_request.head.sha);
}
if (overridePr) {
reportExecArgs.push('-P', overridePr);
} else if (context.eventName == 'pull_request_target') {
const payload = context.payload as PullRequestEvent;
reportExecArgs.push('-P', payload.number.toString());
}
if (slug) {
reportExecArgs.push('--slug', slug);
}
if (failCi) {
reportExecArgs.push('-Z');
}
if (workingDir) {
reportOptions.cwd = workingDir;
}
return {reportExecArgs, reportOptions, reportCommand};
};
const buildUploadExec = async (): Promise<{
uploadExecArgs: any[];
uploadOptions: any;
disableSafeDirectory: boolean;
failCi: boolean;
os: string;
uploaderVersion: string;
uploadCommand: string;
}> => {
const disableFileFixes = isTrue(core.getInput('disable_file_fixes'));
const disableSafeDirectory = isTrue(core.getInput('disable_safe_directory'));
const disableSearch = isTrue(core.getInput('disable_search'));
const dryRun = isTrue(core.getInput('dry_run'));
const envVars = core.getInput('env_vars');
const exclude = core.getInput('exclude');
const failCi = isTrue(core.getInput('fail_ci_if_error'));
const file = core.getInput('file');
const files = core.getInput('files');
const flags = core.getInput('flags');
const gitService = getGitService();
const handleNoReportsFound = isTrue(core.getInput('handle_no_reports_found'));
const jobCode = core.getInput('job_code');
const name = core.getInput('name');
const networkFilter = core.getInput('network_filter');
const networkPrefix = core.getInput('network_prefix');
const os = core.getInput('os');
const overrideBranch = core.getInput('override_branch');
const overrideBuild = core.getInput('override_build');
const overrideBuildUrl = core.getInput('override_build_url');
const overrideCommit = core.getInput('override_commit');
const overridePr = core.getInput('override_pr');
const plugin = core.getInput('plugin');
const plugins = core.getInput('plugins');
const reportCode = core.getInput('report_code');
const rootDir = core.getInput('root_dir');
const searchDir = core.getInput('directory');
const slug = core.getInput('slug');
const token = await getToken();
let uploaderVersion = core.getInput('version');
const useLegacyUploadEndpoint = isTrue(
core.getInput('use_legacy_upload_endpoint'),
);
const workingDir = core.getInput('working-directory');
const uploadExecArgs: string[] = [];
const uploadCommand = 'do-upload';
const uploadOptions: any = {};
uploadOptions.env = Object.assign(process.env, {
GITHUB_ACTION: process.env.GITHUB_ACTION,
GITHUB_RUN_ID: process.env.GITHUB_RUN_ID,
GITHUB_REF: process.env.GITHUB_REF,
GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY,
GITHUB_SHA: process.env.GITHUB_SHA,
GITHUB_HEAD_REF: process.env.GITHUB_HEAD_REF || '',
});
const envVarsArg = [];
for (const envVar of envVars.split(',')) {
const envVarClean = envVar.trim();
if (envVarClean) {
uploadOptions.env[envVarClean] = process.env[envVarClean];
envVarsArg.push(envVarClean);
}
}
if (token) {
uploadOptions.env.CODECOV_TOKEN = token;
}
if (disableFileFixes) {
uploadExecArgs.push('--disable-file-fixes');
}
if (disableSearch) {
uploadExecArgs.push('--disable-search');
}
if (dryRun) {
uploadExecArgs.push('-d');
}
if (envVarsArg.length) {
uploadExecArgs.push('-e', envVarsArg.join(','));
}
if (exclude) {
uploadExecArgs.push('--exclude', exclude);
}
if (failCi) {
uploadExecArgs.push('-Z');
}
if (file) {
uploadExecArgs.push('-f', file);
}
if (files) {
files
.split(',')
.map((f) => f.trim())
.forEach((f) => {
if (f.length > 0) {
// this handles trailing commas
uploadExecArgs.push('-f', f);
}
});
}
if (flags) {
flags
.split(',')
.map((f) => f.trim())
.forEach((f) => {
uploadExecArgs.push('-F', f);
});
}
uploadExecArgs.push('--git-service', gitService);
if (handleNoReportsFound) {
uploadExecArgs.push('--handle-no-reports-found');
}
if (jobCode) {
uploadExecArgs.push('--job-code', jobCode);
}
if (name) {
uploadExecArgs.push('-n', name);
}
if (networkFilter) {
uploadExecArgs.push('--network-filter', networkFilter);
}
if (networkPrefix) {
uploadExecArgs.push('--network-prefix', networkPrefix);
}
if (overrideBranch) {
uploadExecArgs.push('-B', overrideBranch);
}
if (overrideBuild) {
uploadExecArgs.push('-b', overrideBuild);
}
if (overrideBuildUrl) {
uploadExecArgs.push('--build-url', overrideBuildUrl);
}
if (overrideCommit) {
uploadExecArgs.push('-C', overrideCommit);
} else if (
['pull_request', 'pull_request_target'].includes(context.eventName)
) {
const payload = context.payload as PullRequestEvent;
uploadExecArgs.push('-C', payload.pull_request.head.sha);
}
if (overridePr) {
uploadExecArgs.push('-P', overridePr);
} else if (context.eventName == 'pull_request_target') {
const payload = context.payload as PullRequestEvent;
uploadExecArgs.push('-P', payload.number.toString());
}
if (plugin) {
uploadExecArgs.push('--plugin', plugin);
}
if (plugins) {
plugins
.split(',')
.map((p) => p.trim())
.forEach((p) => {
uploadExecArgs.push('--plugin', p);
});
}
if (reportCode) {
uploadExecArgs.push('--report-code', reportCode);
}
if (rootDir) {
uploadExecArgs.push('--network-root-folder', rootDir);
}
if (searchDir) {
uploadExecArgs.push('-s', searchDir);
}
if (slug) {
uploadExecArgs.push('-r', slug);
}
if (workingDir) {
uploadOptions.cwd = workingDir;
}
if (uploaderVersion == '') {
uploaderVersion = 'latest';
}
if (useLegacyUploadEndpoint) {
uploadExecArgs.push('--legacy');
}
return {
uploadExecArgs,
uploadOptions,
disableSafeDirectory,
failCi,
os,
uploaderVersion,
uploadCommand,
};
};
export {
buildCommitExec,
buildGeneralExec,
buildReportExec,
buildUploadExec,
getToken,
};

View File

@@ -1,96 +0,0 @@
import * as exec from '@actions/exec';
import {
PLATFORMS,
getBaseUrl,
getCommand,
getPlatform,
isValidPlatform,
isWindows,
setSafeDirectory,
} from './helpers';
let OLDOS = process.env.RUNNER_OS;
beforeEach(() => {
jest.resetModules();
OLDOS = process.env.RUNNER_OS;
});
afterAll(() => {
process.env.RUNNER_OS = OLDOS;
});
test('getPlatform', () => {
expect(getPlatform('linux')).toBe('linux');
expect(getPlatform('windows')).toBe('windows');
const defaultPlatform =
process.env.RUNNER_OS ? process.env.RUNNER_OS.toLowerCase() : 'linux';
expect(getPlatform('fakeos')).toBe(defaultPlatform);
expect(getPlatform()).toBe(defaultPlatform);
process.env.RUNNER_OS = 'macos';
expect(getPlatform('fakeos')).toBe('macos');
expect(getPlatform()).toBe('macos');
process.env.RUNNER_OS = 'alsofakeos';
expect(getPlatform()).toBe('linux');
expect(getPlatform('fakeos')).toBe('linux');
});
test('getBaseUrl', () => {
expect(PLATFORMS.map((platform) => {
return getBaseUrl(platform, 'latest');
})).toEqual([
'https://cli.codecov.io/latest/linux/codecov',
'https://cli.codecov.io/latest/macos/codecov',
'https://cli.codecov.io/latest/windows/codecov.exe',
'https://cli.codecov.io/latest/alpine/codecov',
'https://cli.codecov.io/latest/linux-arm64/codecov',
'https://cli.codecov.io/latest/alpine-arm64/codecov',
]);
expect(PLATFORMS.map((platform) => {
return getBaseUrl(platform, 'v0.1.0_8880');
})).toEqual([
'https://cli.codecov.io/v0.1.0_8880/linux/codecov',
'https://cli.codecov.io/v0.1.0_8880/macos/codecov',
'https://cli.codecov.io/v0.1.0_8880/windows/codecov.exe',
'https://cli.codecov.io/v0.1.0_8880/alpine/codecov',
'https://cli.codecov.io/v0.1.0_8880/linux-arm64/codecov',
'https://cli.codecov.io/v0.1.0_8880/alpine-arm64/codecov',
]);
});
test('isWindows', () => {
expect(PLATFORMS.map((platform) => {
return isWindows(platform);
})).toEqual([false, false, true, false, false, false]);
});
test('isValidPlatform', () => {
expect(PLATFORMS.map((platform) => {
return isValidPlatform(platform);
})).toEqual([true, true, true, true, true, true]);
expect(isValidPlatform('fakeos')).toBeFalsy();
});
test('getCommand', () => {
expect(getCommand('path', ['-v', '-x'], 'do-upload'))
.toEqual(['path', '-v', '-x', 'do-upload']);
});
test('setSafeDirectory', async () => {
process.env.GITHUB_WORKSPACE = 'testOrg/testRepo';
await setSafeDirectory();
const testSafeDirectory = ([
'git',
'config',
'--get',
'safe.directory',
]).join(' ');
const safeDirectory = await exec.getExecOutput(testSafeDirectory);
expect(safeDirectory.stdout).toBe('testOrg/testRepo\n');
});

View File

@@ -1,97 +0,0 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
const PLATFORMS = [
'linux',
'macos',
'windows',
'alpine',
'linux-arm64',
'alpine-arm64',
] as const;
type Platform = typeof PLATFORMS[number];
const setFailure = (message: string, failCi: boolean): void => {
if (failCi) {
core.setFailed(message);
} else {
core.warning(message);
}
if (failCi) {
process.exit();
}
};
const getUploaderName = (platform: string): string => {
if (isWindows(platform)) {
return 'codecov.exe';
} else {
return 'codecov';
}
};
const isValidPlatform = (platform: string): platform is Platform => {
return PLATFORMS.includes(platform as Platform);
};
const isWindows = (platform: string): boolean => {
return platform === 'windows';
};
const getPlatform = (os?: string): string => {
if (isValidPlatform(os)) {
core.info(`==> ${os} OS provided`);
return os;
}
const platform = process.env.RUNNER_OS?.toLowerCase();
if (isValidPlatform(platform)) {
core.info(`==> ${platform} OS detected`);
return platform;
}
core.info(
'==> Could not detect OS or provided OS is invalid. Defaulting to linux',
);
return 'linux';
};
const getBaseUrl = (platform: string, version: string): string => {
return `https://cli.codecov.io/${version}/${platform}/${getUploaderName(platform)}`;
};
const getCommand = (
filename: string,
generalArgs:string[],
command: string,
): string[] => {
const fullCommand = [filename, ...generalArgs, command];
core.info(`==> Running command '${fullCommand.join(' ')}'`);
return fullCommand;
};
const setSafeDirectory = async () => {
const command = ([
'git',
'config',
'--global',
'--add',
'safe.directory',
`${process.env['GITHUB_WORKSPACE']}`,
].join(' '));
core.info(`==> Running ${command}`);
await exec.exec(command);
};
export {
PLATFORMS,
getBaseUrl,
getPlatform,
getUploaderName,
isValidPlatform,
isWindows,
setFailure,
setSafeDirectory,
getCommand,
};

View File

@@ -1,129 +0,0 @@
import * as fs from 'node:fs';
import * as https from 'node:https';
import * as path from 'node:path';
import * as exec from '@actions/exec';
import {
buildCommitExec,
buildGeneralExec,
buildReportExec,
buildUploadExec,
} from './buildExec';
import {
getBaseUrl,
getCommand,
getPlatform,
getUploaderName,
setFailure,
setSafeDirectory,
} from './helpers';
import verify from './validate';
import versionInfo from './version';
let failCi;
const run = async (): Promise<void> => {
try {
const {commitExecArgs, commitOptions, commitCommand} = await buildCommitExec();
const {reportExecArgs, reportOptions, reportCommand} = await buildReportExec();
const {
uploadExecArgs,
uploadOptions,
disableSafeDirectory,
failCi,
os,
uploaderVersion,
uploadCommand,
} = await buildUploadExec();
const {args, verbose} = buildGeneralExec();
const platform = getPlatform(os);
const filename = path.join( __dirname, getUploaderName(platform));
https.get(getBaseUrl(platform, uploaderVersion), (res) => {
// Image will be stored at this path
const filePath = fs.createWriteStream(filename);
res.pipe(filePath);
filePath
.on('error', (err) => {
setFailure(
`Codecov: Failed to write uploader binary: ${err.message}`,
true,
);
}).on('finish', async () => {
filePath.close();
await verify(filename, platform, uploaderVersion, verbose, failCi);
await versionInfo(platform, uploaderVersion);
await fs.chmodSync(filename, '777');
if (!disableSafeDirectory) {
await setSafeDirectory();
}
const unlink = (): void => {
fs.unlink(filename, (err) => {
if (err) {
setFailure(
`Codecov: Could not unlink uploader: ${err.message}`,
failCi,
);
}
});
};
const doUpload = async (): Promise<void> => {
await exec.exec(getCommand(filename, args, uploadCommand).join(' '),
uploadExecArgs,
uploadOptions)
.catch((err) => {
setFailure(
`Codecov:
Failed to properly upload report: ${err.message}`,
failCi,
);
});
};
const createReport = async (): Promise<void> => {
await exec.exec(
getCommand(filename, args, reportCommand).join(' '),
reportExecArgs,
reportOptions)
.then(async (exitCode) => {
if (exitCode == 0) {
await doUpload();
}
}).catch((err) => {
setFailure(
`Codecov:
Failed to properly create report: ${err.message}`,
failCi,
);
});
};
await exec.exec(
getCommand(
filename,
args,
commitCommand,
).join(' '),
commitExecArgs, commitOptions)
.then(async (exitCode) => {
if (exitCode == 0) {
await createReport();
}
unlink();
}).catch((err) => {
setFailure(
`Codecov: Failed to properly create commit: ${err.message}`,
failCi,
);
});
});
});
} catch (err) {
setFailure(`Codecov: Encountered an unexpected error ${err.message}`, failCi);
}
};
run();

View File

@@ -1,52 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=ch7z
-----END PGP PUBLIC KEY BLOCK-----

1
src/scripts Submodule

Submodule src/scripts added at 44fa6396f4

View File

@@ -1,120 +0,0 @@
import {execSync} from 'node:child_process';
import * as crypto from 'node:crypto';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as core from '@actions/core';
import {request} from 'undici';
import {
getBaseUrl,
getUploaderName,
setFailure,
} from './helpers';
const verify = async (
filename: string,
platform: string,
version: string,
verbose: boolean,
failCi: boolean,
): Promise<void> => {
try {
const uploaderName = getUploaderName(platform);
// Get SHASUM and SHASUM signature files
console.log(`${getBaseUrl(platform, version)}.SHA256SUM`);
const shasumRes = await request(
`${getBaseUrl(platform, version)}.SHA256SUM`,
);
const shasum = await shasumRes.body.text();
if (verbose) {
console.log(`Received SHA256SUM ${shasum}`);
}
await fs.writeFileSync(
path.join(__dirname, `${uploaderName}.SHA256SUM`),
shasum,
);
const shaSigRes = await request(
`${getBaseUrl(platform, version)}.SHA256SUM.sig`,
);
const shaSig = await shaSigRes.body.text();
if (verbose) {
console.log(`Received SHA256SUM signature ${shaSig}`);
}
await fs.writeFileSync(
path.join(__dirname, `${uploaderName}.SHA256SUM.sig`),
shaSig,
);
const validateSha = async () => {
const calculateHash = async (filename: string) => {
const stream = fs.createReadStream(filename);
const uploaderSha = crypto.createHash(`sha256`);
stream.pipe(uploaderSha);
return new Promise((resolve, reject) => {
stream.on('end', () => resolve(
`${uploaderSha.digest('hex')} ${uploaderName}`,
));
stream.on('error', reject);
});
};
const hash = await calculateHash(
path.join(__dirname, `${uploaderName}`),
);
if (hash === shasum) {
core.info(`==> Uploader SHASUM verified (${hash})`);
} else {
setFailure(
'Codecov: Uploader shasum does not match -- ' +
`uploader hash: ${hash}, public hash: ${shasum}`,
failCi,
);
}
};
const verifySignature = async () => {
const command = [
'gpg',
'--logger-fd',
'1',
'--verify',
path.join(__dirname, `${uploaderName}.SHA256SUM.sig`),
path.join(__dirname, `${uploaderName}.SHA256SUM`),
].join(' ');
try {
await execSync(command, {stdio: 'inherit'});
} catch (err) {
setFailure(`Codecov: Error verifying gpg signature: ${err.message}`, failCi);
}
};
const importKey = async () => {
const command = [
'gpg',
'--logger-fd',
'1',
'--no-default-keyring',
'--import',
path.join(__dirname, 'pgp_keys.asc'),
].join(' ');
try {
await execSync(command, {stdio: 'inherit'});
} catch (err) {
setFailure(`Codecov: Error importing gpg key: ${err.message}`, failCi);
}
};
await importKey();
await verifySignature();
await validateSha();
} catch (err) {
setFailure(`Codecov: Error validating uploader: ${err.message}`, failCi);
}
};
export default verify;

1
src/version Normal file
View File

@@ -0,0 +1 @@
CODECOV_ACTION_VERSION="5.0.0"

View File

@@ -1,62 +0,0 @@
import * as core from '@actions/core';
import {Agent, MockAgent, setGlobalDispatcher} from 'undici';
import versionInfo from './version';
const mockAgent = new MockAgent();
beforeAll(() => {
setGlobalDispatcher(mockAgent);
mockAgent.disableNetConnect();
});
afterEach(() => {
jest.clearAllMocks();
});
afterAll(async () => {
await mockAgent.close();
setGlobalDispatcher(new Agent());
});
describe('versionInfo', () => {
const platform = 'linux';
test('should resolve requested version info', async () => {
const version = 'latest';
const coreInfoSpy = jest.spyOn(core, 'info');
mockAgent
.get('https://cli.codecov.io')
.intercept({
path: `/${platform}/${version}`,
})
.reply(200, {
version: 'v0.5.2',
});
await versionInfo(platform, version);
expect(coreInfoSpy).toHaveBeenCalledTimes(2);
expect(coreInfoSpy).toHaveBeenCalledWith('==> Running version latest');
expect(coreInfoSpy).toHaveBeenCalledWith('==> Running version v0.5.2');
});
test('should handle unsupported version', async () => {
const version = 'unsupported';
const coreInfoSpy = jest.spyOn(core, 'info');
mockAgent
.get('https://cli.codecov.io')
.intercept({
path: `/${platform}/${version}`,
})
.reply(404, 'MESSAGE');
await versionInfo(platform, version);
expect(coreInfoSpy).toHaveBeenCalledTimes(2);
expect(coreInfoSpy).toHaveBeenCalledWith('==> Running version unsupported');
expect(coreInfoSpy).toHaveBeenCalledWith(expect.stringContaining('Could not pull latest version information'));
});
});

View File

@@ -1,20 +0,0 @@
import * as core from '@actions/core';
import {request} from 'undici';
const versionInfo = async (
platform: string,
version: string,
): Promise<void> => {
core.info(`==> Running version ${version}`);
try {
const metadataRes = await request(`https://cli.codecov.io/${platform}/${version}`, {
headers: {'Accept': 'application/json'},
});
const metadata = await metadataRes.body.json();
core.info(`==> Running version ${metadata['version']}`);
} catch (err) {
core.info(`Could not pull latest version information: ${err}`);
}
};
export default versionInfo;