Compare commits

...

5 Commits

Author SHA1 Message Date
cf72500b28 Add path prefix if working director specified (#34) 2020-07-10 19:20:33 +00:00
d737e6d962 Fix misleading version input description (#33)
* Fix misleading version input description

Signed-off-by: Tam Mach <sayboras@yahoo.com>

* Run npm run all

* Update dep to fix CI

* Update dep to fix CI

* Bump to 1.28

* Locked down setup-go version
2020-07-06 06:17:53 +02:00
8870cfbcd4 remove output setting (#22)
Relates: #21
2020-05-23 12:34:30 +03:00
3395f777a4 Replace forked cache by official npm (#21)
* Replace forked cache by official npm

* Follow the same validation as @action/cache

* Remove debug log
2020-05-23 12:25:16 +03:00
04eca20383 don't add --new args if not requested 2020-05-22 10:48:00 +03:00
11 changed files with 4034 additions and 1635 deletions

View File

@ -10,7 +10,7 @@ jobs:
build: # make sure build/ci work properly build: # make sure build/ci work properly
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- run: | - run: |
npm install npm install
npm run prepare-deps npm run prepare-deps
@ -18,9 +18,9 @@ jobs:
test: # make sure the action works on a clean machine without building test: # make sure the action works on a clean machine without building
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- uses: ./ - uses: ./
with: with:
version: v1.26 version: v1.28
args: --issues-exit-code=0 ./sample/... args: --issues-exit-code=0 ./sample/...
only-new-issues: true only-new-issues: true

View File

@ -58,7 +58,7 @@ The restrictions of annotations are the following:
The action was implemented with performance in mind: 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. 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. 3. We do as much as we can in parallel, e.g. we download cache, go and golangci-lint binary in parallel.
@ -74,7 +74,7 @@ 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: We use JavaScript-based action. We don't use Docker-based action because:
1. docker pulling is slow currently 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)
Inside our action we perform 3 steps: Inside our action we perform 3 steps:

View File

@ -4,7 +4,7 @@ description: 'Official golangci-lint action with line-attached annotations for f
author: 'golangci' author: 'golangci'
inputs: inputs:
version: version:
description: 'version of golangci-lint to use in form of v1.2.3' description: 'version of golangci-lint to use in form of v1.2'
required: true required: true
args: args:
description: 'golangci-lint command line arguments' description: 'golangci-lint command line arguments'

2724
dist/post_run/index.js vendored

File diff suppressed because it is too large Load Diff

2724
dist/run/index.js vendored

File diff suppressed because it is too large Load Diff

49
package-lock.json generated
View File

@ -4,6 +4,20 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@actions/cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-0.2.1.tgz",
"integrity": "sha512-CV2D9zp+d+nL7o6XK/I7vVh350JglPMp/jHi9ppRUkdBHPUeP0UHVUfygZaAs8WmxhhWY1MI0gWah+t0QYu3Fg==",
"requires": {
"@actions/core": "^1.2.4",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.1",
"semver": "^6.1.0",
"uuid": "^3.3.3"
}
},
"@actions/core": { "@actions/core": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.4.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.4.tgz",
@ -446,18 +460,6 @@
"resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
"integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc="
}, },
"cache": {
"version": "git+https://github.com/golangci/cache.git#3df9f001c2d6c950a3deb6f2c1f88ddc2a609d25",
"from": "git+https://github.com/golangci/cache.git",
"requires": {
"@actions/core": "^1.2.0",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.1",
"uuid": "^3.3.3"
}
},
"callsites": { "callsites": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -1804,14 +1806,29 @@
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
}, },
"setup-go": { "setup-go": {
"version": "git+https://github.com/actions/setup-go.git#0f551ac199fb202fc2c3bf3612df37a2f074ef66", "version": "git+https://github.com/actions/setup-go.git#1616116e1b39417f86ba049745f1a8946d4d00e7",
"from": "git+https://github.com/actions/setup-go.git", "from": "git+https://github.com/actions/setup-go.git#v2.1.0",
"requires": { "requires": {
"@actions/core": "^1.2.2", "@actions/core": "^1.2.3",
"@actions/http-client": "^1.0.6", "@actions/http-client": "^1.0.6",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.3.3", "@actions/tool-cache": "^1.5.5",
"semver": "^6.1.1" "semver": "^6.1.1"
},
"dependencies": {
"@actions/tool-cache": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.5.5.tgz",
"integrity": "sha512-y/YO37BOaXzOEHpvoGZDLCwvg6XZWQ7Ala4Np4xzrKD1r48mff+K/GAmzXMejnApU7kgqC6lL/aCKTZDCrhdmw==",
"requires": {
"@actions/core": "^1.2.3",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
}
}
} }
}, },
"shebang-command": { "shebang-command": {

View File

@ -6,8 +6,7 @@
"main": "dist/main.js", "main": "dist/main.js",
"scripts": { "scripts": {
"prepare-setup-go": "cd node_modules/setup-go && npm run build", "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",
"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", "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_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", "watched_build_post_main": "tsc && ncc build -w -o dist/post_run/ src/post_main.ts",
@ -30,10 +29,10 @@
"@actions/exec": "^1.0.1", "@actions/exec": "^1.0.1",
"@actions/github": "^2.1.1", "@actions/github": "^2.1.1",
"@actions/tool-cache": "^1.3.4", "@actions/tool-cache": "^1.3.4",
"@actions/cache": "^0.2.1",
"@types/semver": "^7.1.0", "@types/semver": "^7.1.0",
"@types/tmp": "^0.2.0", "@types/tmp": "^0.2.0",
"cache": "git+https://github.com/golangci/cache.git", "setup-go": "git+https://github.com/actions/setup-go.git#v2.1.0",
"setup-go": "git+https://github.com/actions/setup-go.git",
"tmp": "^0.2.1" "tmp": "^0.2.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,9 +1,11 @@
import * as cache from "@actions/cache"
import * as core from "@actions/core" 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 crypto from "crypto"
import * as fs from "fs" import * as fs from "fs"
import { Events, State } from "./constants"
import * as utils from "./utils/actionUtils"
function checksumFile(hashName: string, path: string): Promise<string> { function checksumFile(hashName: string, path: string): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const hash = crypto.createHash(hashName) const hash = crypto.createHash(hashName)
@ -52,30 +54,80 @@ async function buildCacheKeys(): Promise<string[]> {
} }
export async function restoreCache(): Promise<void> { 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 startedAt = Date.now()
const keys = await buildCacheKeys() const keys = await buildCacheKeys()
const primaryKey = keys.pop() const primaryKey = keys.pop()
const restoreKeys = keys.reverse() 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. // Tell golangci-lint to use our cache directory.
process.env.GOLANGCI_LINT_CACHE = getLintCacheDir() process.env.GOLANGCI_LINT_CACHE = getLintCacheDir()
await restore() if (!primaryKey) {
core.info(`Restored cache for golangci-lint from key '${primaryKey}' in ${Date.now() - startedAt}ms`) 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> { 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 startedAt = Date.now()
const cacheDirs = getCacheDirs() 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() const state = utils.getCacheState()
core.info(`Saved cache for golangci-lint from paths '${cacheDirs.join(`, `)}' in ${Date.now() - startedAt}ms`)
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
View 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"

View File

@ -136,14 +136,16 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
} }
addedArgs.push(`--out-format=github-actions`) addedArgs.push(`--out-format=github-actions`)
if (patchPath && (userArgNames.has(`new`) || userArgNames.has(`new-from-rev`) || userArgNames.has(`new-from-patch`))) { if (patchPath) {
throw new Error(`please, don't specify manually --new* args when requesting only new issues`) 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}`) }
addedArgs.push(`--new-from-patch=${patchPath}`)
// Override config values. // Override config values.
addedArgs.push(`--new=false`) addedArgs.push(`--new=false`)
addedArgs.push(`--new-from-rev=`) addedArgs.push(`--new-from-rev=`)
}
const workingDirectory = core.getInput(`working-directory`) const workingDirectory = core.getInput(`working-directory`)
const cmdArgs: ExecOptions = {} const cmdArgs: ExecOptions = {}
@ -155,12 +157,14 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) { if (!fs.existsSync(workingDirectory) || !fs.lstatSync(workingDirectory).isDirectory()) {
throw new Error(`working-directory (${workingDirectory}) was not a path`) 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) cmdArgs.cwd = path.resolve(workingDirectory)
} }
const cmd = `${lintPath} run ${addedArgs.join(` `)} ${userArgs}`.trimRight() 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() const startedAt = Date.now()
try { try {
const res = await execShellCommand(cmd, cmdArgs) const res = await execShellCommand(cmd, cmdArgs)

37
src/utils/actionUtils.ts Normal file
View 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])
}