mirror of
https://github.com/golangci/golangci-lint-action.git
synced 2025-12-16 07:28:27 +00:00
Comprehensive Chech Run ID Resolution
This was surprisingly difficult. This is pretty reliable, using low-cost methods (filtering on Name comparison, Annotation count [we add one, so it should have atleast one]) and then searching for a unique string if the count is still higher than 1. I'm pretty happy about this, I think this will stand the test of time until GitHub get's their act together...
This commit is contained in:
parent
6910ba7f87
commit
aa82c092a1
3 changed files with 710 additions and 551 deletions
549
dist/post_run/index.js
vendored
549
dist/post_run/index.js
vendored
|
|
@ -2505,7 +2505,7 @@ exports.toCommandValue = toCommandValue;
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
var rng = __webpack_require__(139);
|
var rng = __webpack_require__(139);
|
||||||
var bytesToUuid = __webpack_require__(105);
|
var bytesToUuid = __webpack_require__(722);
|
||||||
|
|
||||||
// **`v1()` - Generate time-based UUID**
|
// **`v1()` - Generate time-based UUID**
|
||||||
//
|
//
|
||||||
|
|
@ -3769,38 +3769,7 @@ var _default = version;
|
||||||
exports.default = _default;
|
exports.default = _default;
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 105 */
|
/* 105 */,
|
||||||
/***/ (function(module) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert array of 16 byte values to UUID string format of the form:
|
|
||||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
||||||
*/
|
|
||||||
var byteToHex = [];
|
|
||||||
for (var i = 0; i < 256; ++i) {
|
|
||||||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bytesToUuid(buf, offset) {
|
|
||||||
var i = offset || 0;
|
|
||||||
var bth = byteToHex;
|
|
||||||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
|
||||||
return ([
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]]
|
|
||||||
]).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = bytesToUuid;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 106 */
|
/* 106 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
|
@ -6718,7 +6687,8 @@ const fs = __importStar(__webpack_require__(747));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
const tmp_1 = __webpack_require__(150);
|
const tmp_1 = __webpack_require__(150);
|
||||||
const util_1 = __webpack_require__(669);
|
const util_1 = __webpack_require__(669);
|
||||||
const cache_1 = __webpack_require__(722);
|
const uuid_1 = __webpack_require__(930);
|
||||||
|
const cache_1 = __webpack_require__(913);
|
||||||
const install_1 = __webpack_require__(655);
|
const install_1 = __webpack_require__(655);
|
||||||
const version_1 = __webpack_require__(52);
|
const version_1 = __webpack_require__(52);
|
||||||
const execShellCommand = util_1.promisify(child_process_1.exec);
|
const execShellCommand = util_1.promisify(child_process_1.exec);
|
||||||
|
|
@ -6787,6 +6757,8 @@ function fetchPatch() {
|
||||||
function prepareEnv() {
|
function prepareEnv() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
|
// Resolve Check Run ID
|
||||||
|
const resolveCheckRunIdPromise = resolveCheckRunId();
|
||||||
// Prepare cache, lint and go in parallel.
|
// Prepare cache, lint and go in parallel.
|
||||||
const restoreCachePromise = cache_1.restoreCache();
|
const restoreCachePromise = cache_1.restoreCache();
|
||||||
const prepareLintPromise = prepareLint();
|
const prepareLintPromise = prepareLint();
|
||||||
|
|
@ -6796,8 +6768,9 @@ function prepareEnv() {
|
||||||
yield installGoPromise;
|
yield installGoPromise;
|
||||||
yield restoreCachePromise;
|
yield restoreCachePromise;
|
||||||
const patchPath = yield patchPromise;
|
const patchPath = yield patchPromise;
|
||||||
|
const checkRunId = yield resolveCheckRunIdPromise;
|
||||||
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
|
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
|
||||||
return { lintPath, patchPath };
|
return { lintPath, patchPath, checkRunId };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var LintSeverity;
|
var LintSeverity;
|
||||||
|
|
@ -6851,26 +6824,78 @@ const logLintIssues = (issues) => {
|
||||||
core.info(`${header} ${pos} - ${issue.Text} (${issue.FromLinter})`);
|
core.info(`${header} ${pos} - ${issue.Text} (${issue.FromLinter})`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
function annotateLintIssues(issues) {
|
function resolveCheckRunId() {
|
||||||
var _a;
|
var _a, _b, _c;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!issues.length) {
|
let checkRunId = -1;
|
||||||
|
if (process.env.GITHUB_ACTIONS === `true`) {
|
||||||
|
try {
|
||||||
|
const searchToken = uuid_1.v4();
|
||||||
|
core.info(`::warning::Resolving GitHub CheckRunID (${searchToken})`);
|
||||||
|
const ctx = github.context;
|
||||||
|
const ref = (_a = ctx.payload.after) !== null && _a !== void 0 ? _a : ctx.sha;
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
||||||
|
const { data: checkRunsResponse } = yield octokit.checks
|
||||||
|
.listForRef(Object.assign(Object.assign({}, ctx.repo), { ref, status: `in_progress`, filter: `latest` }))
|
||||||
|
.catch((e) => {
|
||||||
|
throw `Unable to fetch Check Run List: ${e}`;
|
||||||
|
});
|
||||||
|
if (checkRunsResponse.check_runs.length > 0) {
|
||||||
|
let checkRuns = checkRunsResponse.check_runs;
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = (_b = checkRuns.filter((run) => run.name.includes(ctx.job))) !== null && _b !== void 0 ? _b : checkRuns;
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = (_c = checkRuns.filter((run) => run.output.annotations_count > 0)) !== null && _c !== void 0 ? _c : checkRuns;
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
for (const run of checkRuns) {
|
||||||
|
try {
|
||||||
|
if ((yield octokit.checks.listAnnotations(Object.assign(Object.assign({}, ctx.repo), { check_run_id: run.id }))).data.findIndex((annotation) => annotation.message.includes(searchToken)) !== -1) {
|
||||||
|
checkRunId = run.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
core.info(`::debug::Error Fetching CheckRun ${run.id}: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (checkRuns[0]) {
|
||||||
|
checkRunId = checkRuns[0].id;
|
||||||
|
core.info(`Current Check Run is: ${checkRunId}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw `Unable to resolve GitHub Check Run`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw `Fetching octokit.checks.listForRef(${ref}) returned no results`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
core.info(`::error::Error resolving GitHub Check Run: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info(`::debug::Not in GitHub Action Context, Skipping Check Run Resolution`);
|
||||||
|
}
|
||||||
|
return checkRunId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function annotateLintIssues(issues, checkRunId) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (checkRunId === -1 || !issues.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ctx = github.context;
|
|
||||||
const ref = ctx.payload.after;
|
|
||||||
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
|
||||||
const checkRunsPromise = octokit.checks
|
|
||||||
.listForRef(Object.assign(Object.assign({}, ctx.repo), { ref, status: "in_progress" }))
|
|
||||||
.catch((e) => {
|
|
||||||
throw `Error getting Check Run Data: ${e}`;
|
|
||||||
});
|
|
||||||
const chunkSize = 50;
|
const chunkSize = 50;
|
||||||
const issueCounts = {
|
const issueCounts = {
|
||||||
notice: 0,
|
notice: 0,
|
||||||
warning: 0,
|
warning: 0,
|
||||||
failure: 0,
|
failure: 0,
|
||||||
};
|
};
|
||||||
|
const ctx = github.context;
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
||||||
const githubAnnotations = issues.map((issue) => {
|
const githubAnnotations = issues.map((issue) => {
|
||||||
// If/when we transition to comments, we would build the request structure here
|
// If/when we transition to comments, we would build the request structure here
|
||||||
const annotation = {
|
const annotation = {
|
||||||
|
|
@ -6904,22 +6929,11 @@ function annotateLintIssues(issues) {
|
||||||
}
|
}
|
||||||
return annotation;
|
return annotation;
|
||||||
});
|
});
|
||||||
let checkRun;
|
const title = `GolangCI-Lint`;
|
||||||
const { data: checkRunsResponse } = yield checkRunsPromise;
|
|
||||||
if (checkRunsResponse.check_runs.length === 0) {
|
|
||||||
throw `octokit.checks.listForRef(${ref}) returned no results`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
checkRun = checkRunsResponse.check_runs.find((run) => run.name.includes(`Lint`));
|
|
||||||
}
|
|
||||||
if (!(checkRun === null || checkRun === void 0 ? void 0 : checkRun.id)) {
|
|
||||||
throw `Could not find current check run`;
|
|
||||||
}
|
|
||||||
const title = (_a = checkRun.output.title) !== null && _a !== void 0 ? _a : `GolangCI-Lint`;
|
|
||||||
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`;
|
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`;
|
||||||
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) => githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)).forEach((annotations) => {
|
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) => githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)).forEach((annotations) => {
|
||||||
octokit.checks
|
octokit.checks
|
||||||
.update(Object.assign(Object.assign({}, ctx.repo), { check_run_id: checkRun === null || checkRun === void 0 ? void 0 : checkRun.id, output: {
|
.update(Object.assign(Object.assign({}, ctx.repo), { check_run_id: checkRunId, output: {
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
annotations,
|
annotations,
|
||||||
|
|
@ -6961,14 +6975,14 @@ const printOutput = (res) => {
|
||||||
core.info(res.stderr);
|
core.info(res.stderr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function printLintOutput(res) {
|
function printLintOutput(res, checkRunId) {
|
||||||
var _a;
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let lintOutput;
|
let lintOutput;
|
||||||
const exit_code = (_a = res.code) !== null && _a !== void 0 ? _a : 0;
|
const exit_code = (_a = res.code) !== null && _a !== void 0 ? _a : 0;
|
||||||
try {
|
try {
|
||||||
try {
|
if (res.stdout) {
|
||||||
if (res.stdout) {
|
try {
|
||||||
// This object contains other information, such as errors and the active linters
|
// This object contains other information, such as errors and the active linters
|
||||||
// TODO: Should we do something with that data?
|
// TODO: Should we do something with that data?
|
||||||
lintOutput = parseOutput(res.stdout);
|
lintOutput = parseOutput(res.stdout);
|
||||||
|
|
@ -6980,7 +6994,7 @@ function printLintOutput(res) {
|
||||||
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case `push`:
|
case `push`:
|
||||||
yield annotateLintIssues(lintOutput.Issues);
|
yield annotateLintIssues(lintOutput.Issues, checkRunId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// At this time, other events are not supported
|
// At this time, other events are not supported
|
||||||
|
|
@ -6988,22 +7002,20 @@ function printLintOutput(res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (e) {
|
||||||
catch (e) {
|
throw `there was an error processing golangci-lint output: ${e}`;
|
||||||
throw `there was an error processing golangci-lint output: ${e}`;
|
}
|
||||||
}
|
}
|
||||||
if (res.stderr) {
|
if (res.stderr) {
|
||||||
core.info(res.stderr);
|
core.info(res.stderr);
|
||||||
}
|
}
|
||||||
if (exit_code === 1) {
|
if (exit_code === 1) {
|
||||||
if (lintOutput) {
|
if (!lintOutput) {
|
||||||
if (hasFailingIssues(lintOutput.Issues)) {
|
|
||||||
throw `issues found`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`;
|
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`;
|
||||||
}
|
}
|
||||||
|
if (hasFailingIssues(lintOutput.Issues)) {
|
||||||
|
throw `issues found`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (exit_code > 1) {
|
else if (exit_code > 1) {
|
||||||
throw `golangci-lint exit with code ${exit_code}`;
|
throw `golangci-lint exit with code ${exit_code}`;
|
||||||
|
|
@ -7015,7 +7027,7 @@ function printLintOutput(res) {
|
||||||
return core.info(`golangci-lint found no blocking issues`);
|
return core.info(`golangci-lint found no blocking issues`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function runLint(lintPath, patchPath) {
|
function runLint(lintPath, patchPath, checkRunId) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const debug = core.getInput(`debug`);
|
const debug = core.getInput(`debug`);
|
||||||
if (debug.split(`,`).includes(`cache`)) {
|
if (debug.split(`,`).includes(`cache`)) {
|
||||||
|
|
@ -7065,12 +7077,12 @@ function runLint(lintPath, patchPath) {
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
try {
|
try {
|
||||||
const res = yield execShellCommand(cmd, cmdArgs);
|
const res = yield execShellCommand(cmd, cmdArgs);
|
||||||
yield printLintOutput(res);
|
yield printLintOutput(res, checkRunId);
|
||||||
}
|
}
|
||||||
catch (exc) {
|
catch (exc) {
|
||||||
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
||||||
// TODO: support reviewdog or leaving comments by GitHub API.
|
// TODO: support reviewdog or leaving comments by GitHub API.
|
||||||
yield printLintOutput(exc);
|
yield printLintOutput(exc, checkRunId);
|
||||||
}
|
}
|
||||||
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
|
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
|
||||||
});
|
});
|
||||||
|
|
@ -7078,9 +7090,9 @@ function runLint(lintPath, patchPath) {
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
const { lintPath, patchPath } = yield core.group(`prepare environment`, prepareEnv);
|
const { lintPath, patchPath, checkRunId } = yield core.group(`prepare environment`, prepareEnv);
|
||||||
core.addPath(path.dirname(lintPath));
|
core.addPath(path.dirname(lintPath));
|
||||||
yield core.group(`run golangci-lint`, () => runLint(lintPath, patchPath));
|
yield core.group(`run golangci-lint`, () => runLint(lintPath, patchPath, checkRunId));
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.error(`Failed to run: ${error}, ${error.stack}`);
|
core.error(`Failed to run: ${error}, ${error.stack}`);
|
||||||
|
|
@ -52341,183 +52353,34 @@ __webpack_require__(71);
|
||||||
/* 720 */,
|
/* 720 */,
|
||||||
/* 721 */,
|
/* 721 */,
|
||||||
/* 722 */
|
/* 722 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(module) {
|
||||||
|
|
||||||
"use strict";
|
/**
|
||||||
|
* Convert array of 16 byte values to UUID string format of the form:
|
||||||
|
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||||
|
*/
|
||||||
|
var byteToHex = [];
|
||||||
|
for (var i = 0; i < 256; ++i) {
|
||||||
|
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
function bytesToUuid(buf, offset) {
|
||||||
if (k2 === undefined) k2 = k;
|
var i = offset || 0;
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
var bth = byteToHex;
|
||||||
}) : (function(o, m, k, k2) {
|
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||||||
if (k2 === undefined) k2 = k;
|
return ([
|
||||||
o[k2] = m[k];
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
}));
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
}) : function(o, v) {
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
o["default"] = v;
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
});
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
bth[buf[i++]], bth[buf[i++]]
|
||||||
if (mod && mod.__esModule) return mod;
|
]).join('');
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.saveCache = exports.restoreCache = void 0;
|
|
||||||
const cache = __importStar(__webpack_require__(638));
|
|
||||||
const core = __importStar(__webpack_require__(470));
|
|
||||||
const crypto = __importStar(__webpack_require__(417));
|
|
||||||
const fs = __importStar(__webpack_require__(747));
|
|
||||||
const path_1 = __importDefault(__webpack_require__(622));
|
|
||||||
const constants_1 = __webpack_require__(196);
|
|
||||||
const utils = __importStar(__webpack_require__(443));
|
|
||||||
function checksumFile(hashName, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const hash = crypto.createHash(hashName);
|
|
||||||
const stream = fs.createReadStream(path);
|
|
||||||
stream.on("error", (err) => reject(err));
|
|
||||||
stream.on("data", (chunk) => hash.update(chunk));
|
|
||||||
stream.on("end", () => resolve(hash.digest("hex")));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
const pathExists = (path) => __awaiter(void 0, void 0, void 0, function* () { return !!(yield fs.promises.stat(path).catch(() => false)); });
|
|
||||||
const getLintCacheDir = () => {
|
module.exports = bytesToUuid;
|
||||||
return path_1.default.resolve(`${process.env.HOME}/.cache/golangci-lint`);
|
|
||||||
};
|
|
||||||
const getCacheDirs = () => {
|
|
||||||
// Not existing dirs are ok here: it works.
|
|
||||||
const skipPkgCache = core.getInput(`skip-pkg-cache`, { required: true }).trim();
|
|
||||||
const skipBuildCache = core.getInput(`skip-build-cache`, { required: true }).trim();
|
|
||||||
const dirs = [getLintCacheDir()];
|
|
||||||
if (skipBuildCache.toLowerCase() == "true") {
|
|
||||||
core.info(`Omitting ~/.cache/go-build from cache directories`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dirs.push(path_1.default.resolve(`${process.env.HOME}/.cache/go-build`));
|
|
||||||
}
|
|
||||||
if (skipPkgCache.toLowerCase() == "true") {
|
|
||||||
core.info(`Omitting ~/go/pkg from cache directories`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dirs.push(path_1.default.resolve(`${process.env.HOME}/go/pkg`));
|
|
||||||
}
|
|
||||||
return dirs;
|
|
||||||
};
|
|
||||||
const getIntervalKey = (invalidationIntervalDays) => {
|
|
||||||
const now = new Date();
|
|
||||||
const secondsSinceEpoch = now.getTime() / 1000;
|
|
||||||
const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400));
|
|
||||||
return intervalNumber.toString();
|
|
||||||
};
|
|
||||||
function buildCacheKeys() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const keys = [];
|
|
||||||
let cacheKey = `golangci-lint.cache-`;
|
|
||||||
keys.push(cacheKey);
|
|
||||||
// Periodically invalidate a cache because a new code being added.
|
|
||||||
// TODO: configure it via inputs.
|
|
||||||
cacheKey += `${getIntervalKey(7)}-`;
|
|
||||||
keys.push(cacheKey);
|
|
||||||
if (yield pathExists(`go.mod`)) {
|
|
||||||
// Add checksum to key to invalidate a cache when dependencies change.
|
|
||||||
cacheKey += yield checksumFile(`sha1`, `go.mod`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cacheKey += `nogomod`;
|
|
||||||
}
|
|
||||||
keys.push(cacheKey);
|
|
||||||
return keys;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function restoreCache() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const keys = yield buildCacheKeys();
|
|
||||||
const primaryKey = keys.pop();
|
|
||||||
const restoreKeys = keys.reverse();
|
|
||||||
// Tell golangci-lint to use our cache directory.
|
|
||||||
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir();
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Invalid primary key`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
|
|
||||||
try {
|
|
||||||
const cacheKey = yield cache.restoreCache(getCacheDirs(), primaryKey, restoreKeys);
|
|
||||||
if (!cacheKey) {
|
|
||||||
core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(", ")}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store the matched cache key
|
|
||||||
utils.setCacheState(cacheKey);
|
|
||||||
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error.name === cache.ValidationError.name) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.warning(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.restoreCache = restoreCache;
|
|
||||||
function saveCache() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Validate inputs, this can cause task failure
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const cacheDirs = getCacheDirs();
|
|
||||||
const primaryKey = core.getState(constants_1.State.CachePrimaryKey);
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Error retrieving key from state.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const state = utils.getCacheState();
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
|
||||||
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
yield cache.saveCache(cacheDirs, primaryKey);
|
|
||||||
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error.name === cache.ValidationError.name) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
else if (error.name === cache.ReserveCacheError.name) {
|
|
||||||
core.info(error.message);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.info(`[warning] ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.saveCache = saveCache;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
@ -55772,7 +55635,7 @@ var __createBinding;
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
var rng = __webpack_require__(139);
|
var rng = __webpack_require__(139);
|
||||||
var bytesToUuid = __webpack_require__(105);
|
var bytesToUuid = __webpack_require__(722);
|
||||||
|
|
||||||
function v4(options, buf, offset) {
|
function v4(options, buf, offset) {
|
||||||
var i = buf && offset || 0;
|
var i = buf && offset || 0;
|
||||||
|
|
@ -60629,7 +60492,187 @@ __exportStar(__webpack_require__(764), exports);
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 911 */,
|
/* 911 */,
|
||||||
/* 912 */,
|
/* 912 */,
|
||||||
/* 913 */,
|
/* 913 */
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.saveCache = exports.restoreCache = void 0;
|
||||||
|
const cache = __importStar(__webpack_require__(638));
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const crypto = __importStar(__webpack_require__(417));
|
||||||
|
const fs = __importStar(__webpack_require__(747));
|
||||||
|
const path_1 = __importDefault(__webpack_require__(622));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
const utils = __importStar(__webpack_require__(443));
|
||||||
|
function checksumFile(hashName, path) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const hash = crypto.createHash(hashName);
|
||||||
|
const stream = fs.createReadStream(path);
|
||||||
|
stream.on("error", (err) => reject(err));
|
||||||
|
stream.on("data", (chunk) => hash.update(chunk));
|
||||||
|
stream.on("end", () => resolve(hash.digest("hex")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const pathExists = (path) => __awaiter(void 0, void 0, void 0, function* () { return !!(yield fs.promises.stat(path).catch(() => false)); });
|
||||||
|
const getLintCacheDir = () => {
|
||||||
|
return path_1.default.resolve(`${process.env.HOME}/.cache/golangci-lint`);
|
||||||
|
};
|
||||||
|
const getCacheDirs = () => {
|
||||||
|
// Not existing dirs are ok here: it works.
|
||||||
|
const skipPkgCache = core.getInput(`skip-pkg-cache`, { required: true }).trim();
|
||||||
|
const skipBuildCache = core.getInput(`skip-build-cache`, { required: true }).trim();
|
||||||
|
const dirs = [getLintCacheDir()];
|
||||||
|
if (skipBuildCache.toLowerCase() == "true") {
|
||||||
|
core.info(`Omitting ~/.cache/go-build from cache directories`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirs.push(path_1.default.resolve(`${process.env.HOME}/.cache/go-build`));
|
||||||
|
}
|
||||||
|
if (skipPkgCache.toLowerCase() == "true") {
|
||||||
|
core.info(`Omitting ~/go/pkg from cache directories`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirs.push(path_1.default.resolve(`${process.env.HOME}/go/pkg`));
|
||||||
|
}
|
||||||
|
return dirs;
|
||||||
|
};
|
||||||
|
const getIntervalKey = (invalidationIntervalDays) => {
|
||||||
|
const now = new Date();
|
||||||
|
const secondsSinceEpoch = now.getTime() / 1000;
|
||||||
|
const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400));
|
||||||
|
return intervalNumber.toString();
|
||||||
|
};
|
||||||
|
function buildCacheKeys() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const keys = [];
|
||||||
|
let cacheKey = `golangci-lint.cache-`;
|
||||||
|
keys.push(cacheKey);
|
||||||
|
// Periodically invalidate a cache because a new code being added.
|
||||||
|
// TODO: configure it via inputs.
|
||||||
|
cacheKey += `${getIntervalKey(7)}-`;
|
||||||
|
keys.push(cacheKey);
|
||||||
|
if (yield pathExists(`go.mod`)) {
|
||||||
|
// Add checksum to key to invalidate a cache when dependencies change.
|
||||||
|
cacheKey += yield checksumFile(`sha1`, `go.mod`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cacheKey += `nogomod`;
|
||||||
|
}
|
||||||
|
keys.push(cacheKey);
|
||||||
|
return keys;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function restoreCache() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const keys = yield buildCacheKeys();
|
||||||
|
const primaryKey = keys.pop();
|
||||||
|
const restoreKeys = keys.reverse();
|
||||||
|
// Tell golangci-lint to use our cache directory.
|
||||||
|
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir();
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Invalid primary key`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
|
||||||
|
try {
|
||||||
|
const cacheKey = yield cache.restoreCache(getCacheDirs(), primaryKey, restoreKeys);
|
||||||
|
if (!cacheKey) {
|
||||||
|
core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(", ")}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Store the matched cache key
|
||||||
|
utils.setCacheState(cacheKey);
|
||||||
|
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.warning(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.restoreCache = restoreCache;
|
||||||
|
function saveCache() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Validate inputs, this can cause task failure
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const cacheDirs = getCacheDirs();
|
||||||
|
const primaryKey = core.getState(constants_1.State.CachePrimaryKey);
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Error retrieving key from state.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const state = utils.getCacheState();
|
||||||
|
if (utils.isExactKeyMatch(primaryKey, state)) {
|
||||||
|
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
yield cache.saveCache(cacheDirs, primaryKey);
|
||||||
|
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info(`[warning] ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 914 */,
|
/* 914 */,
|
||||||
/* 915 */,
|
/* 915 */,
|
||||||
/* 916 */,
|
/* 916 */,
|
||||||
|
|
|
||||||
549
dist/run/index.js
vendored
549
dist/run/index.js
vendored
|
|
@ -2505,7 +2505,7 @@ exports.toCommandValue = toCommandValue;
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
var rng = __webpack_require__(139);
|
var rng = __webpack_require__(139);
|
||||||
var bytesToUuid = __webpack_require__(105);
|
var bytesToUuid = __webpack_require__(722);
|
||||||
|
|
||||||
// **`v1()` - Generate time-based UUID**
|
// **`v1()` - Generate time-based UUID**
|
||||||
//
|
//
|
||||||
|
|
@ -3769,38 +3769,7 @@ var _default = version;
|
||||||
exports.default = _default;
|
exports.default = _default;
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 105 */
|
/* 105 */,
|
||||||
/***/ (function(module) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert array of 16 byte values to UUID string format of the form:
|
|
||||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
||||||
*/
|
|
||||||
var byteToHex = [];
|
|
||||||
for (var i = 0; i < 256; ++i) {
|
|
||||||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function bytesToUuid(buf, offset) {
|
|
||||||
var i = offset || 0;
|
|
||||||
var bth = byteToHex;
|
|
||||||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
|
||||||
return ([
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]], '-',
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]],
|
|
||||||
bth[buf[i++]], bth[buf[i++]]
|
|
||||||
]).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = bytesToUuid;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 106 */
|
/* 106 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
|
@ -6728,7 +6697,8 @@ const fs = __importStar(__webpack_require__(747));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
const tmp_1 = __webpack_require__(150);
|
const tmp_1 = __webpack_require__(150);
|
||||||
const util_1 = __webpack_require__(669);
|
const util_1 = __webpack_require__(669);
|
||||||
const cache_1 = __webpack_require__(722);
|
const uuid_1 = __webpack_require__(930);
|
||||||
|
const cache_1 = __webpack_require__(913);
|
||||||
const install_1 = __webpack_require__(655);
|
const install_1 = __webpack_require__(655);
|
||||||
const version_1 = __webpack_require__(52);
|
const version_1 = __webpack_require__(52);
|
||||||
const execShellCommand = util_1.promisify(child_process_1.exec);
|
const execShellCommand = util_1.promisify(child_process_1.exec);
|
||||||
|
|
@ -6797,6 +6767,8 @@ function fetchPatch() {
|
||||||
function prepareEnv() {
|
function prepareEnv() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
|
// Resolve Check Run ID
|
||||||
|
const resolveCheckRunIdPromise = resolveCheckRunId();
|
||||||
// Prepare cache, lint and go in parallel.
|
// Prepare cache, lint and go in parallel.
|
||||||
const restoreCachePromise = cache_1.restoreCache();
|
const restoreCachePromise = cache_1.restoreCache();
|
||||||
const prepareLintPromise = prepareLint();
|
const prepareLintPromise = prepareLint();
|
||||||
|
|
@ -6806,8 +6778,9 @@ function prepareEnv() {
|
||||||
yield installGoPromise;
|
yield installGoPromise;
|
||||||
yield restoreCachePromise;
|
yield restoreCachePromise;
|
||||||
const patchPath = yield patchPromise;
|
const patchPath = yield patchPromise;
|
||||||
|
const checkRunId = yield resolveCheckRunIdPromise;
|
||||||
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
|
core.info(`Prepared env in ${Date.now() - startedAt}ms`);
|
||||||
return { lintPath, patchPath };
|
return { lintPath, patchPath, checkRunId };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var LintSeverity;
|
var LintSeverity;
|
||||||
|
|
@ -6861,26 +6834,78 @@ const logLintIssues = (issues) => {
|
||||||
core.info(`${header} ${pos} - ${issue.Text} (${issue.FromLinter})`);
|
core.info(`${header} ${pos} - ${issue.Text} (${issue.FromLinter})`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
function annotateLintIssues(issues) {
|
function resolveCheckRunId() {
|
||||||
var _a;
|
var _a, _b, _c;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!issues.length) {
|
let checkRunId = -1;
|
||||||
|
if (process.env.GITHUB_ACTIONS === `true`) {
|
||||||
|
try {
|
||||||
|
const searchToken = uuid_1.v4();
|
||||||
|
core.info(`::warning::Resolving GitHub CheckRunID (${searchToken})`);
|
||||||
|
const ctx = github.context;
|
||||||
|
const ref = (_a = ctx.payload.after) !== null && _a !== void 0 ? _a : ctx.sha;
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
||||||
|
const { data: checkRunsResponse } = yield octokit.checks
|
||||||
|
.listForRef(Object.assign(Object.assign({}, ctx.repo), { ref, status: `in_progress`, filter: `latest` }))
|
||||||
|
.catch((e) => {
|
||||||
|
throw `Unable to fetch Check Run List: ${e}`;
|
||||||
|
});
|
||||||
|
if (checkRunsResponse.check_runs.length > 0) {
|
||||||
|
let checkRuns = checkRunsResponse.check_runs;
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = (_b = checkRuns.filter((run) => run.name.includes(ctx.job))) !== null && _b !== void 0 ? _b : checkRuns;
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = (_c = checkRuns.filter((run) => run.output.annotations_count > 0)) !== null && _c !== void 0 ? _c : checkRuns;
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
for (const run of checkRuns) {
|
||||||
|
try {
|
||||||
|
if ((yield octokit.checks.listAnnotations(Object.assign(Object.assign({}, ctx.repo), { check_run_id: run.id }))).data.findIndex((annotation) => annotation.message.includes(searchToken)) !== -1) {
|
||||||
|
checkRunId = run.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
core.info(`::debug::Error Fetching CheckRun ${run.id}: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (checkRuns[0]) {
|
||||||
|
checkRunId = checkRuns[0].id;
|
||||||
|
core.info(`Current Check Run is: ${checkRunId}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw `Unable to resolve GitHub Check Run`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw `Fetching octokit.checks.listForRef(${ref}) returned no results`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
core.info(`::error::Error resolving GitHub Check Run: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info(`::debug::Not in GitHub Action Context, Skipping Check Run Resolution`);
|
||||||
|
}
|
||||||
|
return checkRunId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function annotateLintIssues(issues, checkRunId) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (checkRunId === -1 || !issues.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ctx = github.context;
|
|
||||||
const ref = ctx.payload.after;
|
|
||||||
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
|
||||||
const checkRunsPromise = octokit.checks
|
|
||||||
.listForRef(Object.assign(Object.assign({}, ctx.repo), { ref, status: "in_progress" }))
|
|
||||||
.catch((e) => {
|
|
||||||
throw `Error getting Check Run Data: ${e}`;
|
|
||||||
});
|
|
||||||
const chunkSize = 50;
|
const chunkSize = 50;
|
||||||
const issueCounts = {
|
const issueCounts = {
|
||||||
notice: 0,
|
notice: 0,
|
||||||
warning: 0,
|
warning: 0,
|
||||||
failure: 0,
|
failure: 0,
|
||||||
};
|
};
|
||||||
|
const ctx = github.context;
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }));
|
||||||
const githubAnnotations = issues.map((issue) => {
|
const githubAnnotations = issues.map((issue) => {
|
||||||
// If/when we transition to comments, we would build the request structure here
|
// If/when we transition to comments, we would build the request structure here
|
||||||
const annotation = {
|
const annotation = {
|
||||||
|
|
@ -6914,22 +6939,11 @@ function annotateLintIssues(issues) {
|
||||||
}
|
}
|
||||||
return annotation;
|
return annotation;
|
||||||
});
|
});
|
||||||
let checkRun;
|
const title = `GolangCI-Lint`;
|
||||||
const { data: checkRunsResponse } = yield checkRunsPromise;
|
|
||||||
if (checkRunsResponse.check_runs.length === 0) {
|
|
||||||
throw `octokit.checks.listForRef(${ref}) returned no results`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
checkRun = checkRunsResponse.check_runs.find((run) => run.name.includes(`Lint`));
|
|
||||||
}
|
|
||||||
if (!(checkRun === null || checkRun === void 0 ? void 0 : checkRun.id)) {
|
|
||||||
throw `Could not find current check run`;
|
|
||||||
}
|
|
||||||
const title = (_a = checkRun.output.title) !== null && _a !== void 0 ? _a : `GolangCI-Lint`;
|
|
||||||
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`;
|
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`;
|
||||||
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) => githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)).forEach((annotations) => {
|
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) => githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)).forEach((annotations) => {
|
||||||
octokit.checks
|
octokit.checks
|
||||||
.update(Object.assign(Object.assign({}, ctx.repo), { check_run_id: checkRun === null || checkRun === void 0 ? void 0 : checkRun.id, output: {
|
.update(Object.assign(Object.assign({}, ctx.repo), { check_run_id: checkRunId, output: {
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
annotations,
|
annotations,
|
||||||
|
|
@ -6971,14 +6985,14 @@ const printOutput = (res) => {
|
||||||
core.info(res.stderr);
|
core.info(res.stderr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function printLintOutput(res) {
|
function printLintOutput(res, checkRunId) {
|
||||||
var _a;
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let lintOutput;
|
let lintOutput;
|
||||||
const exit_code = (_a = res.code) !== null && _a !== void 0 ? _a : 0;
|
const exit_code = (_a = res.code) !== null && _a !== void 0 ? _a : 0;
|
||||||
try {
|
try {
|
||||||
try {
|
if (res.stdout) {
|
||||||
if (res.stdout) {
|
try {
|
||||||
// This object contains other information, such as errors and the active linters
|
// This object contains other information, such as errors and the active linters
|
||||||
// TODO: Should we do something with that data?
|
// TODO: Should we do something with that data?
|
||||||
lintOutput = parseOutput(res.stdout);
|
lintOutput = parseOutput(res.stdout);
|
||||||
|
|
@ -6990,7 +7004,7 @@ function printLintOutput(res) {
|
||||||
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case `push`:
|
case `push`:
|
||||||
yield annotateLintIssues(lintOutput.Issues);
|
yield annotateLintIssues(lintOutput.Issues, checkRunId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// At this time, other events are not supported
|
// At this time, other events are not supported
|
||||||
|
|
@ -6998,22 +7012,20 @@ function printLintOutput(res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (e) {
|
||||||
catch (e) {
|
throw `there was an error processing golangci-lint output: ${e}`;
|
||||||
throw `there was an error processing golangci-lint output: ${e}`;
|
}
|
||||||
}
|
}
|
||||||
if (res.stderr) {
|
if (res.stderr) {
|
||||||
core.info(res.stderr);
|
core.info(res.stderr);
|
||||||
}
|
}
|
||||||
if (exit_code === 1) {
|
if (exit_code === 1) {
|
||||||
if (lintOutput) {
|
if (!lintOutput) {
|
||||||
if (hasFailingIssues(lintOutput.Issues)) {
|
|
||||||
throw `issues found`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`;
|
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`;
|
||||||
}
|
}
|
||||||
|
if (hasFailingIssues(lintOutput.Issues)) {
|
||||||
|
throw `issues found`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (exit_code > 1) {
|
else if (exit_code > 1) {
|
||||||
throw `golangci-lint exit with code ${exit_code}`;
|
throw `golangci-lint exit with code ${exit_code}`;
|
||||||
|
|
@ -7025,7 +7037,7 @@ function printLintOutput(res) {
|
||||||
return core.info(`golangci-lint found no blocking issues`);
|
return core.info(`golangci-lint found no blocking issues`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function runLint(lintPath, patchPath) {
|
function runLint(lintPath, patchPath, checkRunId) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const debug = core.getInput(`debug`);
|
const debug = core.getInput(`debug`);
|
||||||
if (debug.split(`,`).includes(`cache`)) {
|
if (debug.split(`,`).includes(`cache`)) {
|
||||||
|
|
@ -7075,12 +7087,12 @@ function runLint(lintPath, patchPath) {
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
try {
|
try {
|
||||||
const res = yield execShellCommand(cmd, cmdArgs);
|
const res = yield execShellCommand(cmd, cmdArgs);
|
||||||
yield printLintOutput(res);
|
yield printLintOutput(res, checkRunId);
|
||||||
}
|
}
|
||||||
catch (exc) {
|
catch (exc) {
|
||||||
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
||||||
// TODO: support reviewdog or leaving comments by GitHub API.
|
// TODO: support reviewdog or leaving comments by GitHub API.
|
||||||
yield printLintOutput(exc);
|
yield printLintOutput(exc, checkRunId);
|
||||||
}
|
}
|
||||||
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
|
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`);
|
||||||
});
|
});
|
||||||
|
|
@ -7088,9 +7100,9 @@ function runLint(lintPath, patchPath) {
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
const { lintPath, patchPath } = yield core.group(`prepare environment`, prepareEnv);
|
const { lintPath, patchPath, checkRunId } = yield core.group(`prepare environment`, prepareEnv);
|
||||||
core.addPath(path.dirname(lintPath));
|
core.addPath(path.dirname(lintPath));
|
||||||
yield core.group(`run golangci-lint`, () => runLint(lintPath, patchPath));
|
yield core.group(`run golangci-lint`, () => runLint(lintPath, patchPath, checkRunId));
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.error(`Failed to run: ${error}, ${error.stack}`);
|
core.error(`Failed to run: ${error}, ${error.stack}`);
|
||||||
|
|
@ -52351,183 +52363,34 @@ __webpack_require__(71);
|
||||||
/* 720 */,
|
/* 720 */,
|
||||||
/* 721 */,
|
/* 721 */,
|
||||||
/* 722 */
|
/* 722 */
|
||||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
/***/ (function(module) {
|
||||||
|
|
||||||
"use strict";
|
/**
|
||||||
|
* Convert array of 16 byte values to UUID string format of the form:
|
||||||
|
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||||
|
*/
|
||||||
|
var byteToHex = [];
|
||||||
|
for (var i = 0; i < 256; ++i) {
|
||||||
|
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
function bytesToUuid(buf, offset) {
|
||||||
if (k2 === undefined) k2 = k;
|
var i = offset || 0;
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
var bth = byteToHex;
|
||||||
}) : (function(o, m, k, k2) {
|
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||||||
if (k2 === undefined) k2 = k;
|
return ([
|
||||||
o[k2] = m[k];
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
}));
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
}) : function(o, v) {
|
bth[buf[i++]], bth[buf[i++]], '-',
|
||||||
o["default"] = v;
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
});
|
bth[buf[i++]], bth[buf[i++]],
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
bth[buf[i++]], bth[buf[i++]]
|
||||||
if (mod && mod.__esModule) return mod;
|
]).join('');
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.saveCache = exports.restoreCache = void 0;
|
|
||||||
const cache = __importStar(__webpack_require__(638));
|
|
||||||
const core = __importStar(__webpack_require__(470));
|
|
||||||
const crypto = __importStar(__webpack_require__(417));
|
|
||||||
const fs = __importStar(__webpack_require__(747));
|
|
||||||
const path_1 = __importDefault(__webpack_require__(622));
|
|
||||||
const constants_1 = __webpack_require__(196);
|
|
||||||
const utils = __importStar(__webpack_require__(443));
|
|
||||||
function checksumFile(hashName, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const hash = crypto.createHash(hashName);
|
|
||||||
const stream = fs.createReadStream(path);
|
|
||||||
stream.on("error", (err) => reject(err));
|
|
||||||
stream.on("data", (chunk) => hash.update(chunk));
|
|
||||||
stream.on("end", () => resolve(hash.digest("hex")));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
const pathExists = (path) => __awaiter(void 0, void 0, void 0, function* () { return !!(yield fs.promises.stat(path).catch(() => false)); });
|
|
||||||
const getLintCacheDir = () => {
|
module.exports = bytesToUuid;
|
||||||
return path_1.default.resolve(`${process.env.HOME}/.cache/golangci-lint`);
|
|
||||||
};
|
|
||||||
const getCacheDirs = () => {
|
|
||||||
// Not existing dirs are ok here: it works.
|
|
||||||
const skipPkgCache = core.getInput(`skip-pkg-cache`, { required: true }).trim();
|
|
||||||
const skipBuildCache = core.getInput(`skip-build-cache`, { required: true }).trim();
|
|
||||||
const dirs = [getLintCacheDir()];
|
|
||||||
if (skipBuildCache.toLowerCase() == "true") {
|
|
||||||
core.info(`Omitting ~/.cache/go-build from cache directories`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dirs.push(path_1.default.resolve(`${process.env.HOME}/.cache/go-build`));
|
|
||||||
}
|
|
||||||
if (skipPkgCache.toLowerCase() == "true") {
|
|
||||||
core.info(`Omitting ~/go/pkg from cache directories`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dirs.push(path_1.default.resolve(`${process.env.HOME}/go/pkg`));
|
|
||||||
}
|
|
||||||
return dirs;
|
|
||||||
};
|
|
||||||
const getIntervalKey = (invalidationIntervalDays) => {
|
|
||||||
const now = new Date();
|
|
||||||
const secondsSinceEpoch = now.getTime() / 1000;
|
|
||||||
const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400));
|
|
||||||
return intervalNumber.toString();
|
|
||||||
};
|
|
||||||
function buildCacheKeys() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const keys = [];
|
|
||||||
let cacheKey = `golangci-lint.cache-`;
|
|
||||||
keys.push(cacheKey);
|
|
||||||
// Periodically invalidate a cache because a new code being added.
|
|
||||||
// TODO: configure it via inputs.
|
|
||||||
cacheKey += `${getIntervalKey(7)}-`;
|
|
||||||
keys.push(cacheKey);
|
|
||||||
if (yield pathExists(`go.mod`)) {
|
|
||||||
// Add checksum to key to invalidate a cache when dependencies change.
|
|
||||||
cacheKey += yield checksumFile(`sha1`, `go.mod`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cacheKey += `nogomod`;
|
|
||||||
}
|
|
||||||
keys.push(cacheKey);
|
|
||||||
return keys;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function restoreCache() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const keys = yield buildCacheKeys();
|
|
||||||
const primaryKey = keys.pop();
|
|
||||||
const restoreKeys = keys.reverse();
|
|
||||||
// Tell golangci-lint to use our cache directory.
|
|
||||||
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir();
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Invalid primary key`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
|
|
||||||
try {
|
|
||||||
const cacheKey = yield cache.restoreCache(getCacheDirs(), primaryKey, restoreKeys);
|
|
||||||
if (!cacheKey) {
|
|
||||||
core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(", ")}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store the matched cache key
|
|
||||||
utils.setCacheState(cacheKey);
|
|
||||||
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error.name === cache.ValidationError.name) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.warning(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.restoreCache = restoreCache;
|
|
||||||
function saveCache() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Validate inputs, this can cause task failure
|
|
||||||
if (!utils.isValidEvent()) {
|
|
||||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const cacheDirs = getCacheDirs();
|
|
||||||
const primaryKey = core.getState(constants_1.State.CachePrimaryKey);
|
|
||||||
if (!primaryKey) {
|
|
||||||
utils.logWarning(`Error retrieving key from state.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const state = utils.getCacheState();
|
|
||||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
|
||||||
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
yield cache.saveCache(cacheDirs, primaryKey);
|
|
||||||
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error.name === cache.ValidationError.name) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
else if (error.name === cache.ReserveCacheError.name) {
|
|
||||||
core.info(error.message);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
core.info(`[warning] ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.saveCache = saveCache;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
@ -55782,7 +55645,7 @@ var __createBinding;
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
var rng = __webpack_require__(139);
|
var rng = __webpack_require__(139);
|
||||||
var bytesToUuid = __webpack_require__(105);
|
var bytesToUuid = __webpack_require__(722);
|
||||||
|
|
||||||
function v4(options, buf, offset) {
|
function v4(options, buf, offset) {
|
||||||
var i = buf && offset || 0;
|
var i = buf && offset || 0;
|
||||||
|
|
@ -60629,7 +60492,187 @@ __exportStar(__webpack_require__(764), exports);
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 911 */,
|
/* 911 */,
|
||||||
/* 912 */,
|
/* 912 */,
|
||||||
/* 913 */,
|
/* 913 */
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.saveCache = exports.restoreCache = void 0;
|
||||||
|
const cache = __importStar(__webpack_require__(638));
|
||||||
|
const core = __importStar(__webpack_require__(470));
|
||||||
|
const crypto = __importStar(__webpack_require__(417));
|
||||||
|
const fs = __importStar(__webpack_require__(747));
|
||||||
|
const path_1 = __importDefault(__webpack_require__(622));
|
||||||
|
const constants_1 = __webpack_require__(196);
|
||||||
|
const utils = __importStar(__webpack_require__(443));
|
||||||
|
function checksumFile(hashName, path) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const hash = crypto.createHash(hashName);
|
||||||
|
const stream = fs.createReadStream(path);
|
||||||
|
stream.on("error", (err) => reject(err));
|
||||||
|
stream.on("data", (chunk) => hash.update(chunk));
|
||||||
|
stream.on("end", () => resolve(hash.digest("hex")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const pathExists = (path) => __awaiter(void 0, void 0, void 0, function* () { return !!(yield fs.promises.stat(path).catch(() => false)); });
|
||||||
|
const getLintCacheDir = () => {
|
||||||
|
return path_1.default.resolve(`${process.env.HOME}/.cache/golangci-lint`);
|
||||||
|
};
|
||||||
|
const getCacheDirs = () => {
|
||||||
|
// Not existing dirs are ok here: it works.
|
||||||
|
const skipPkgCache = core.getInput(`skip-pkg-cache`, { required: true }).trim();
|
||||||
|
const skipBuildCache = core.getInput(`skip-build-cache`, { required: true }).trim();
|
||||||
|
const dirs = [getLintCacheDir()];
|
||||||
|
if (skipBuildCache.toLowerCase() == "true") {
|
||||||
|
core.info(`Omitting ~/.cache/go-build from cache directories`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirs.push(path_1.default.resolve(`${process.env.HOME}/.cache/go-build`));
|
||||||
|
}
|
||||||
|
if (skipPkgCache.toLowerCase() == "true") {
|
||||||
|
core.info(`Omitting ~/go/pkg from cache directories`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirs.push(path_1.default.resolve(`${process.env.HOME}/go/pkg`));
|
||||||
|
}
|
||||||
|
return dirs;
|
||||||
|
};
|
||||||
|
const getIntervalKey = (invalidationIntervalDays) => {
|
||||||
|
const now = new Date();
|
||||||
|
const secondsSinceEpoch = now.getTime() / 1000;
|
||||||
|
const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400));
|
||||||
|
return intervalNumber.toString();
|
||||||
|
};
|
||||||
|
function buildCacheKeys() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const keys = [];
|
||||||
|
let cacheKey = `golangci-lint.cache-`;
|
||||||
|
keys.push(cacheKey);
|
||||||
|
// Periodically invalidate a cache because a new code being added.
|
||||||
|
// TODO: configure it via inputs.
|
||||||
|
cacheKey += `${getIntervalKey(7)}-`;
|
||||||
|
keys.push(cacheKey);
|
||||||
|
if (yield pathExists(`go.mod`)) {
|
||||||
|
// Add checksum to key to invalidate a cache when dependencies change.
|
||||||
|
cacheKey += yield checksumFile(`sha1`, `go.mod`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cacheKey += `nogomod`;
|
||||||
|
}
|
||||||
|
keys.push(cacheKey);
|
||||||
|
return keys;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function restoreCache() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const keys = yield buildCacheKeys();
|
||||||
|
const primaryKey = keys.pop();
|
||||||
|
const restoreKeys = keys.reverse();
|
||||||
|
// Tell golangci-lint to use our cache directory.
|
||||||
|
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir();
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Invalid primary key`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
|
||||||
|
try {
|
||||||
|
const cacheKey = yield cache.restoreCache(getCacheDirs(), primaryKey, restoreKeys);
|
||||||
|
if (!cacheKey) {
|
||||||
|
core.info(`Cache not found for input keys: ${[primaryKey, ...restoreKeys].join(", ")}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Store the matched cache key
|
||||||
|
utils.setCacheState(cacheKey);
|
||||||
|
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.warning(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.restoreCache = restoreCache;
|
||||||
|
function saveCache() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// Validate inputs, this can cause task failure
|
||||||
|
if (!utils.isValidEvent()) {
|
||||||
|
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported because it's not tied to a branch or tag ref.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const cacheDirs = getCacheDirs();
|
||||||
|
const primaryKey = core.getState(constants_1.State.CachePrimaryKey);
|
||||||
|
if (!primaryKey) {
|
||||||
|
utils.logWarning(`Error retrieving key from state.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const state = utils.getCacheState();
|
||||||
|
if (utils.isExactKeyMatch(primaryKey, state)) {
|
||||||
|
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
yield cache.saveCache(cacheDirs, primaryKey);
|
||||||
|
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.name === cache.ValidationError.name) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else if (error.name === cache.ReserveCacheError.name) {
|
||||||
|
core.info(error.message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info(`[warning] ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.saveCache = saveCache;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
/* 914 */,
|
/* 914 */,
|
||||||
/* 915 */,
|
/* 915 */,
|
||||||
/* 916 */,
|
/* 916 */,
|
||||||
|
|
|
||||||
163
src/run.ts
163
src/run.ts
|
|
@ -6,6 +6,7 @@ import * as fs from "fs"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
import { dir } from "tmp"
|
import { dir } from "tmp"
|
||||||
import { promisify } from "util"
|
import { promisify } from "util"
|
||||||
|
import { v4 as uuidv4 } from "uuid"
|
||||||
|
|
||||||
import { restoreCache, saveCache } from "./cache"
|
import { restoreCache, saveCache } from "./cache"
|
||||||
import { installGo, installLint } from "./install"
|
import { installGo, installLint } from "./install"
|
||||||
|
|
@ -78,11 +79,15 @@ async function fetchPatch(): Promise<string> {
|
||||||
type Env = {
|
type Env = {
|
||||||
lintPath: string
|
lintPath: string
|
||||||
patchPath: string
|
patchPath: string
|
||||||
|
checkRunId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
async function prepareEnv(): Promise<Env> {
|
async function prepareEnv(): Promise<Env> {
|
||||||
const startedAt = Date.now()
|
const startedAt = Date.now()
|
||||||
|
|
||||||
|
// Resolve Check Run ID
|
||||||
|
const resolveCheckRunIdPromise = resolveCheckRunId()
|
||||||
|
|
||||||
// Prepare cache, lint and go in parallel.
|
// Prepare cache, lint and go in parallel.
|
||||||
const restoreCachePromise = restoreCache()
|
const restoreCachePromise = restoreCache()
|
||||||
const prepareLintPromise = prepareLint()
|
const prepareLintPromise = prepareLint()
|
||||||
|
|
@ -93,9 +98,10 @@ async function prepareEnv(): Promise<Env> {
|
||||||
await installGoPromise
|
await installGoPromise
|
||||||
await restoreCachePromise
|
await restoreCachePromise
|
||||||
const patchPath = await patchPromise
|
const patchPath = await patchPromise
|
||||||
|
const checkRunId = await resolveCheckRunIdPromise
|
||||||
|
|
||||||
core.info(`Prepared env in ${Date.now() - startedAt}ms`)
|
core.info(`Prepared env in ${Date.now() - startedAt}ms`)
|
||||||
return { lintPath, patchPath }
|
return { lintPath, patchPath, checkRunId }
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecRes = {
|
type ExecRes = {
|
||||||
|
|
@ -164,16 +170,34 @@ type GithubAnnotation = {
|
||||||
end_line: number
|
end_line: number
|
||||||
start_column?: number
|
start_column?: number
|
||||||
end_column?: number
|
end_column?: number
|
||||||
|
annotation_level: LintSeverityStrings
|
||||||
title: string
|
title: string
|
||||||
message: string
|
message: string
|
||||||
annotation_level: LintSeverityStrings
|
|
||||||
raw_details?: string
|
raw_details?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckRun = {
|
type CheckRun = {
|
||||||
id: number
|
id: number
|
||||||
|
node_id: string
|
||||||
|
head_sha: string
|
||||||
|
external_id: string
|
||||||
|
url: string
|
||||||
|
html_url: string
|
||||||
|
details_url: string
|
||||||
|
status: string
|
||||||
|
conclusion: string | null
|
||||||
|
started_at: string
|
||||||
|
completed_at: string | null
|
||||||
output: {
|
output: {
|
||||||
title: string
|
title: string | null
|
||||||
|
summary: string | null
|
||||||
|
text: string | null
|
||||||
|
annotations_count: number
|
||||||
|
annotations_url: string
|
||||||
|
}
|
||||||
|
name: string
|
||||||
|
check_suite: {
|
||||||
|
id: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,22 +255,78 @@ const logLintIssues = (issues: LintIssue[]): void => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function annotateLintIssues(issues: LintIssue[]): Promise<void> {
|
async function resolveCheckRunId(): Promise<number> {
|
||||||
if (!issues.length) {
|
let checkRunId = -1
|
||||||
|
|
||||||
|
if (process.env.GITHUB_ACTIONS === `true`) {
|
||||||
|
try {
|
||||||
|
const searchToken = uuidv4()
|
||||||
|
core.info(`::warning::Resolving GitHub CheckRunID (${searchToken})`)
|
||||||
|
|
||||||
|
const ctx = github.context
|
||||||
|
const ref = ctx.payload.after ?? ctx.sha
|
||||||
|
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }))
|
||||||
|
const { data: checkRunsResponse } = await octokit.checks
|
||||||
|
.listForRef({
|
||||||
|
...ctx.repo,
|
||||||
|
ref,
|
||||||
|
status: `in_progress`,
|
||||||
|
filter: `latest`,
|
||||||
|
})
|
||||||
|
.catch((e: string) => {
|
||||||
|
throw `Unable to fetch Check Run List: ${e}`
|
||||||
|
})
|
||||||
|
|
||||||
|
if (checkRunsResponse.check_runs.length > 0) {
|
||||||
|
let checkRuns: CheckRun[] = checkRunsResponse.check_runs
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = checkRuns.filter((run) => run.name.includes(ctx.job)) ?? checkRuns
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
checkRuns = checkRuns.filter((run) => run.output.annotations_count > 0) ?? checkRuns
|
||||||
|
}
|
||||||
|
if (checkRuns.length > 1) {
|
||||||
|
for (const run of checkRuns) {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
await octokit.checks.listAnnotations({
|
||||||
|
...ctx.repo,
|
||||||
|
check_run_id: run.id,
|
||||||
|
})
|
||||||
|
).data.findIndex((annotation: { message: string }) => annotation.message.includes(searchToken)) !== -1
|
||||||
|
) {
|
||||||
|
checkRunId = run.id
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
core.info(`::debug::Error Fetching CheckRun ${run.id}: ${e}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (checkRuns[0]) {
|
||||||
|
checkRunId = checkRuns[0].id
|
||||||
|
core.info(`Current Check Run is: ${checkRunId}`)
|
||||||
|
} else {
|
||||||
|
throw `Unable to resolve GitHub Check Run`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw `Fetching octokit.checks.listForRef(${ref}) returned no results`
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
core.info(`::error::Error resolving GitHub Check Run: ${e}`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.info(`::debug::Not in GitHub Action Context, Skipping Check Run Resolution`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkRunId
|
||||||
|
}
|
||||||
|
|
||||||
|
async function annotateLintIssues(issues: LintIssue[], checkRunId: number): Promise<void> {
|
||||||
|
if (checkRunId === -1 || !issues.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const ctx = github.context
|
|
||||||
const ref = ctx.payload.after
|
|
||||||
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }))
|
|
||||||
const checkRunsPromise = octokit.checks
|
|
||||||
.listForRef({
|
|
||||||
...ctx.repo,
|
|
||||||
ref,
|
|
||||||
status: "in_progress",
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
throw `Error getting Check Run Data: ${e}`
|
|
||||||
})
|
|
||||||
|
|
||||||
const chunkSize = 50
|
const chunkSize = 50
|
||||||
const issueCounts = {
|
const issueCounts = {
|
||||||
|
|
@ -254,6 +334,10 @@ async function annotateLintIssues(issues: LintIssue[]): Promise<void> {
|
||||||
warning: 0,
|
warning: 0,
|
||||||
failure: 0,
|
failure: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ctx = github.context
|
||||||
|
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }))
|
||||||
|
|
||||||
const githubAnnotations: GithubAnnotation[] = issues.map(
|
const githubAnnotations: GithubAnnotation[] = issues.map(
|
||||||
(issue: LintIssue): GithubAnnotation => {
|
(issue: LintIssue): GithubAnnotation => {
|
||||||
// If/when we transition to comments, we would build the request structure here
|
// If/when we transition to comments, we would build the request structure here
|
||||||
|
|
@ -291,17 +375,7 @@ async function annotateLintIssues(issues: LintIssue[]): Promise<void> {
|
||||||
return annotation as GithubAnnotation
|
return annotation as GithubAnnotation
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let checkRun: CheckRun | undefined
|
const title = `GolangCI-Lint`
|
||||||
const { data: checkRunsResponse } = await checkRunsPromise
|
|
||||||
if (checkRunsResponse.check_runs.length === 0) {
|
|
||||||
throw `octokit.checks.listForRef(${ref}) returned no results`
|
|
||||||
} else {
|
|
||||||
checkRun = checkRunsResponse.check_runs.find((run) => run.name.includes(`Lint`))
|
|
||||||
}
|
|
||||||
if (!checkRun?.id) {
|
|
||||||
throw `Could not find current check run`
|
|
||||||
}
|
|
||||||
const title = checkRun.output.title ?? `GolangCI-Lint`
|
|
||||||
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`
|
const summary = `There are {issueCounts.failure} failures, {issueCounts.wairning} warnings, and {issueCounts.notice} notices.`
|
||||||
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) =>
|
Array.from({ length: Math.ceil(githubAnnotations.length / chunkSize) }, (v, i) =>
|
||||||
githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)
|
githubAnnotations.slice(i * chunkSize, i * chunkSize + chunkSize)
|
||||||
|
|
@ -309,7 +383,7 @@ async function annotateLintIssues(issues: LintIssue[]): Promise<void> {
|
||||||
octokit.checks
|
octokit.checks
|
||||||
.update({
|
.update({
|
||||||
...ctx.repo,
|
...ctx.repo,
|
||||||
check_run_id: checkRun?.id as number,
|
check_run_id: checkRunId,
|
||||||
output: {
|
output: {
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
|
|
@ -359,12 +433,12 @@ const printOutput = (res: ExecRes): void => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function printLintOutput(res: ExecRes): Promise<void> {
|
async function printLintOutput(res: ExecRes, checkRunId: number): Promise<void> {
|
||||||
let lintOutput: LintOutput | undefined
|
let lintOutput: LintOutput | undefined
|
||||||
const exit_code = res.code ?? 0
|
const exit_code = res.code ?? 0
|
||||||
try {
|
try {
|
||||||
try {
|
if (res.stdout) {
|
||||||
if (res.stdout) {
|
try {
|
||||||
// This object contains other information, such as errors and the active linters
|
// This object contains other information, such as errors and the active linters
|
||||||
// TODO: Should we do something with that data?
|
// TODO: Should we do something with that data?
|
||||||
lintOutput = parseOutput(res.stdout)
|
lintOutput = parseOutput(res.stdout)
|
||||||
|
|
@ -378,16 +452,16 @@ async function printLintOutput(res: ExecRes): Promise<void> {
|
||||||
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
// TODO: When we are ready to handle these as Comments, instead of Annotations, we would place that logic here
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case `push`:
|
case `push`:
|
||||||
await annotateLintIssues(lintOutput.Issues)
|
await annotateLintIssues(lintOutput.Issues, checkRunId)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// At this time, other events are not supported
|
// At this time, other events are not supported
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw `there was an error processing golangci-lint output: ${e}`
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
throw `there was an error processing golangci-lint output: ${e}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.stderr) {
|
if (res.stderr) {
|
||||||
|
|
@ -395,13 +469,12 @@ async function printLintOutput(res: ExecRes): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_code === 1) {
|
if (exit_code === 1) {
|
||||||
if (lintOutput) {
|
if (!lintOutput) {
|
||||||
if (hasFailingIssues(lintOutput.Issues)) {
|
|
||||||
throw `issues found`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`
|
throw `unexpected state, golangci-lint exited with 1, but provided no lint output`
|
||||||
}
|
}
|
||||||
|
if (hasFailingIssues(lintOutput.Issues)) {
|
||||||
|
throw `issues found`
|
||||||
|
}
|
||||||
} else if (exit_code > 1) {
|
} else if (exit_code > 1) {
|
||||||
throw `golangci-lint exit with code ${exit_code}`
|
throw `golangci-lint exit with code ${exit_code}`
|
||||||
}
|
}
|
||||||
|
|
@ -411,7 +484,7 @@ async function printLintOutput(res: ExecRes): Promise<void> {
|
||||||
return <void>core.info(`golangci-lint found no blocking issues`)
|
return <void>core.info(`golangci-lint found no blocking issues`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
async function runLint(lintPath: string, patchPath: string, checkRunId: number): Promise<void> {
|
||||||
const debug = core.getInput(`debug`)
|
const debug = core.getInput(`debug`)
|
||||||
if (debug.split(`,`).includes(`cache`)) {
|
if (debug.split(`,`).includes(`cache`)) {
|
||||||
const res = await execShellCommand(`${lintPath} cache status`)
|
const res = await execShellCommand(`${lintPath} cache status`)
|
||||||
|
|
@ -467,11 +540,11 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
||||||
const startedAt = Date.now()
|
const startedAt = Date.now()
|
||||||
try {
|
try {
|
||||||
const res = await execShellCommand(cmd, cmdArgs)
|
const res = await execShellCommand(cmd, cmdArgs)
|
||||||
await printLintOutput(res)
|
await printLintOutput(res, checkRunId)
|
||||||
} catch (exc) {
|
} catch (exc) {
|
||||||
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
// This logging passes issues to GitHub annotations but comments can be more convenient for some users.
|
||||||
// TODO: support reviewdog or leaving comments by GitHub API.
|
// TODO: support reviewdog or leaving comments by GitHub API.
|
||||||
await printLintOutput(exc)
|
await printLintOutput(exc, checkRunId)
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`)
|
core.info(`Ran golangci-lint in ${Date.now() - startedAt}ms`)
|
||||||
|
|
@ -479,9 +552,9 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const { lintPath, patchPath } = await core.group(`prepare environment`, prepareEnv)
|
const { lintPath, patchPath, checkRunId } = await core.group(`prepare environment`, prepareEnv)
|
||||||
core.addPath(path.dirname(lintPath))
|
core.addPath(path.dirname(lintPath))
|
||||||
await core.group(`run golangci-lint`, () => runLint(lintPath, patchPath))
|
await core.group(`run golangci-lint`, () => runLint(lintPath, patchPath, checkRunId))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.error(`Failed to run: ${error}, ${error.stack}`)
|
core.error(`Failed to run: ${error}, ${error.stack}`)
|
||||||
core.setFailed(error.message)
|
core.setFailed(error.message)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue