Compare commits

...

4 Commits

Author SHA1 Message Date
Tom Hu
967e2b38a8 Merge pull request #287 from codecov/update-validation-regex
Update validation regex, pull checksums into script, and bump to 1.4.1
2021-04-20 08:59:13 -04:00
Tom Hu
77a7b61cd5 Lint 2021-04-20 08:38:33 -04:00
Tom Hu
50895b2a6f Pull checksums into script 2021-04-20 08:35:56 -04:00
Tom Hu
95e6f30a60 Update validation regex and bump to 1.4.1 2021-04-19 21:23:35 -04:00
7 changed files with 127 additions and 169 deletions

View File

@@ -1,3 +1,7 @@
## 1.4.1
## Fixes
- #287 Update VERSION regex to restrict on digits and dot and move checksums into script
## 1.4.0 ## 1.4.0
### Features ### Features
- #282 Add checksum verification of bash script - #282 Add checksum verification of bash script

138
dist/index.js vendored
View File

@@ -13203,17 +13203,11 @@ try {
timeout: 3000, timeout: 3000,
url: 'https://codecov.io/bash', url: 'https://codecov.io/bash',
}, function (error, response, body) { return __awaiter(void 0, void 0, void 0, function () { }, function (error, response, body) { return __awaiter(void 0, void 0, void 0, function () {
var _a, execArgs, options, filepath, failCi, isValid, failure, error_1; var _a, execArgs, options, filepath, failCi, isValid, failure;
return __generator(this, function (_b) { return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = buildExec_1["default"](), execArgs = _a.execArgs, options = _a.options, filepath = _a.filepath, failCi = _a.failCi; _a = buildExec_1["default"](), execArgs = _a.execArgs, options = _a.options, filepath = _a.filepath, failCi = _a.failCi;
_b.label = 1; try {
case 1: isValid = validate_1["default"](body);
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, validate_1["default"](body)];
case 2:
isValid = _b.sent();
if (!isValid) { if (!isValid) {
failure = 'Codecov failure: ' + failure = 'Codecov failure: ' +
'Bash script checksums do not match published values. ' + 'Bash script checksums do not match published values. ' +
@@ -13256,13 +13250,11 @@ try {
}); });
}; };
}); });
return [3 /*break*/, 4];
case 3:
error_1 = _b.sent();
core.setFailed("Codecov failed with the following error: " + error_1.message);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
} }
catch (error) {
core.setFailed("Codecov failed with the following error: " + error.message);
}
return [2 /*return*/];
}); });
}); }); }); });
} }
@@ -49178,109 +49170,57 @@ module.exports = function (data, opts) {
"use strict"; "use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
exports.__esModule = true; exports.__esModule = true;
exports.retrieveChecksum = void 0; exports.retrieveChecksum = void 0;
var crypto = __webpack_require__(417); var crypto = __webpack_require__(417);
var core = __webpack_require__(470); var core = __webpack_require__(470);
var request = __webpack_require__(335); var validateUploader = function (body) {
var validateUploader = function (body) { return __awaiter(void 0, void 0, void 0, function () { var version = getVersion(body);
var version, _i, _a, i, publicChecksum, uploaderChecksum;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
version = getVersion(body);
if (version === null) { if (version === null) {
core.warning('Codecov could not identify the bash uploader version.'); core.warning('Codecov could not identify the bash uploader version.');
return [2 /*return*/, false]; return false;
} }
_i = 0, _a = [1, 256, 512]; for (var _i = 0, _a = [1, 256, 512]; _i < _a.length; _i++) {
_b.label = 1; var i = _a[_i];
case 1: var publicChecksum = exports.retrieveChecksum(version, i);
if (!(_i < _a.length)) return [3 /*break*/, 4]; var uploaderChecksum = calculateChecksum(body, i);
i = _a[_i]; if (uploaderChecksum !== publicChecksum) {
return [4 /*yield*/, exports.retrieveChecksum(version, i)];
case 2:
publicChecksum = _b.sent();
uploaderChecksum = calculateChecksum(body, i);
if (uploaderChecksum !== publicChecksum.trim()) {
core.warning("Codecov " + version + " checksums for SHA" + i + " failed to match.\n" + core.warning("Codecov " + version + " checksums for SHA" + i + " failed to match.\n" +
("Public checksum: " + publicChecksum) + ("Public checksum: " + publicChecksum) +
("Uploader checksum: " + uploaderChecksum)); ("Uploader checksum: " + uploaderChecksum));
return [2 /*return*/, false]; return false;
} }
_b.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, true];
} }
}); return true;
}); }; };
var retrieveChecksum = function (version, encryption) { return __awaiter(void 0, void 0, void 0, function () { var retrieveChecksum = function (version, encryption) {
var url, response; var checksums = {
return __generator(this, function (_a) { '1.0.1': {
switch (_a.label) { '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8',
case 0: '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8',
url = "https://raw.githubusercontent.com/codecov/codecov-bash/" + version + "/SHA" + encryption + "SUM"; '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862ae' +
return [4 /*yield*/, request({ 'b005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e',
maxAttempts: 10, },
timeout: 3000, '1.0.2': {
url: url, '1': '537069158a6f72b145cfe5f782dceb608d9ef594',
})]; '256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9',
case 1: '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9af' +
response = _a.sent(); 'c346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d',
if (response.statusCode != 200) { },
core.warning("Codecov could not retrieve checksum SHA" + encryption + " at " + url); };
return [2 /*return*/, '']; if (version in checksums && encryption in checksums[version]) {
return checksums[version][encryption];
} }
return [2 /*return*/, response.body]; return null;
} };
});
}); };
exports.retrieveChecksum = retrieveChecksum; exports.retrieveChecksum = retrieveChecksum;
var calculateChecksum = function (body, i) { var calculateChecksum = function (body, i) {
var shasum = crypto.createHash("sha" + i); var shasum = crypto.createHash("sha" + i);
shasum.update(body); shasum.update(body);
return shasum.digest('hex') + " codecov"; return "" + shasum.digest('hex');
}; };
var getVersion = function (body) { var getVersion = function (body) {
var regex = /VERSION="(.*)+"/g; var regex = /VERSION="([\d\.]+)"/g;
var match = regex.exec(body); var match = regex.exec(body);
return match ? match[1] : null; return match ? match[1] : null;
}; };

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "codecov-action", "name": "codecov-action",
"version": "1.4.0", "version": "1.4.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "codecov-action", "name": "codecov-action",
"version": "1.4.0", "version": "1.4.1",
"description": "Upload coverage reports to Codecov from GitHub Actions", "description": "Upload coverage reports to Codecov from GitHub Actions",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@@ -18,7 +18,7 @@ try {
const {execArgs, options, filepath, failCi} = buildExec(); const {execArgs, options, filepath, failCi} = buildExec();
try { try {
const isValid = await validateUploader(body); const isValid = validateUploader(body);
if (!isValid) { if (!isValid) {
const failure = 'Codecov failure: ' + const failure = 'Codecov failure: ' +
'Bash script checksums do not match published values. ' + 'Bash script checksums do not match published values. ' +

View File

@@ -17,23 +17,34 @@ const bashScript = (async () => {
}); });
test('valid checksums', async () => { test('valid checksums', async () => {
const valid = await validateUploader(await bashScript()); const valid = validateUploader(await bashScript());
expect(valid).toBeTruthy(); expect(valid).toBeTruthy();
}); });
test('invalid checksums', async () => { test('invalid checksums', async () => {
const script = await bashScript(); const script = await bashScript();
const valid = await validateUploader(script.substring(0, script.length - 1)); const valid = validateUploader(script.substring(0, script.length - 1));
expect(valid).toBeFalsy(); expect(valid).toBeFalsy();
}); });
test('invalid script version', async () => { test('invalid script version', async () => {
const script = await bashScript(); const script = await bashScript();
const valid = await validateUploader(script.substring(0, 20)); const valid = validateUploader(script.substring(0, 20));
expect(valid).toBeFalsy(); expect(valid).toBeFalsy();
}); });
test('invalid public checksum file', async () => { test('invalid public checksum file', () => {
const checksum = await retrieveChecksum('foo', 'bar'); const checksum = retrieveChecksum('foo', 'bar');
expect(checksum).toBeFalsy(); expect(checksum).toBeFalsy();
}); });
test('invalid public checksum file', () => {
const checksum = retrieveChecksum('foo', 'bar');
expect(checksum).toBeFalsy();
});
test('invalid encryption', () => {
const checksum = retrieveChecksum('1.0.1', 'foo');
expect(checksum).toBeFalsy();
});

View File

@@ -2,9 +2,7 @@ const crypto = require('crypto');
const core = require('@actions/core'); const core = require('@actions/core');
const request = require('requestretry'); const validateUploader = (body) => {
const validateUploader = async (body) => {
const version = getVersion(body); const version = getVersion(body);
if (version === null) { if (version === null) {
core.warning('Codecov could not identify the bash uploader version.'); core.warning('Codecov could not identify the bash uploader version.');
@@ -12,9 +10,9 @@ const validateUploader = async (body) => {
} }
for (const i of [1, 256, 512]) { for (const i of [1, 256, 512]) {
const publicChecksum = await retrieveChecksum(version, i); const publicChecksum = retrieveChecksum(version, i);
const uploaderChecksum = calculateChecksum(body, i); const uploaderChecksum = calculateChecksum(body, i);
if (uploaderChecksum !== publicChecksum.trim()) { if (uploaderChecksum !== publicChecksum) {
core.warning( core.warning(
`Codecov ${version} checksums for SHA${i} failed to match.\n` + `Codecov ${version} checksums for SHA${i} failed to match.\n` +
`Public checksum: ${publicChecksum}` + `Public checksum: ${publicChecksum}` +
@@ -26,31 +24,36 @@ const validateUploader = async (body) => {
return true; return true;
}; };
export const retrieveChecksum = async (version, encryption) => { export const retrieveChecksum = (version, encryption) => {
const url = `https://raw.githubusercontent.com/codecov/codecov-bash/${version}/SHA${encryption}SUM`; const checksums = {
const response = await request({ '1.0.1': {
maxAttempts: 10, '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8',
timeout: 3000, '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8',
url: url, '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862ae' +
}); 'b005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e',
},
'1.0.2': {
'1': '537069158a6f72b145cfe5f782dceb608d9ef594',
'256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9',
'512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9af' +
'c346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d',
},
};
if (response.statusCode != 200) { if (version in checksums && encryption in checksums[version]) {
core.warning( return checksums[version][encryption];
`Codecov could not retrieve checksum SHA${encryption} at ${url}`,
);
return '';
} }
return response.body; return null;
}; };
const calculateChecksum = (body, i) => { const calculateChecksum = (body, i) => {
const shasum = crypto.createHash(`sha${i}`); const shasum = crypto.createHash(`sha${i}`);
shasum.update(body); shasum.update(body);
return `${shasum.digest('hex')} codecov`; return `${shasum.digest('hex')}`;
}; };
const getVersion = (body) => { const getVersion = (body) => {
const regex = /VERSION="(.*)+"/g; const regex = /VERSION="([\d\.]+)"/g;
const match = regex.exec(body); const match = regex.exec(body);
return match ? match[1] : null; return match ? match[1] : null;
}; };