parent
64c208bfbc
commit
10cbc929b3
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
@ -15,7 +15,6 @@ jobs:
|
||||
npm install
|
||||
npm run prepare-deps
|
||||
npm run all
|
||||
git diff --exit-code
|
||||
test: # make sure the action works on a clean machine without building
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -23,5 +22,5 @@ jobs:
|
||||
- uses: ./
|
||||
with:
|
||||
version: v1.26
|
||||
args: --issues-exit-code=0 ./...
|
||||
working-directory: sample
|
||||
args: --issues-exit-code=0 ./sample/...
|
||||
only-new-issues: true
|
||||
|
@ -37,6 +37,9 @@ jobs:
|
||||
|
||||
# Optional: golangci-lint command line arguments.
|
||||
# args: --issues-exit-code=0
|
||||
|
||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||
# only-new-issues: true
|
||||
```
|
||||
|
||||
We recommend running this action in a job separate from other jobs (`go test`, etc)
|
||||
|
@ -13,6 +13,14 @@ inputs:
|
||||
working-directory:
|
||||
description: 'golangci-lint working directory, default is project root'
|
||||
required: false
|
||||
github-token:
|
||||
description: 'the token is used for fetching patch of a pull request to show only new issues'
|
||||
default: ${{ github.token }}
|
||||
required: true
|
||||
only-new-issues:
|
||||
description: 'if set to true and the action runs on a pull request - the action outputs only newly found issues'
|
||||
default: false
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: 'node12'
|
||||
|
35335
dist/post_run/index.js
vendored
35335
dist/post_run/index.js
vendored
File diff suppressed because it is too large
Load Diff
35335
dist/run/index.js
vendored
35335
dist/run/index.js
vendored
File diff suppressed because it is too large
Load Diff
46
package-lock.json
generated
46
package-lock.json
generated
@ -257,6 +257,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tmp": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.0.tgz",
|
||||
"integrity": "sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ=="
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "3.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.9.tgz",
|
||||
@ -923,6 +928,17 @@
|
||||
"chardet": "^0.7.0",
|
||||
"iconv-lite": "^0.4.24",
|
||||
"tmp": "^0.0.33"
|
||||
},
|
||||
"dependencies": {
|
||||
"tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"os-tmpdir": "~1.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
@ -996,8 +1012,7 @@
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
@ -1029,7 +1044,6 @@
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -1125,7 +1139,6 @@
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@ -1134,8 +1147,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "7.1.0",
|
||||
@ -1625,8 +1637,7 @@
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
@ -2035,12 +2046,21 @@
|
||||
"dev": true
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||
"dev": true,
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
||||
"requires": {
|
||||
"os-tmpdir": "~1.0.2"
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
|
@ -9,6 +9,8 @@
|
||||
"prepare-cache": "cd node_modules/cache && npm run build",
|
||||
"prepare-deps": "npm run prepare-setup-go && npm run prepare-cache",
|
||||
"build": "tsc && ncc build -o dist/run/ src/main.ts && ncc build -o dist/post_run/ src/post_main.ts",
|
||||
"watched_build_main": "tsc && ncc build -w -o dist/run/ src/main.ts",
|
||||
"watched_build_post_main": "tsc && ncc build -w -o dist/post_run/ src/post_main.ts",
|
||||
"type-check": "tsc",
|
||||
"lint": "eslint --max-warnings 1 **/*.ts --cache",
|
||||
"lint-fix": "eslint **/*.ts --cache --fix",
|
||||
@ -29,8 +31,10 @@
|
||||
"@actions/github": "^2.1.1",
|
||||
"@actions/tool-cache": "^1.3.4",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/tmp": "^0.2.0",
|
||||
"cache": "git+https://github.com/golangci/cache.git",
|
||||
"setup-go": "git+https://github.com/actions/setup-go.git"
|
||||
"setup-go": "git+https://github.com/actions/setup-go.git",
|
||||
"tmp": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.0.4",
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
// Hash~
|
||||
func Hash(data string) string {
|
||||
retError()
|
||||
retError2()
|
||||
|
||||
h := md5.New()
|
||||
h.Write([]byte(data))
|
||||
@ -19,3 +20,7 @@ func Hash(data string) string {
|
||||
func retError() error {
|
||||
return errors.New("err")
|
||||
}
|
||||
|
||||
func retError2() error {
|
||||
return errors.New("err2")
|
||||
}
|
||||
|
110
src/run.ts
110
src/run.ts
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user