Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
6317259e28 | |||
809d3b078b | |||
b026646c83 | |||
c598686db1 | |||
25d72af787 | |||
79f232513c | |||
f7f5eff206 | |||
485c6a047e | |||
e2ff3f296a | |||
294f27a519 | |||
c238b72278 | |||
ba40dc6b1d | |||
65dc624d8b | |||
466abb7dfd | |||
5c7c749f16 | |||
2f458de87f | |||
94d029dd63 | |||
a5502f9224 | |||
fa6ef09daf | |||
2effa0b58a | |||
3b01eb9dce | |||
0d019f3dae | |||
48e7180822 | |||
8577a0ee23 | |||
cf72500b28 | |||
d737e6d962 | |||
8870cfbcd4 | |||
3395f777a4 | |||
04eca20383 |
14
.github/dependabot.yml
vendored
Normal file
14
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
reviewers:
|
||||
- "golangci/team"
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
reviewers:
|
||||
- "golangci/team"
|
31
.github/workflows/test.yml
vendored
31
.github/workflows/test.yml
vendored
@ -4,23 +4,28 @@ on: # rebuild any PRs and main branch changes
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'releases/*'
|
||||
- "releases/*"
|
||||
|
||||
jobs:
|
||||
build: # make sure build/ci work properly
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm run prepare-deps
|
||||
npm run all
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
npm install
|
||||
npm run all
|
||||
test: # make sure the action works on a clean machine without building
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: ./
|
||||
with:
|
||||
version: v1.26
|
||||
args: --issues-exit-code=0 ./sample/...
|
||||
only-new-issues: true
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./
|
||||
with:
|
||||
version: latest
|
||||
args: --issues-exit-code=0 ./sample/...
|
||||
only-new-issues: true
|
||||
|
18
README.md
18
README.md
@ -7,6 +7,12 @@ The action runs [golangci-lint](https://github.com/golangci/golangci-lint) and r
|
||||
|
||||

|
||||
|
||||
## Compatibility
|
||||
|
||||
* `v2.0.0+` works with `golangci-lint` version >= `v1.28.3`
|
||||
* `v1.2.2` is deprecated due to we forgot to change the minimum version of `golangci-lint` to `v1.28.3` ([issue](https://github.com/golangci/golangci-lint-action/issues/39))
|
||||
* `v1.2.1` works with `golangci-lint` version >= `v1.14.0` ([issue](https://github.com/golangci/golangci-lint-action/issues/39))
|
||||
|
||||
## How to use
|
||||
|
||||
Add `.github/workflows/golangci-lint.yml` with the following contents:
|
||||
@ -30,8 +36,8 @@ jobs:
|
||||
uses: golangci/golangci-lint-action@v1
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.26
|
||||
|
||||
version: v1.29
|
||||
|
||||
# Optional: working directory, useful for monorepos
|
||||
# working-directory: somedir
|
||||
|
||||
@ -58,7 +64,7 @@ The restrictions of annotations are the following:
|
||||
|
||||
The action was implemented with performance in mind:
|
||||
|
||||
1. We cache data by [@actions/cache](https://github.com/actions/cache) between builds: Go build cache, Go modules cache, golangci-lint analysis cache.
|
||||
1. We cache data by [@actions/cache](https://github.com/actions/toolkit/tree/master/packages/cache) between builds: Go build cache, Go modules cache, golangci-lint analysis cache.
|
||||
2. We don't use Docker because image pulling is slow.
|
||||
3. We do as much as we can in parallel, e.g. we download cache, go and golangci-lint binary in parallel.
|
||||
|
||||
@ -74,7 +80,9 @@ For example, in a repository of [golangci-lint](https://github.com/golangci/gola
|
||||
We use JavaScript-based action. We don't use Docker-based action because:
|
||||
|
||||
1. docker pulling is slow currently
|
||||
2. it's easier to use caching from [@actions/cache](https://github.com/actions/cache) until GitHub team hasn't supported reusing actions from actions
|
||||
2. it's easier to use caching from [@actions/cache](https://github.com/actions/toolkit/tree/master/packages/cache)
|
||||
|
||||
We support different platforms, such as `ubuntu`, `macos` and `windows` with `x32` and `x64` archs.
|
||||
|
||||
Inside our action we perform 3 steps:
|
||||
|
||||
@ -89,7 +97,7 @@ Inside our action we perform 3 steps:
|
||||
### Caching internals
|
||||
|
||||
1. We save and restore the following directories: `~/.cache/golangci-lint`, `~/.cache/go-build`, `~/go/pkg`.
|
||||
2. The primary caching key looks like `golangci-lint.cache-{interval_number}-{go.mod_hash}`. Interval number ensures that we periodically invalidate
|
||||
2. The primary caching key looks like `golangci-lint.cache-{platform-arch}-{interval_number}-{go.mod_hash}`. Interval number ensures that we periodically invalidate
|
||||
our cache (every 7 days). `go.mod` hash ensures that we invalidate the cache early - as soon as dependencies have changed.
|
||||
3. We use [restore keys](https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key): `golangci-lint.cache-{interval_number}-`, `golangci-lint.cache-`. GitHub matches keys by prefix if we have no exact match for the primary cache.
|
||||
|
||||
|
30
action.yml
30
action.yml
@ -1,31 +1,31 @@
|
||||
---
|
||||
name: 'Run golangci-lint'
|
||||
description: 'Official golangci-lint action with line-attached annotations for found issues, caching and parallel execution.'
|
||||
author: 'golangci'
|
||||
name: "Run golangci-lint"
|
||||
description: "Official golangci-lint action with line-attached annotations for found issues, caching and parallel execution."
|
||||
author: "golangci"
|
||||
inputs:
|
||||
version:
|
||||
description: 'version of golangci-lint to use in form of v1.2.3'
|
||||
required: true
|
||||
description: "version of golangci-lint to use in form of v1.2 or `latest` to use the latest version"
|
||||
required: false
|
||||
args:
|
||||
description: 'golangci-lint command line arguments'
|
||||
default: ''
|
||||
description: "golangci-lint command line arguments"
|
||||
default: ""
|
||||
required: false
|
||||
working-directory:
|
||||
description: 'golangci-lint working directory, default is project root'
|
||||
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'
|
||||
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'
|
||||
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'
|
||||
main: 'dist/run/index.js'
|
||||
post: 'dist/post_run/index.js'
|
||||
using: "node12"
|
||||
main: "dist/run/index.js"
|
||||
post: "dist/post_run/index.js"
|
||||
branding:
|
||||
icon: 'shield'
|
||||
color: 'yellow'
|
||||
icon: "shield"
|
||||
color: "yellow"
|
||||
|
68851
dist/post_run/index.js
vendored
68851
dist/post_run/index.js
vendored
File diff suppressed because one or more lines are too long
68857
dist/run/index.js
vendored
68857
dist/run/index.js
vendored
File diff suppressed because one or more lines are too long
929
package-lock.json
generated
929
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
37
package.json
37
package.json
@ -1,13 +1,12 @@
|
||||
{
|
||||
"name": "golanci-lint-action",
|
||||
"version": "1.1.2",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"description": "golangci-lint github action",
|
||||
"main": "dist/main.js",
|
||||
"scripts": {
|
||||
"prepare-setup-go": "cd node_modules/setup-go && npm run build",
|
||||
"prepare-cache": "cd node_modules/cache && npm run build",
|
||||
"prepare-deps": "npm run prepare-setup-go && npm run prepare-cache",
|
||||
"prepare-deps": "npm run prepare-setup-go",
|
||||
"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",
|
||||
@ -16,38 +15,38 @@
|
||||
"lint-fix": "eslint **/*.ts --cache --fix",
|
||||
"format": "prettier --write **/*.ts",
|
||||
"format-check": "prettier --check **/*.ts",
|
||||
"all": "npm run build && npm run format-check && npm run lint",
|
||||
"all": "npm run prepare-deps && npm run build && npm run format-check && npm run lint",
|
||||
"local": "npm run build && act -j test -b"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/golangci/golangci-lint-action.git"
|
||||
},
|
||||
"author": "GitHub",
|
||||
"author": "golangci",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^1.0.1",
|
||||
"@actions/core": "^1.2.0",
|
||||
"@actions/exec": "^1.0.1",
|
||||
"@actions/github": "^2.1.1",
|
||||
"@actions/tool-cache": "^1.3.4",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@actions/github": "^4.0.0",
|
||||
"@actions/tool-cache": "^1.6.0",
|
||||
"@types/semver": "^7.3.1",
|
||||
"@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#v2.1.1",
|
||||
"tmp": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.0.4",
|
||||
"@types/uuid": "^3.4.5",
|
||||
"@typescript-eslint/eslint-plugin": "^2.7.0",
|
||||
"@typescript-eslint/parser": "^2.7.0",
|
||||
"@zeit/ncc": "^0.20.5",
|
||||
"@types/node": "^14.0.27",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.34.0",
|
||||
"@typescript-eslint/parser": "^2.34.0",
|
||||
"@zeit/ncc": "^0.22.3",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint-config-prettier": "^6.5.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"eslint-plugin-simple-import-sort": "^5.0.2",
|
||||
"prettier": "^1.19.1",
|
||||
"typescript": "^3.8.3"
|
||||
"prettier": "^2.0.5",
|
||||
"typescript": "^3.9.7"
|
||||
}
|
||||
}
|
||||
|
87
src/cache.ts
87
src/cache.ts
@ -1,26 +1,31 @@
|
||||
import * as cache from "@actions/cache"
|
||||
import * as core from "@actions/core"
|
||||
import restore from "cache/lib/restore"
|
||||
import save from "cache/lib/save"
|
||||
import * as crypto from "crypto"
|
||||
import * as fs from "fs"
|
||||
import path from "path"
|
||||
|
||||
import { Events, State } from "./constants"
|
||||
import * as utils from "./utils/actionUtils"
|
||||
|
||||
function checksumFile(hashName: string, path: string): Promise<string> {
|
||||
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("error", (err) => reject(err))
|
||||
stream.on("data", (chunk) => hash.update(chunk))
|
||||
stream.on("end", () => resolve(hash.digest("hex")))
|
||||
})
|
||||
}
|
||||
|
||||
const pathExists = async (path: string): Promise<boolean> => !!(await fs.promises.stat(path).catch(() => false))
|
||||
|
||||
const getLintCacheDir = (): string => `${process.env.HOME}/.cache/golangci-lint`
|
||||
const getLintCacheDir = (): string => {
|
||||
return path.resolve(`${process.env.HOME}/.cache/golangci-lint`)
|
||||
}
|
||||
|
||||
const getCacheDirs = (): string[] => {
|
||||
// Not existing dirs are ok here: it works.
|
||||
return [getLintCacheDir(), `${process.env.HOME}/.cache/go-build`, `${process.env.HOME}/go/pkg`]
|
||||
return [getLintCacheDir(), path.resolve(`${process.env.HOME}/.cache/go-build`), path.resolve(`${process.env.HOME}/go/pkg`)]
|
||||
}
|
||||
|
||||
const getIntervalKey = (invalidationIntervalDays: number): string => {
|
||||
@ -52,30 +57,80 @@ async function buildCacheKeys(): Promise<string[]> {
|
||||
}
|
||||
|
||||
export async function restoreCache(): Promise<void> {
|
||||
if (!utils.isValidEvent()) {
|
||||
utils.logWarning(
|
||||
`Event Validation Error: The event type ${process.env[Events.Key]} is not supported because it's not tied to a branch or tag ref.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const startedAt = Date.now()
|
||||
|
||||
const keys = await buildCacheKeys()
|
||||
const primaryKey = keys.pop()
|
||||
const restoreKeys = keys.reverse()
|
||||
core.info(`Primary analysis cache key is '${primaryKey}', restore keys are '${restoreKeys.join(` | `)}'`)
|
||||
process.env[`INPUT_RESTORE-KEYS`] = restoreKeys.join(`\n`)
|
||||
process.env.INPUT_KEY = primaryKey
|
||||
|
||||
process.env.INPUT_PATH = getCacheDirs().join(`\n`)
|
||||
|
||||
// Tell golangci-lint to use our cache directory.
|
||||
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir()
|
||||
|
||||
await restore()
|
||||
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`)
|
||||
if (!primaryKey) {
|
||||
utils.logWarning(`Invalid primary key`)
|
||||
return
|
||||
}
|
||||
core.saveState(State.CachePrimaryKey, primaryKey)
|
||||
try {
|
||||
const cacheKey = await 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveCache(): Promise<void> {
|
||||
// Validate inputs, this can cause task failure
|
||||
if (!utils.isValidEvent()) {
|
||||
utils.logWarning(
|
||||
`Event Validation Error: The event type ${process.env[Events.Key]} is not supported because it's not tied to a branch or tag ref.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const startedAt = Date.now()
|
||||
|
||||
const cacheDirs = getCacheDirs()
|
||||
process.env.INPUT_PATH = cacheDirs.join(`\n`)
|
||||
const primaryKey = core.getState(State.CachePrimaryKey)
|
||||
if (!primaryKey) {
|
||||
utils.logWarning(`Error retrieving key from state.`)
|
||||
return
|
||||
}
|
||||
|
||||
await save()
|
||||
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`)
|
||||
const state = utils.getCacheState()
|
||||
|
||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
||||
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await 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}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
18
src/constants.ts
Normal file
18
src/constants.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export enum Inputs {
|
||||
Key = "key",
|
||||
Path = "path",
|
||||
RestoreKeys = "restore-keys",
|
||||
}
|
||||
|
||||
export enum State {
|
||||
CachePrimaryKey = "CACHE_KEY",
|
||||
CacheMatchedKey = "CACHE_RESULT",
|
||||
}
|
||||
|
||||
export enum Events {
|
||||
Key = "GITHUB_EVENT_NAME",
|
||||
Push = "push",
|
||||
PullRequest = "pull_request",
|
||||
}
|
||||
|
||||
export const RefKey = "GITHUB_REF"
|
@ -1,21 +1,55 @@
|
||||
import * as core from "@actions/core"
|
||||
import * as tc from "@actions/tool-cache"
|
||||
import os from "os"
|
||||
import path from "path"
|
||||
import { run as setupGo } from "setup-go/lib/main"
|
||||
|
||||
import { VersionConfig } from "./version"
|
||||
|
||||
const downloadURL = "https://github.com/golangci/golangci-lint/releases/download"
|
||||
|
||||
const getAssetURL = (versionConfig: VersionConfig): string => {
|
||||
let ext = "tar.gz"
|
||||
let platform = os.platform().toString()
|
||||
switch (platform) {
|
||||
case "win32":
|
||||
platform = "windows"
|
||||
ext = "zip"
|
||||
break
|
||||
}
|
||||
let arch = os.arch()
|
||||
switch (arch) {
|
||||
case "x64":
|
||||
arch = "amd64"
|
||||
break
|
||||
case "x32":
|
||||
case "ia32":
|
||||
arch = "386"
|
||||
break
|
||||
}
|
||||
const noPrefix = versionConfig.TargetVersion.slice(1)
|
||||
|
||||
return `${downloadURL}/${versionConfig.TargetVersion}/golangci-lint-${noPrefix}-${platform}-${arch}.${ext}`
|
||||
}
|
||||
|
||||
// The installLint returns path to installed binary of golangci-lint.
|
||||
export async function installLint(versionConfig: VersionConfig): Promise<string> {
|
||||
core.info(`Installing golangci-lint ${versionConfig.TargetVersion}...`)
|
||||
const startedAt = Date.now()
|
||||
const assetURL = getAssetURL(versionConfig)
|
||||
core.info(`Downloading ${assetURL} ...`)
|
||||
const archivePath = await tc.downloadTool(assetURL)
|
||||
let extractedDir = ""
|
||||
let repl = /\.tar\.gz$/
|
||||
if (assetURL.endsWith("zip")) {
|
||||
extractedDir = await tc.extractZip(archivePath, process.env.HOME)
|
||||
repl = /\.zip$/
|
||||
} else {
|
||||
extractedDir = await tc.extractTar(archivePath, process.env.HOME)
|
||||
}
|
||||
|
||||
core.info(`Downloading ${versionConfig.AssetURL} ...`)
|
||||
const tarGzPath = await tc.downloadTool(versionConfig.AssetURL)
|
||||
const extractedDir = await tc.extractTar(tarGzPath, process.env.HOME)
|
||||
|
||||
const urlParts = versionConfig.AssetURL.split(`/`)
|
||||
const dirName = urlParts[urlParts.length - 1].replace(/\.tar\.gz$/, ``)
|
||||
const urlParts = assetURL.split(`/`)
|
||||
const dirName = urlParts[urlParts.length - 1].replace(repl, ``)
|
||||
const lintPath = path.join(extractedDir, dirName, `golangci-lint`)
|
||||
core.info(`Installed golangci-lint into ${lintPath} in ${Date.now() - startedAt}ms`)
|
||||
return lintPath
|
||||
|
30
src/run.ts
30
src/run.ts
@ -39,7 +39,7 @@ async function fetchPatch(): Promise<string> {
|
||||
return ``
|
||||
}
|
||||
|
||||
const octokit = new github.GitHub(core.getInput(`github-token`, { required: true }))
|
||||
const octokit = github.getOctokit(core.getInput(`github-token`, { required: true }))
|
||||
let patch: string
|
||||
try {
|
||||
const patchResp = await octokit.pulls.get({
|
||||
@ -125,9 +125,9 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
||||
const userArgNames = new Set<string>()
|
||||
userArgs
|
||||
.split(/\s/)
|
||||
.map(arg => arg.split(`=`)[0])
|
||||
.filter(arg => arg.startsWith(`-`))
|
||||
.forEach(arg => {
|
||||
.map((arg) => arg.split(`=`)[0])
|
||||
.filter((arg) => arg.startsWith(`-`))
|
||||
.forEach((arg) => {
|
||||
userArgNames.add(arg.replace(`-`, ``))
|
||||
})
|
||||
|
||||
@ -136,14 +136,16 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
||||
}
|
||||
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}`)
|
||||
if (patchPath) {
|
||||
if (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=`)
|
||||
// Override config values.
|
||||
addedArgs.push(`--new=false`)
|
||||
addedArgs.push(`--new-from-rev=`)
|
||||
}
|
||||
|
||||
const workingDirectory = core.getInput(`working-directory`)
|
||||
const cmdArgs: ExecOptions = {}
|
||||
@ -155,12 +157,14 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
|
||||
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
|
||||
throw new Error(`working-directory (${workingDirectory}) was not a path`)
|
||||
}
|
||||
|
||||
if (!userArgNames.has(`path-prefix`)) {
|
||||
addedArgs.push(`--path-prefix=${workingDirectory}`)
|
||||
}
|
||||
cmdArgs.cwd = path.resolve(workingDirectory)
|
||||
}
|
||||
|
||||
const cmd = `${lintPath} run ${addedArgs.join(` `)} ${userArgs}`.trimRight()
|
||||
core.info(`Running [${cmd}] in [${cmdArgs.cwd}] ...`)
|
||||
core.info(`Running [${cmd}] in [${cmdArgs.cwd || ``}] ...`)
|
||||
const startedAt = Date.now()
|
||||
try {
|
||||
const res = await execShellCommand(cmd, cmdArgs)
|
||||
|
37
src/utils/actionUtils.ts
Normal file
37
src/utils/actionUtils.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import * as core from "@actions/core"
|
||||
|
||||
import { RefKey, State } from "../constants"
|
||||
|
||||
export function isExactKeyMatch(key: string, cacheKey?: string): boolean {
|
||||
return !!(
|
||||
cacheKey &&
|
||||
cacheKey.localeCompare(key, undefined, {
|
||||
sensitivity: "accent",
|
||||
}) === 0
|
||||
)
|
||||
}
|
||||
|
||||
export function setCacheState(state: string): void {
|
||||
core.saveState(State.CacheMatchedKey, state)
|
||||
}
|
||||
|
||||
export function getCacheState(): string | undefined {
|
||||
const cacheKey = core.getState(State.CacheMatchedKey)
|
||||
if (cacheKey) {
|
||||
core.debug(`Cache state/key: ${cacheKey}`)
|
||||
return cacheKey
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
export function logWarning(message: string): void {
|
||||
const warningPrefix = "[warning]"
|
||||
core.info(`${warningPrefix}${message}`)
|
||||
}
|
||||
|
||||
// Cache token authorized for all events that are tied to a ref
|
||||
// See GitHub Context https://help.github.com/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context
|
||||
export function isValidEvent(): boolean {
|
||||
return RefKey in process.env && Boolean(process.env[RefKey])
|
||||
}
|
@ -6,11 +6,14 @@ export type Version = {
|
||||
major: number
|
||||
minor: number
|
||||
patch: number | null
|
||||
}
|
||||
} | null
|
||||
|
||||
const versionRe = /^v(\d+)\.(\d+)(?:\.(\d+))?$/
|
||||
|
||||
const parseVersion = (s: string): Version => {
|
||||
if (s == "latest" || s == "") {
|
||||
return null
|
||||
}
|
||||
const match = s.match(versionRe)
|
||||
if (!match) {
|
||||
throw new Error(`invalid version string '${s}', expected format v1.2 or v1.2.3`)
|
||||
@ -23,33 +26,41 @@ const parseVersion = (s: string): Version => {
|
||||
}
|
||||
}
|
||||
|
||||
export const stringifyVersion = (v: Version): string => `v${v.major}.${v.minor}${v.patch !== null ? `.${v.patch}` : ``}`
|
||||
export const stringifyVersion = (v: Version): string => {
|
||||
if (v == null) {
|
||||
return "latest"
|
||||
}
|
||||
return `v${v.major}.${v.minor}${v.patch !== null ? `.${v.patch}` : ``}`
|
||||
}
|
||||
|
||||
const minVersion = {
|
||||
major: 1,
|
||||
minor: 14,
|
||||
patch: 0,
|
||||
minor: 28,
|
||||
patch: 3,
|
||||
}
|
||||
|
||||
const isLessVersion = (a: Version, b: Version): boolean => {
|
||||
if (a == null) {
|
||||
return true
|
||||
}
|
||||
if (b == null) {
|
||||
return false
|
||||
}
|
||||
if (a.major != b.major) {
|
||||
return a.major < b.major
|
||||
}
|
||||
|
||||
if (a.minor != b.minor) {
|
||||
return a.minor < b.minor
|
||||
}
|
||||
|
||||
if (a.patch === null || b.patch === null) {
|
||||
return true
|
||||
}
|
||||
|
||||
return a.patch < b.patch
|
||||
// Do not compare patch parts because if the min version has a non zero value
|
||||
// then it returns false, since the patch version of requested is always zero
|
||||
return a.minor < b.minor
|
||||
}
|
||||
|
||||
const getRequestedLintVersion = (): Version => {
|
||||
const requestedLintVersion = core.getInput(`version`, { required: true })
|
||||
const requestedLintVersion = core.getInput(`version`)
|
||||
const parsedRequestedLintVersion = parseVersion(requestedLintVersion)
|
||||
if (parsedRequestedLintVersion == null) {
|
||||
return null
|
||||
}
|
||||
if (parsedRequestedLintVersion.patch !== null) {
|
||||
throw new Error(
|
||||
`requested golangci-lint version '${requestedLintVersion}' was specified with the patch version, need specify only minor version`
|
||||
@ -99,15 +110,14 @@ const getConfig = async (): Promise<Config> => {
|
||||
export async function findLintVersion(): Promise<VersionConfig> {
|
||||
core.info(`Finding needed golangci-lint version...`)
|
||||
const startedAt = Date.now()
|
||||
const reqLintVersion = getRequestedLintVersion()
|
||||
|
||||
const config = await getConfig()
|
||||
|
||||
if (!config.MinorVersionToConfig) {
|
||||
core.warning(JSON.stringify(config))
|
||||
throw new Error(`invalid config: no MinorVersionToConfig field`)
|
||||
}
|
||||
|
||||
const reqLintVersion = getRequestedLintVersion()
|
||||
const versionConfig = config.MinorVersionToConfig[stringifyVersion(reqLintVersion)]
|
||||
if (!versionConfig) {
|
||||
throw new Error(`requested golangci-lint version '${stringifyVersion(reqLintVersion)}' doesn't exist`)
|
||||
@ -118,8 +128,9 @@ export async function findLintVersion(): Promise<VersionConfig> {
|
||||
}
|
||||
|
||||
core.info(
|
||||
`Requested golangci-lint '${stringifyVersion(reqLintVersion)}', using '${versionConfig.TargetVersion}', calculation took ${Date.now() -
|
||||
startedAt}ms`
|
||||
`Requested golangci-lint '${stringifyVersion(reqLintVersion)}', using '${versionConfig.TargetVersion}', calculation took ${
|
||||
Date.now() - startedAt
|
||||
}ms`
|
||||
)
|
||||
return versionConfig
|
||||
}
|
||||
|
Reference in New Issue
Block a user