fix: really do the move

This commit is contained in:
Tom Hu 2024-03-08 19:43:44 -08:00
parent cf70ca862e
commit 0c3f353a54
No known key found for this signature in database
GPG key ID: 79155678363963D2
30 changed files with 164 additions and 44144 deletions

View file

@ -1,22 +0,0 @@
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": [
"google",
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"linebreak-style": 0
}
}

View file

@ -110,7 +110,23 @@ branding:
runs:
using: 'composite'
steps:
- id: codecov-upload
run: |
echo "meow"
- name: Determine os
id: determine-os
if: ${{ inputs.os }} != ""
shell: bash
run: |
./determine_os.sh
- name: Upload to Codecov
id: codecov-upload
shell: bash
run: |
curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step
curl -Os https://cli.codecov.io/latest/linux/codecov
curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM
curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM.sig
gpg --verify codecov.SHA256SUM.sig codecov.SHA256SUM
shasum -a 256 -c codecov.SHA256SUM
sudo chmod +x codecov
./codecov

453
dist/37.index.js vendored
View file

@ -1,453 +0,0 @@
"use strict";
exports.id = 37;
exports.ids = [37];
exports.modules = {
/***/ 4037:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "toFormData": () => (/* binding */ toFormData)
/* harmony export */ });
/* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2777);
/* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8010);
let s = 0;
const S = {
START_BOUNDARY: s++,
HEADER_FIELD_START: s++,
HEADER_FIELD: s++,
HEADER_VALUE_START: s++,
HEADER_VALUE: s++,
HEADER_VALUE_ALMOST_DONE: s++,
HEADERS_ALMOST_DONE: s++,
PART_DATA_START: s++,
PART_DATA: s++,
END: s++
};
let f = 1;
const F = {
PART_BOUNDARY: f,
LAST_BOUNDARY: f *= 2
};
const LF = 10;
const CR = 13;
const SPACE = 32;
const HYPHEN = 45;
const COLON = 58;
const A = 97;
const Z = 122;
const lower = c => c | 0x20;
const noop = () => {};
class MultipartParser {
/**
* @param {string} boundary
*/
constructor(boundary) {
this.index = 0;
this.flags = 0;
this.onHeaderEnd = noop;
this.onHeaderField = noop;
this.onHeadersEnd = noop;
this.onHeaderValue = noop;
this.onPartBegin = noop;
this.onPartData = noop;
this.onPartEnd = noop;
this.boundaryChars = {};
boundary = '\r\n--' + boundary;
const ui8a = new Uint8Array(boundary.length);
for (let i = 0; i < boundary.length; i++) {
ui8a[i] = boundary.charCodeAt(i);
this.boundaryChars[ui8a[i]] = true;
}
this.boundary = ui8a;
this.lookbehind = new Uint8Array(this.boundary.length + 8);
this.state = S.START_BOUNDARY;
}
/**
* @param {Uint8Array} data
*/
write(data) {
let i = 0;
const length_ = data.length;
let previousIndex = this.index;
let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
const boundaryLength = this.boundary.length;
const boundaryEnd = boundaryLength - 1;
const bufferLength = data.length;
let c;
let cl;
const mark = name => {
this[name + 'Mark'] = i;
};
const clear = name => {
delete this[name + 'Mark'];
};
const callback = (callbackSymbol, start, end, ui8a) => {
if (start === undefined || start !== end) {
this[callbackSymbol](ui8a && ui8a.subarray(start, end));
}
};
const dataCallback = (name, clear) => {
const markSymbol = name + 'Mark';
if (!(markSymbol in this)) {
return;
}
if (clear) {
callback(name, this[markSymbol], i, data);
delete this[markSymbol];
} else {
callback(name, this[markSymbol], data.length, data);
this[markSymbol] = 0;
}
};
for (i = 0; i < length_; i++) {
c = data[i];
switch (state) {
case S.START_BOUNDARY:
if (index === boundary.length - 2) {
if (c === HYPHEN) {
flags |= F.LAST_BOUNDARY;
} else if (c !== CR) {
return;
}
index++;
break;
} else if (index - 1 === boundary.length - 2) {
if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
state = S.END;
flags = 0;
} else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
index = 0;
callback('onPartBegin');
state = S.HEADER_FIELD_START;
} else {
return;
}
break;
}
if (c !== boundary[index + 2]) {
index = -2;
}
if (c === boundary[index + 2]) {
index++;
}
break;
case S.HEADER_FIELD_START:
state = S.HEADER_FIELD;
mark('onHeaderField');
index = 0;
// falls through
case S.HEADER_FIELD:
if (c === CR) {
clear('onHeaderField');
state = S.HEADERS_ALMOST_DONE;
break;
}
index++;
if (c === HYPHEN) {
break;
}
if (c === COLON) {
if (index === 1) {
// empty header field
return;
}
dataCallback('onHeaderField', true);
state = S.HEADER_VALUE_START;
break;
}
cl = lower(c);
if (cl < A || cl > Z) {
return;
}
break;
case S.HEADER_VALUE_START:
if (c === SPACE) {
break;
}
mark('onHeaderValue');
state = S.HEADER_VALUE;
// falls through
case S.HEADER_VALUE:
if (c === CR) {
dataCallback('onHeaderValue', true);
callback('onHeaderEnd');
state = S.HEADER_VALUE_ALMOST_DONE;
}
break;
case S.HEADER_VALUE_ALMOST_DONE:
if (c !== LF) {
return;
}
state = S.HEADER_FIELD_START;
break;
case S.HEADERS_ALMOST_DONE:
if (c !== LF) {
return;
}
callback('onHeadersEnd');
state = S.PART_DATA_START;
break;
case S.PART_DATA_START:
state = S.PART_DATA;
mark('onPartData');
// falls through
case S.PART_DATA:
previousIndex = index;
if (index === 0) {
// boyer-moore derrived algorithm to safely skip non-boundary data
i += boundaryEnd;
while (i < bufferLength && !(data[i] in boundaryChars)) {
i += boundaryLength;
}
i -= boundaryEnd;
c = data[i];
}
if (index < boundary.length) {
if (boundary[index] === c) {
if (index === 0) {
dataCallback('onPartData', true);
}
index++;
} else {
index = 0;
}
} else if (index === boundary.length) {
index++;
if (c === CR) {
// CR = part boundary
flags |= F.PART_BOUNDARY;
} else if (c === HYPHEN) {
// HYPHEN = end boundary
flags |= F.LAST_BOUNDARY;
} else {
index = 0;
}
} else if (index - 1 === boundary.length) {
if (flags & F.PART_BOUNDARY) {
index = 0;
if (c === LF) {
// unset the PART_BOUNDARY flag
flags &= ~F.PART_BOUNDARY;
callback('onPartEnd');
callback('onPartBegin');
state = S.HEADER_FIELD_START;
break;
}
} else if (flags & F.LAST_BOUNDARY) {
if (c === HYPHEN) {
callback('onPartEnd');
state = S.END;
flags = 0;
} else {
index = 0;
}
} else {
index = 0;
}
}
if (index > 0) {
// when matching a possible boundary, keep a lookbehind reference
// in case it turns out to be a false lead
lookbehind[index - 1] = c;
} else if (previousIndex > 0) {
// if our boundary turned out to be rubbish, the captured lookbehind
// belongs to partData
const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
callback('onPartData', 0, previousIndex, _lookbehind);
previousIndex = 0;
mark('onPartData');
// reconsider the current character even so it interrupted the sequence
// it could be the beginning of a new sequence
i--;
}
break;
case S.END:
break;
default:
throw new Error(`Unexpected state entered: ${state}`);
}
}
dataCallback('onHeaderField');
dataCallback('onHeaderValue');
dataCallback('onPartData');
// Update properties for the next call
this.index = index;
this.state = state;
this.flags = flags;
}
end() {
if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
(this.state === S.PART_DATA && this.index === this.boundary.length)) {
this.onPartEnd();
} else if (this.state !== S.END) {
throw new Error('MultipartParser.end(): stream ended unexpectedly');
}
}
}
function _fileName(headerValue) {
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
if (!m) {
return;
}
const match = m[2] || m[3] || '';
let filename = match.slice(match.lastIndexOf('\\') + 1);
filename = filename.replace(/%22/g, '"');
filename = filename.replace(/&#(\d{4});/g, (m, code) => {
return String.fromCharCode(code);
});
return filename;
}
async function toFormData(Body, ct) {
if (!/multipart/i.test(ct)) {
throw new TypeError('Failed to fetch');
}
const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
if (!m) {
throw new TypeError('no or bad content-type header, no multipart boundary');
}
const parser = new MultipartParser(m[1] || m[2]);
let headerField;
let headerValue;
let entryValue;
let entryName;
let contentType;
let filename;
const entryChunks = [];
const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .Ct();
const onPartData = ui8a => {
entryValue += decoder.decode(ui8a, {stream: true});
};
const appendToFile = ui8a => {
entryChunks.push(ui8a);
};
const appendFileToFormData = () => {
const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .$B(entryChunks, filename, {type: contentType});
formData.append(entryName, file);
};
const appendEntryToFormData = () => {
formData.append(entryName, entryValue);
};
const decoder = new TextDecoder('utf-8');
decoder.decode();
parser.onPartBegin = function () {
parser.onPartData = onPartData;
parser.onPartEnd = appendEntryToFormData;
headerField = '';
headerValue = '';
entryValue = '';
entryName = '';
contentType = '';
filename = null;
entryChunks.length = 0;
};
parser.onHeaderField = function (ui8a) {
headerField += decoder.decode(ui8a, {stream: true});
};
parser.onHeaderValue = function (ui8a) {
headerValue += decoder.decode(ui8a, {stream: true});
};
parser.onHeaderEnd = function () {
headerValue += decoder.decode();
headerField = headerField.toLowerCase();
if (headerField === 'content-disposition') {
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
if (m) {
entryName = m[2] || m[3] || '';
}
filename = _fileName(headerValue);
if (filename) {
parser.onPartData = appendToFile;
parser.onPartEnd = appendFileToFormData;
}
} else if (headerField === 'content-type') {
contentType = headerValue;
}
headerValue = '';
headerField = '';
};
for await (const chunk of Body) {
parser.write(chunk);
}
parser.end();
return formData;
}
/***/ })
};
;
//# sourceMappingURL=37.index.js.map

File diff suppressed because one or more lines are too long

453
dist/629.index.js vendored
View file

@ -1,453 +0,0 @@
exports.id = 629;
exports.ids = [629];
exports.modules = {
/***/ 6629:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "toFormData": () => (/* binding */ toFormData)
/* harmony export */ });
/* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4818);
/* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1402);
let s = 0;
const S = {
START_BOUNDARY: s++,
HEADER_FIELD_START: s++,
HEADER_FIELD: s++,
HEADER_VALUE_START: s++,
HEADER_VALUE: s++,
HEADER_VALUE_ALMOST_DONE: s++,
HEADERS_ALMOST_DONE: s++,
PART_DATA_START: s++,
PART_DATA: s++,
END: s++
};
let f = 1;
const F = {
PART_BOUNDARY: f,
LAST_BOUNDARY: f *= 2
};
const LF = 10;
const CR = 13;
const SPACE = 32;
const HYPHEN = 45;
const COLON = 58;
const A = 97;
const Z = 122;
const lower = c => c | 0x20;
const noop = () => {};
class MultipartParser {
/**
* @param {string} boundary
*/
constructor(boundary) {
this.index = 0;
this.flags = 0;
this.onHeaderEnd = noop;
this.onHeaderField = noop;
this.onHeadersEnd = noop;
this.onHeaderValue = noop;
this.onPartBegin = noop;
this.onPartData = noop;
this.onPartEnd = noop;
this.boundaryChars = {};
boundary = '\r\n--' + boundary;
const ui8a = new Uint8Array(boundary.length);
for (let i = 0; i < boundary.length; i++) {
ui8a[i] = boundary.charCodeAt(i);
this.boundaryChars[ui8a[i]] = true;
}
this.boundary = ui8a;
this.lookbehind = new Uint8Array(this.boundary.length + 8);
this.state = S.START_BOUNDARY;
}
/**
* @param {Uint8Array} data
*/
write(data) {
let i = 0;
const length_ = data.length;
let previousIndex = this.index;
let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
const boundaryLength = this.boundary.length;
const boundaryEnd = boundaryLength - 1;
const bufferLength = data.length;
let c;
let cl;
const mark = name => {
this[name + 'Mark'] = i;
};
const clear = name => {
delete this[name + 'Mark'];
};
const callback = (callbackSymbol, start, end, ui8a) => {
if (start === undefined || start !== end) {
this[callbackSymbol](ui8a && ui8a.subarray(start, end));
}
};
const dataCallback = (name, clear) => {
const markSymbol = name + 'Mark';
if (!(markSymbol in this)) {
return;
}
if (clear) {
callback(name, this[markSymbol], i, data);
delete this[markSymbol];
} else {
callback(name, this[markSymbol], data.length, data);
this[markSymbol] = 0;
}
};
for (i = 0; i < length_; i++) {
c = data[i];
switch (state) {
case S.START_BOUNDARY:
if (index === boundary.length - 2) {
if (c === HYPHEN) {
flags |= F.LAST_BOUNDARY;
} else if (c !== CR) {
return;
}
index++;
break;
} else if (index - 1 === boundary.length - 2) {
if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
state = S.END;
flags = 0;
} else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
index = 0;
callback('onPartBegin');
state = S.HEADER_FIELD_START;
} else {
return;
}
break;
}
if (c !== boundary[index + 2]) {
index = -2;
}
if (c === boundary[index + 2]) {
index++;
}
break;
case S.HEADER_FIELD_START:
state = S.HEADER_FIELD;
mark('onHeaderField');
index = 0;
// falls through
case S.HEADER_FIELD:
if (c === CR) {
clear('onHeaderField');
state = S.HEADERS_ALMOST_DONE;
break;
}
index++;
if (c === HYPHEN) {
break;
}
if (c === COLON) {
if (index === 1) {
// empty header field
return;
}
dataCallback('onHeaderField', true);
state = S.HEADER_VALUE_START;
break;
}
cl = lower(c);
if (cl < A || cl > Z) {
return;
}
break;
case S.HEADER_VALUE_START:
if (c === SPACE) {
break;
}
mark('onHeaderValue');
state = S.HEADER_VALUE;
// falls through
case S.HEADER_VALUE:
if (c === CR) {
dataCallback('onHeaderValue', true);
callback('onHeaderEnd');
state = S.HEADER_VALUE_ALMOST_DONE;
}
break;
case S.HEADER_VALUE_ALMOST_DONE:
if (c !== LF) {
return;
}
state = S.HEADER_FIELD_START;
break;
case S.HEADERS_ALMOST_DONE:
if (c !== LF) {
return;
}
callback('onHeadersEnd');
state = S.PART_DATA_START;
break;
case S.PART_DATA_START:
state = S.PART_DATA;
mark('onPartData');
// falls through
case S.PART_DATA:
previousIndex = index;
if (index === 0) {
// boyer-moore derrived algorithm to safely skip non-boundary data
i += boundaryEnd;
while (i < bufferLength && !(data[i] in boundaryChars)) {
i += boundaryLength;
}
i -= boundaryEnd;
c = data[i];
}
if (index < boundary.length) {
if (boundary[index] === c) {
if (index === 0) {
dataCallback('onPartData', true);
}
index++;
} else {
index = 0;
}
} else if (index === boundary.length) {
index++;
if (c === CR) {
// CR = part boundary
flags |= F.PART_BOUNDARY;
} else if (c === HYPHEN) {
// HYPHEN = end boundary
flags |= F.LAST_BOUNDARY;
} else {
index = 0;
}
} else if (index - 1 === boundary.length) {
if (flags & F.PART_BOUNDARY) {
index = 0;
if (c === LF) {
// unset the PART_BOUNDARY flag
flags &= ~F.PART_BOUNDARY;
callback('onPartEnd');
callback('onPartBegin');
state = S.HEADER_FIELD_START;
break;
}
} else if (flags & F.LAST_BOUNDARY) {
if (c === HYPHEN) {
callback('onPartEnd');
state = S.END;
flags = 0;
} else {
index = 0;
}
} else {
index = 0;
}
}
if (index > 0) {
// when matching a possible boundary, keep a lookbehind reference
// in case it turns out to be a false lead
lookbehind[index - 1] = c;
} else if (previousIndex > 0) {
// if our boundary turned out to be rubbish, the captured lookbehind
// belongs to partData
const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
callback('onPartData', 0, previousIndex, _lookbehind);
previousIndex = 0;
mark('onPartData');
// reconsider the current character even so it interrupted the sequence
// it could be the beginning of a new sequence
i--;
}
break;
case S.END:
break;
default:
throw new Error(`Unexpected state entered: ${state}`);
}
}
dataCallback('onHeaderField');
dataCallback('onHeaderValue');
dataCallback('onPartData');
// Update properties for the next call
this.index = index;
this.state = state;
this.flags = flags;
}
end() {
if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
(this.state === S.PART_DATA && this.index === this.boundary.length)) {
this.onPartEnd();
} else if (this.state !== S.END) {
throw new Error('MultipartParser.end(): stream ended unexpectedly');
}
}
}
function _fileName(headerValue) {
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
if (!m) {
return;
}
const match = m[2] || m[3] || '';
let filename = match.slice(match.lastIndexOf('\\') + 1);
filename = filename.replace(/%22/g, '"');
filename = filename.replace(/&#(\d{4});/g, (m, code) => {
return String.fromCharCode(code);
});
return filename;
}
async function toFormData(Body, ct) {
if (!/multipart/i.test(ct)) {
throw new TypeError('Failed to fetch');
}
const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
if (!m) {
throw new TypeError('no or bad content-type header, no multipart boundary');
}
const parser = new MultipartParser(m[1] || m[2]);
let headerField;
let headerValue;
let entryValue;
let entryName;
let contentType;
let filename;
const entryChunks = [];
const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .Ct();
const onPartData = ui8a => {
entryValue += decoder.decode(ui8a, {stream: true});
};
const appendToFile = ui8a => {
entryChunks.push(ui8a);
};
const appendFileToFormData = () => {
const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .$B(entryChunks, filename, {type: contentType});
formData.append(entryName, file);
};
const appendEntryToFormData = () => {
formData.append(entryName, entryValue);
};
const decoder = new TextDecoder('utf-8');
decoder.decode();
parser.onPartBegin = function () {
parser.onPartData = onPartData;
parser.onPartEnd = appendEntryToFormData;
headerField = '';
headerValue = '';
entryValue = '';
entryName = '';
contentType = '';
filename = null;
entryChunks.length = 0;
};
parser.onHeaderField = function (ui8a) {
headerField += decoder.decode(ui8a, {stream: true});
};
parser.onHeaderValue = function (ui8a) {
headerValue += decoder.decode(ui8a, {stream: true});
};
parser.onHeaderEnd = function () {
headerValue += decoder.decode();
headerField = headerField.toLowerCase();
if (headerField === 'content-disposition') {
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
if (m) {
entryName = m[2] || m[3] || '';
}
filename = _fileName(headerValue);
if (filename) {
parser.onPartData = appendToFile;
parser.onPartEnd = appendFileToFormData;
}
} else if (headerField === 'content-type') {
contentType = headerValue;
}
headerValue = '';
headerField = '';
};
for await (const chunk of Body) {
parser.write(chunk);
}
parser.end();
return formData;
}
/***/ })
};
;
//# sourceMappingURL=629.index.js.map

File diff suppressed because one or more lines are too long

32826
dist/index.js vendored

File diff suppressed because one or more lines are too long

1
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

0
dist/pgp_keys.asc vendored Normal file → Executable file
View file

22
dist/scripts/determine_os.sh vendored Executable file
View file

@ -0,0 +1,22 @@
family=$(uname -s | tr '[:upper:]' '[:lower:]')
codecov_os="windows"
[[ $family == "darwin" ]] && codecov_os="macos"
[[ $family == "linux" ]] && codecov_os="linux"
[[ $codecov_os == "linux" ]] && \
osID=$(grep -e "^ID=" /etc/os-release | cut -c4-)
[[ $osID == "alpine" ]] && codecov_os="alpine"
echo "Detected ${codecov_os}"
echo "export codecov_os=${codecov_os}" >> $BASH_ENV
echo "export codecov_version=${PARAM_VERSION}" >> $BASH_ENV
codecov_filename="codecov"
[[ $codecov_os == "windows" ]] && codecov_filename+=".exe"
echo "export codecov_filename=${codecov_filename}" >> $BASH_ENV
[[ $codecov_os == "macos" ]] && \
HOMEBREW_NO_AUTO_UPDATE=1 brew install gpg
codecov_url="https://cli.codecov.io"
codecov_url="$codecov_url/${PARAM_VERSION}"
codecov_url="$codecov_url/${codecov_os}/${codecov_filename}"
echo "Downloading ${codecov_url}"
curl -Os $codecov_url -v

22
dist/scripts/download.sh vendored Executable file
View file

@ -0,0 +1,22 @@
family=$(uname -s | tr '[:upper:]' '[:lower:]')
codecov_os="windows"
[[ $family == "darwin" ]] && codecov_os="macos"
[[ $family == "linux" ]] && codecov_os="linux"
[[ $codecov_os == "linux" ]] && \
osID=$(grep -e "^ID=" /etc/os-release | cut -c4-)
[[ $osID == "alpine" ]] && codecov_os="alpine"
echo "Detected ${codecov_os}"
echo "export codecov_os=${codecov_os}" >> $BASH_ENV
echo "export codecov_version=${PARAM_VERSION}" >> $BASH_ENV
codecov_filename="codecov"
[[ $codecov_os == "windows" ]] && codecov_filename+=".exe"
echo "export codecov_filename=${codecov_filename}" >> $BASH_ENV
[[ $codecov_os == "macos" ]] && \
HOMEBREW_NO_AUTO_UPDATE=1 brew install gpg
codecov_url="https://cli.codecov.io"
codecov_url="$codecov_url/${PARAM_VERSION}"
codecov_url="$codecov_url/${codecov_os}/${codecov_filename}"
echo "Downloading ${codecov_url}"
curl -Os $codecov_url -v

64
dist/scripts/upload.sh vendored Executable file
View file

@ -0,0 +1,64 @@
unset NODE_OPTIONS
# See https://github.com/codecov/uploader/issues/475
source $BASH_ENV
chmod +x $codecov_filename
[ -n "${PARAM_FILE}" ] && \
set - "${@}" "-f" "${PARAM_FILE}"
[ -n "${PARAM_UPLOAD_ARGS}" ] && \
set - "${@}" "${PARAM_UPLOAD_ARGS}"
if [ -z "${PARAM_UPLOAD_NAME}" ]; then
PARAM_UPLOAD_NAME="${CIRCLE_BUILD_NUM}"
fi
FLAGS=""
OLDIFS=$IFS;IFS=,
for flag in $PARAM_FLAGS; do
eval e="\$$flag"
for param in "${e}" "${flag}"; do
if [ -n "${param}" ]; then
if [ -n "${FLAGS}" ]; then
FLAGS="${FLAGS},${param}"
else
FLAGS="${param}"
fi
break
fi
done
done
IFS=$OLDIFS
if [ -n "$FLAGS" ]; then
FLAGS="-F ${FLAGS}"
fi
#create commit
echo "./\"$codecov_filename\" ${PARAM_CLI_ARGS} create-commit -t <redacted>"
./"$codecov_filename" \
${PARAM_CLI_ARGS} \
create-commit \
-t "$(eval echo \$$PARAM_TOKEN)"
#create report
echo "./\"$codecov_filename\" ${PARAM_CLI_ARGS} create-report -t <redacted>"
./"$codecov_filename" \
${PARAM_CLI_ARGS} \
create-report \
-t "$(eval echo \$$PARAM_TOKEN)"
#upload reports
# alpine doesn't allow for indirect expansion
echo "./${codecov_filename} ${PARAM_CLI_ARGS} do-upload -t <redacted> -n \"${PARAM_UPLOAD_NAME}\" ${FLAGS} ${PARAM_UPLOAD_ARGS} ${@}"
./"$codecov_filename" \
${PARAM_CLI_ARGS} \
do-upload \
-t "$(eval echo \$$PARAM_TOKEN)" \
-n "${PARAM_UPLOAD_NAME}" \
${FLAGS} \
${PARAM_UPLOAD_ARGS} \
${@}

13
dist/scripts/validate.sh vendored Executable file
View file

@ -0,0 +1,13 @@
source "$BASH_ENV"
echo "${CODECOV_PUBLIC_PGP_KEY}" | \
gpg --no-default-keyring --keyring trustedkeys.kbx --import
# One-time step
sha_url="https://cli.codecov.io"
sha_url="${sha_url}/${codecov_version}/${codecov_os}"
sha_url="${sha_url}/${codecov_filename}.SHA256SUM"
echo "Downloading ${sha_url}"
curl -Os "$sha_url"
curl -Os "${sha_url}.sig"
gpgv "${codecov_filename}.SHA256SUM.sig" "${codecov_filename}.SHA256SUM"
shasum -a 256 -c "${codecov_filename}.SHA256SUM" || \
sha256sum -c "${codecov_filename}.SHA256SUM"

File diff suppressed because one or more lines are too long

View file

@ -2,9 +2,6 @@
set -e
npm install
npm run lint
npm run build
chmod u+x dist/test.sh
cp -r src/scripts dist/
chmod -R u+x dist/scripts/
git add dist/
git add package-lock.json

View file

@ -1,4 +0,0 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

9207
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,44 +0,0 @@
{
"name": "codecov-action",
"version": "4.1.0",
"description": "Upload coverage reports to Codecov from GitHub Actions",
"main": "index.js",
"scripts": {
"build": "ncc build src/index.ts --source-map",
"lint": "eslint src/**/*.ts",
"test": "npm run test-script && npm run test-calculator && npm run test-coverage",
"test-calculator": "jest --testPathPattern=demo/calculator/ --coverage --coverageDirectory=coverage/calculator",
"test-coverage": "jest --testPathPattern=demo/coverage-test/ --coverage --coverageDirectory=coverage/coverage-test",
"test-script": "jest --testPathPattern=src/ --coverage --coverageDirectory=coverage/script"
},
"repository": {
"type": "git",
"url": "git+https://github.com/codecov/codecov-action.git"
},
"keywords": [],
"author": "Codecov",
"license": "MIT",
"bugs": {
"url": "https://github.com/codecov/codecov-action/issues"
},
"homepage": "https://github.com/codecov/codecov-action#readme",
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
"gpg": "^0.6.0",
"undici": "5.28.2"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^6.21.0",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"jest": "^29.7.0",
"jest-junit": "^16.0.0",
"ts-jest": "^29.1.2",
"typescript": "^5.4.2"
}
}

View file

@ -1,274 +0,0 @@
import * as github from '@actions/github';
import {
buildCommitExec,
buildGeneralExec,
buildReportExec,
buildUploadExec,
} from './buildExec';
const context = github.context;
test('general args', () => {
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} = 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', () => {
const expectedArgs = [
'--git-service',
'github',
];
const {uploadExecArgs, uploadCommand} = 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', () => {
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',
'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} = 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',
'-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', () => {
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} = 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', () => {
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} = 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', () => {
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} = 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', () => {
const expectedArgs :string[] = [
'--git-service',
'github',
];
const {commitExecArgs, commitCommand} = buildCommitExec();
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');
});

View file

@ -1,330 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as core from '@actions/core';
import * as github from '@actions/github';
const context = github.context;
const isTrue = (variable) => {
const lowercase = variable.toLowerCase();
return (
lowercase === '1' ||
lowercase === 't' ||
lowercase === 'true' ||
lowercase === 'y' ||
lowercase === 'yes'
);
};
const buildCommitExec = () => {
const commitParent = core.getInput('commit_parent');
const gitService = core.getInput('git_service');
const overrideBranch = core.getInput('override_branch');
const overrideCommit = core.getInput('override_commit');
const overridePr = core.getInput('override_pr');
const slug = core.getInput('slug');
const token = core.getInput('token');
const failCi = isTrue(core.getInput('fail_ci_if_error'));
const workingDir = core.getInput('working-directory');
const commitCommand = 'create-commit';
const commitExecArgs = [];
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 ? gitService : 'github'}`);
if (overrideBranch) {
commitExecArgs.push('-B', `${overrideBranch}`);
}
if (overrideCommit) {
commitExecArgs.push('-C', `${overrideCommit}`);
} else if (
`${context.eventName}` == 'pull_request' ||
`${context.eventName}` == 'pull_request_target'
) {
commitExecArgs.push('-C', `${context.payload.pull_request.head.sha}`);
}
if (overridePr) {
commitExecArgs.push('--pr', `${overridePr}`);
} else if (
`${context.eventName}` == 'pull_request_target'
) {
commitExecArgs.push('--pr', `${context.payload.number}`);
}
if (slug) {
commitExecArgs.push('--slug', `${slug}`);
}
if (failCi) {
commitExecArgs.push('-Z');
}
if (workingDir) {
commitOptions.cwd = workingDir;
}
return {commitExecArgs, commitOptions, commitCommand};
};
const buildGeneralExec = () => {
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 = () => {
const gitService = core.getInput('git_service');
const overrideCommit = core.getInput('override_commit');
const overridePr = core.getInput('override_pr');
const slug = core.getInput('slug');
const token = core.getInput('token');
const failCi = isTrue(core.getInput('fail_ci_if_error'));
const workingDir = core.getInput('working-directory');
const reportCommand = 'create-report';
const reportExecArgs = [];
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 ? gitService : 'github'}`);
if (overrideCommit) {
reportExecArgs.push('-C', `${overrideCommit}`);
} else if (
`${context.eventName}` == 'pull_request' ||
`${context.eventName}` == 'pull_request_target'
) {
reportExecArgs.push('-C', `${context.payload.pull_request.head.sha}`);
}
if (overridePr) {
reportExecArgs.push('-P', `${overridePr}`);
} else if (
`${context.eventName}` == 'pull_request_target'
) {
reportExecArgs.push('-P', `${context.payload.number}`);
}
if (slug) {
reportExecArgs.push('--slug', `${slug}`);
}
if (failCi) {
reportExecArgs.push('-Z');
}
if (workingDir) {
reportOptions.cwd = workingDir;
}
return {reportExecArgs, reportOptions, reportCommand};
};
const buildUploadExec = () => {
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 = core.getInput('git_service');
const handleNoReportsFound = isTrue(core.getInput('handle_no_reports_found'));
const jobCode = core.getInput('job_code');
const name = core.getInput('name');
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 = core.getInput('token');
let uploaderVersion = core.getInput('version');
const useLegacyUploadEndpoint = isTrue(
core.getInput('use_legacy_upload_endpoint'),
);
const workingDir = core.getInput('working-directory');
const uploadExecArgs = [];
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) => {
uploadExecArgs.push('-f', `${f}`);
});
}
if (flags) {
flags.split(',').map((f) => f.trim()).forEach((f) => {
uploadExecArgs.push('-F', `${f}`);
});
}
uploadExecArgs.push('--git-service', `${gitService ? gitService : 'github'}`);
if (handleNoReportsFound) {
uploadExecArgs.push('--handle-no-reports-found');
}
if (jobCode) {
uploadExecArgs.push('--job-code', `${jobCode}`);
}
if (name) {
uploadExecArgs.push('-n', `${name}`);
}
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 (
`${context.eventName}` == 'pull_request' ||
`${context.eventName}` == 'pull_request_target'
) {
uploadExecArgs.push('-C', `${context.payload.pull_request.head.sha}`);
}
if (overridePr) {
uploadExecArgs.push('-P', `${overridePr}`);
} else if (
`${context.eventName}` == 'pull_request_target'
) {
uploadExecArgs.push('-P', `${context.payload.number}`);
}
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,
};

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,91 +0,0 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
const PLATFORMS = [
'linux',
'macos',
'windows',
'alpine',
'linux-arm64',
'alpine-arm64',
];
const setFailure = (message: string, failCi: boolean): void => {
failCi ? core.setFailed(message) : 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): boolean => {
return PLATFORMS.includes(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,125 +0,0 @@
import * as fs from 'fs';
import * as https from 'https';
import * as path from '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;
try {
const {commitExecArgs, commitOptions, commitCommand} = buildCommitExec();
const {reportExecArgs, reportOptions, reportCommand} = buildReportExec();
const {
uploadExecArgs,
uploadOptions,
disableSafeDirectory,
failCi,
os,
uploaderVersion,
uploadCommand,
} = 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 = () => {
fs.unlink(filename, (err) => {
if (err) {
setFailure(
`Codecov: Could not unlink uploader: ${err.message}`,
failCi,
);
}
});
};
const doUpload = async () => {
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 () => {
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);
}

View file

@ -0,0 +1,22 @@
family=$(uname -s | tr '[:upper:]' '[:lower:]')
codecov_os="windows"
[[ $family == "darwin" ]] && codecov_os="macos"
[[ $family == "linux" ]] && codecov_os="linux"
[[ $codecov_os == "linux" ]] && \
osID=$(grep -e "^ID=" /etc/os-release | cut -c4-)
[[ $osID == "alpine" ]] && codecov_os="alpine"
echo "Detected ${codecov_os}"
echo "export codecov_os=${codecov_os}" >> $BASH_ENV
echo "export codecov_version=${PARAM_VERSION}" >> $BASH_ENV
codecov_filename="codecov"
[[ $codecov_os == "windows" ]] && codecov_filename+=".exe"
echo "export codecov_filename=${codecov_filename}" >> $BASH_ENV
[[ $codecov_os == "macos" ]] && \
HOMEBREW_NO_AUTO_UPDATE=1 brew install gpg
codecov_url="https://cli.codecov.io"
codecov_url="$codecov_url/${PARAM_VERSION}"
codecov_url="$codecov_url/${codecov_os}/${codecov_filename}"
echo "Downloading ${codecov_url}"
curl -Os $codecov_url -v

View file

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

View file

@ -1,116 +0,0 @@
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as gpg from 'gpg';
import * as path from 'path';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
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> => {
await exec.exec(path.join(__dirname, 'test.sh'));
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 = () => {
gpg.call('', [
'--logger-fd',
'1',
'--verify',
path.join(__dirname, `${uploaderName}.SHA256SUM.sig`),
path.join(__dirname, `${uploaderName}.SHA256SUM`),
], async (err, verifyResult) => {
if (err) {
setFailure('Codecov: Error importing pgp key', failCi);
}
core.info(verifyResult);
await validateSha();
});
};
// Import gpg key
gpg.call('', [
'--logger-fd',
'1',
'--no-default-keyring',
'--import',
path.join(__dirname, 'pgp_keys.asc'),
], async (err, importResult) => {
if (err) {
setFailure('Codecov: Error importing pgp key', failCi);
}
core.info(importResult);
verifySignature();
});
} catch (err) {
setFailure(`Codecov: Error validating uploader: ${err.message}`, failCi);
}
};
export default verify;

View file

@ -1,22 +0,0 @@
import * as core from '@actions/core';
import {request} from 'undici';
const versionInfo = async (
platform: string,
version?: string,
): Promise<void> => {
if (version) {
core.info(`==> Running version ${version}`);
}
try {
const metadataRes = await request(`https://cli.codecov.io/${platform}/latest`, {
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;

View file

@ -1,17 +0,0 @@
{
"compilerOptions": {
"esModuleInterop": true,
"moduleResolution": "node",
"outDir": "dist/",
"resolveJsonModule": true,
"rootDir": ".",
"sourceMap": true,
"target": "es2015"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/**/*.test.ts"
]
}