Support only-new-issues (#19)

Fixes #16
This commit is contained in:
Denis Isaev
2020-05-22 10:36:12 +03:00
committed by GitHub
parent 64c208bfbc
commit 10cbc929b3
9 changed files with 62797 additions and 8056 deletions

View File

@ -1,7 +1,9 @@
import * as core from "@actions/core"
import * as github from "@actions/github"
import { exec, ExecOptions } from "child_process"
import * as fs from "fs"
import * as path from "path"
import { dir } from "tmp"
import { promisify } from "util"
import { restoreCache, saveCache } from "./cache"
@ -9,26 +11,91 @@ import { installGo, installLint } from "./install"
import { findLintVersion } from "./version"
const execShellCommand = promisify(exec)
const writeFile = promisify(fs.writeFile)
const createTempDir = promisify(dir)
async function prepareLint(): Promise<string> {
const versionConfig = await findLintVersion()
return await installLint(versionConfig)
}
async function prepareEnv(): Promise<string> {
async function fetchPatch(): Promise<string> {
const onlyNewIssues = core.getInput(`only-new-issues`, { required: true }).trim()
if (onlyNewIssues !== `false` && onlyNewIssues !== `true`) {
throw new Error(`invalid value of "only-new-issues": "${onlyNewIssues}", expected "true" or "false"`)
}
if (onlyNewIssues === `false`) {
return ``
}
const ctx = github.context
if (ctx.eventName !== `pull_request`) {
core.info(`Not fetching patch for showing only new issues because it's not a pull request context: event name is ${ctx.eventName}`)
return ``
}
const pull = ctx.payload.pull_request
if (!pull) {
core.warning(`No pull request in context`)
return ``
}
const octokit = new github.GitHub(core.getInput(`github-token`, { required: true }))
let patch: string
try {
const patchResp = await octokit.pulls.get({
owner: ctx.repo.owner,
repo: ctx.repo.repo,
[`pull_number`]: pull.number,
mediaType: {
format: `diff`,
},
})
if (patchResp.status !== 200) {
core.warning(`failed to fetch pull request patch: response status is ${patchResp.status}`)
return `` // don't fail the action, but analyze without patch
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
patch = patchResp.data as any
} catch (err) {
console.warn(`failed to fetch pull request patch:`, err)
return `` // don't fail the action, but analyze without patch
}
try {
const tempDir = await createTempDir()
const patchPath = path.join(tempDir, "pull.patch")
core.info(`Writing patch to ${patchPath}`)
await writeFile(patchPath, patch)
return patchPath
} catch (err) {
console.warn(`failed to save pull request patch:`, err)
return `` // don't fail the action, but analyze without patch
}
}
type Env = {
lintPath: string
patchPath: string
}
async function prepareEnv(): Promise<Env> {
const startedAt = Date.now()
// Prepare cache, lint and go in parallel.
const restoreCachePromise = restoreCache()
const prepareLintPromise = prepareLint()
const installGoPromise = installGo()
const patchPromise = fetchPatch()
const lintPath = await prepareLintPromise
await installGoPromise
await restoreCachePromise
const patchPath = await patchPromise
core.info(`Prepared env in ${Date.now() - startedAt}ms`)
return lintPath
return { lintPath, patchPath }
}
type ExecRes = {
@ -45,21 +112,46 @@ const printOutput = (res: ExecRes): void => {
}
}
async function runLint(lintPath: string): Promise<void> {
async function runLint(lintPath: string, patchPath: string): Promise<void> {
const debug = core.getInput(`debug`)
if (debug.split(`,`).includes(`cache`)) {
const res = await execShellCommand(`${lintPath} cache status`)
printOutput(res)
}
const args = core.getInput(`args`)
if (args.includes(`-out-format`)) {
const userArgs = core.getInput(`args`)
const addedArgs: string[] = []
const userArgNames = new Set<string>()
userArgs
.split(/\s/)
.map(arg => arg.split(`=`)[0])
.filter(arg => arg.startsWith(`-`))
.forEach(arg => {
userArgNames.add(arg.replace(`-`, ``))
})
if (userArgNames.has(`out-format`)) {
throw new Error(`please, don't change out-format for golangci-lint: it can be broken in a future`)
}
addedArgs.push(`--out-format=github-actions`)
if (patchPath && (userArgNames.has(`new`) || userArgNames.has(`new-from-rev`) || userArgNames.has(`new-from-patch`))) {
throw new Error(`please, don't specify manually --new* args when requesting only new issues`)
}
addedArgs.push(`--new-from-patch=${patchPath}`)
// Override config values.
addedArgs.push(`--new=false`)
addedArgs.push(`--new-from-rev=`)
const workingDirectory = core.getInput(`working-directory`)
const cmdArgs: ExecOptions = {}
if (workingDirectory != ``) {
if (workingDirectory) {
if (patchPath) {
// TODO: make them compatible
throw new Error(`options working-directory and only-new-issues aren't compatible`)
}
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`)
}
@ -67,7 +159,7 @@ async function runLint(lintPath: string): Promise<void> {
cmdArgs.cwd = path.resolve(workingDirectory)
}
const cmd = `${lintPath} run --out-format=github-actions ${args}`.trimRight()
const cmd = `${lintPath} run ${addedArgs.join(` `)} ${userArgs}`.trimRight()
core.info(`Running [${cmd}] in [${cmdArgs.cwd}] ...`)
const startedAt = Date.now()
try {
@ -91,8 +183,8 @@ async function runLint(lintPath: string): Promise<void> {
export async function run(): Promise<void> {
try {
const lintPath = await core.group(`prepare environment`, prepareEnv)
await core.group(`run golangci-lint`, () => runLint(lintPath))
const { lintPath, patchPath } = await core.group(`prepare environment`, prepareEnv)
await core.group(`run golangci-lint`, () => runLint(lintPath, patchPath))
} catch (error) {
core.error(`Failed to run: ${error}, ${error.stack}`)
core.setFailed(error.message)