Compare commits

...

34 Commits

Author SHA1 Message Date
809d3b078b Support latest tag for golangci-lint version (#64) 2020-08-02 11:04:32 -05:00
b026646c83 build(deps): bump @actions/github from 2.1.1 to 4.0.0 (#45)
* build(deps): bump @actions/github from 2.1.1 to 4.0.0

Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 2.1.1 to 4.0.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/master/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

Signed-off-by: dependabot[bot] <support@github.com>

* Fix usage of github action

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sergey Vilgelm <sergey.vilgelm@ibm.com>
2020-08-02 06:08:36 -05:00
c598686db1 Update dist after the dependabot PRs (#62) 2020-08-01 09:09:28 -05:00
25d72af787 build(deps): bump @actions/tool-cache from 1.5.5 to 1.6.0 (#61)
Bumps [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) from 1.5.5 to 1.6.0.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/tool-cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/tool-cache)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-27 06:17:57 -05:00
79f232513c build(deps-dev): bump @types/node from 14.0.23 to 14.0.26 (#60)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.0.23 to 14.0.26.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Xiang Dai <long0dai@foxmail.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-27 15:09:32 +08:00
f7f5eff206 build(deps): bump @actions/cache from 0.2.1 to 1.0.1 (#59)
Bumps [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) from 0.2.1 to 1.0.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/@actions/io@1.0.1/packages/cache)

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Xiang Dai <long0dai@foxmail.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-27 15:08:57 +08:00
485c6a047e build(deps-dev): bump typescript from 3.9.6 to 3.9.7 (#57)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.9.6 to 3.9.7.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.9.6...v3.9.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-27 15:08:12 +08:00
e2ff3f296a build(deps): bump setup-go from v2.1.0 to v2.1.1 (#58)
Bumps [setup-go](https://github.com/actions/setup-go) from v2.1.0 to v2.1.1.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](1616116e1b...d0c5defdf3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-27 15:08:03 +08:00
294f27a519 Update README and test action to use v1.29 (#56) 2020-07-23 11:01:52 +08:00
c238b72278 Prepare v2.0.0 (#40) 2020-07-15 12:18:02 -05:00
ba40dc6b1d Run the build after dependabot PRs (#54) 2020-07-15 09:15:21 +10:00
65dc624d8b build(deps-dev): bump prettier from 1.19.1 to 2.0.5 (#52)
* build(deps-dev): bump prettier from 1.19.1 to 2.0.5

Bumps [prettier](https://github.com/prettier/prettier) from 1.19.1 to 2.0.5.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.19.1...2.0.5)

Signed-off-by: dependabot[bot] <support@github.com>

* Fix prettier

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sergey Vilgelm <sergey.vilgelm@ibm.com>
2020-07-14 09:25:11 -05:00
466abb7dfd build(deps-dev): bump @typescript-eslint/parser from 2.30.0 to 2.34.0 (#53)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 2.30.0 to 2.34.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v2.34.0/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 09:10:40 -05:00
5c7c749f16 build(deps-dev): bump typescript from 3.8.3 to 3.9.6 (#51)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.8.3 to 3.9.6.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.8.3...v3.9.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 09:05:15 -05:00
2f458de87f build(deps-dev): bump @types/node from 12.12.37 to 14.0.23 (#47)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.12.37 to 14.0.23.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 09:00:15 -05:00
94d029dd63 build(deps): bump @types/semver from 7.1.0 to 7.3.1 (#48)
Bumps [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) from 7.1.0 to 7.3.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:57:44 -05:00
a5502f9224 build(deps-dev): bump eslint-plugin-import from 2.20.2 to 2.22.0 (#49)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.20.2 to 2.22.0.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.20.2...v2.22.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:55:26 -05:00
fa6ef09daf build(deps-dev): bump @types/uuid from 3.4.9 to 8.0.0 (#50)
Bumps [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) from 3.4.9 to 8.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:51:27 -05:00
2effa0b58a build(deps-dev): bump @typescript-eslint/eslint-plugin (#44)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 2.30.0 to 2.34.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v2.34.0/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:43:50 -05:00
3b01eb9dce build(deps-dev): bump eslint-plugin-prettier from 3.1.3 to 3.1.4 (#43)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v3.1.3...v3.1.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:40:43 -05:00
0d019f3dae build(deps-dev): bump @zeit/ncc from 0.20.5 to 0.22.3 (#42)
Bumps [@zeit/ncc](https://github.com/zeit/ncc) from 0.20.5 to 0.22.3.
- [Release notes](https://github.com/zeit/ncc/releases)
- [Commits](https://github.com/zeit/ncc/compare/0.20.5...0.22.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:36:34 -05:00
48e7180822 build(deps): bump @actions/tool-cache from 1.3.4 to 1.5.5 (#46)
Bumps [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) from 1.3.4 to 1.5.5.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/master/packages/tool-cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/tool-cache)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-14 08:30:27 -05:00
8577a0ee23 Enable dependabot (#41) 2020-07-14 08:26:47 -05:00
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
10cbc929b3 Support only-new-issues (#19)
Fixes #16
2020-05-22 10:36:12 +03:00
64c208bfbc docs: add working-directory to README 2020-05-21 14:43:37 +03:00
20d5541dab Add working-directory support (#18)
Add working-directory support

Fixes #15
2020-05-21 14:36:02 +03:00
85a3a6abe4 docs: remove 'beta version' 2020-05-16 17:24:18 +03:00
b66692b61d mark the action as stable: v0 -> v1 2020-05-16 17:20:48 +03:00
348830fe4b docs: recommend distinct job 2020-05-09 18:48:24 +03:00
14 changed files with 105689 additions and 7750 deletions

14
.github/dependabot.yml vendored Normal file
View 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"

View File

@ -4,23 +4,22 @@ on: # rebuild any PRs and main branch changes
push: push:
branches: branches:
- master - master
- 'releases/*' - "releases/*"
jobs: 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 all npm run all
git diff --exit-code
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: latest
args: --issues-exit-code=0 ./sample/... args: --issues-exit-code=0 ./sample/...
only-new-issues: true

View File

@ -7,6 +7,12 @@ The action runs [golangci-lint](https://github.com/golangci/golangci-lint) and r
![GitHub Annotations](./static/annotations.png) ![GitHub Annotations](./static/annotations.png)
## 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 ## How to use
Add `.github/workflows/golangci-lint.yml` with the following contents: Add `.github/workflows/golangci-lint.yml` with the following contents:
@ -27,15 +33,24 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v0.2.0 uses: golangci/golangci-lint-action@v1
with: with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. # 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
# Optional: golangci-lint command line arguments. # Optional: golangci-lint command line arguments.
# args: ./the-only-dir-to-analyze/... # 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)
because different jobs [run in parallel](https://help.github.com/en/actions/getting-started-with-github-actions/core-concepts-for-github-actions#job).
## Comments and Annotations ## Comments and Annotations
Currently, GitHub parses the action's output and creates [annotations](https://github.community/t5/GitHub-Actions/What-are-annotations/td-p/30770). Currently, GitHub parses the action's output and creates [annotations](https://github.community/t5/GitHub-Actions/What-are-annotations/td-p/30770).
@ -49,7 +64,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.
@ -65,7 +80,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

@ -1,23 +1,31 @@
--- ---
name: 'Run golangci-lint' name: "Run golangci-lint"
description: 'Official golangci-lint action with line-attached annotations for found issues, caching and parallel execution. Beta version.' description: "Official golangci-lint action with line-attached annotations for found issues, caching and parallel execution."
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 or `latest` to use the latest version"
required: true required: false
args: args:
description: 'golangci-lint command line arguments' description: "golangci-lint command line arguments"
default: '' default: ""
required: false
working-directory:
description: "golangci-lint working directory, default is project root"
required: false required: false
github-token: github-token:
description: 'GitHub token with scope `repo.public_repo`. Used for fetching a list of releases of golangci-lint.' 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 required: true
runs: runs:
using: 'node12' using: "node12"
main: 'dist/run/index.js' main: "dist/run/index.js"
post: 'dist/post_run/index.js' post: "dist/post_run/index.js"
branding: branding:
icon: 'shield' icon: "shield"
color: 'yellow' color: "yellow"

56019
dist/post_run/index.js vendored

File diff suppressed because one or more lines are too long

55999
dist/run/index.js vendored

File diff suppressed because one or more lines are too long

991
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +1,52 @@
{ {
"name": "golanci-lint-action", "name": "golanci-lint-action",
"version": "1.1.2", "version": "2.0.0",
"private": true, "private": true,
"description": "golangci-lint github action", "description": "golangci-lint github action",
"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_post_main": "tsc && ncc build -w -o dist/post_run/ src/post_main.ts",
"type-check": "tsc", "type-check": "tsc",
"lint": "eslint --max-warnings 1 **/*.ts --cache", "lint": "eslint --max-warnings 1 **/*.ts --cache",
"lint-fix": "eslint **/*.ts --cache --fix", "lint-fix": "eslint **/*.ts --cache --fix",
"format": "prettier --write **/*.ts", "format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.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" "local": "npm run build && act -j test -b"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/golangci/golangci-lint-action.git" "url": "git+https://github.com/golangci/golangci-lint-action.git"
}, },
"author": "GitHub", "author": "golangci",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^1.0.1",
"@actions/core": "^1.2.0", "@actions/core": "^1.2.0",
"@actions/exec": "^1.0.1", "@actions/exec": "^1.0.1",
"@actions/github": "^2.1.1", "@actions/github": "^4.0.0",
"@actions/tool-cache": "^1.3.4", "@actions/tool-cache": "^1.6.0",
"@types/semver": "^7.1.0", "@types/semver": "^7.3.1",
"cache": "git+https://github.com/golangci/cache.git", "@types/tmp": "^0.2.0",
"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": { "devDependencies": {
"@types/node": "^12.0.4", "@types/node": "^14.0.27",
"@types/uuid": "^3.4.5", "@types/uuid": "^8.0.0",
"@typescript-eslint/eslint-plugin": "^2.7.0", "@typescript-eslint/eslint-plugin": "^2.34.0",
"@typescript-eslint/parser": "^2.7.0", "@typescript-eslint/parser": "^2.34.0",
"@zeit/ncc": "^0.20.5", "@zeit/ncc": "^0.22.3",
"eslint": "^6.6.0", "eslint": "^6.6.0",
"eslint-config-prettier": "^6.5.0", "eslint-config-prettier": "^6.5.0",
"eslint-plugin-import": "^2.18.2", "eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^3.1.1", "eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-simple-import-sort": "^5.0.2", "eslint-plugin-simple-import-sort": "^5.0.2",
"prettier": "^1.19.1", "prettier": "^2.0.5",
"typescript": "^3.8.3" "typescript": "^3.9.7"
} }
} }

View File

@ -10,6 +10,7 @@ import (
// Hash~ // Hash~
func Hash(data string) string { func Hash(data string) string {
retError() retError()
retError2()
h := md5.New() h := md5.New()
h.Write([]byte(data)) h.Write([]byte(data))
@ -19,3 +20,7 @@ func Hash(data string) string {
func retError() error { func retError() error {
return errors.New("err") return errors.New("err")
} }
func retError2() error {
return errors.New("err2")
}

View File

@ -1,15 +1,17 @@
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)
const stream = fs.createReadStream(path) const stream = fs.createReadStream(path)
stream.on("error", err => reject(err)) stream.on("error", (err) => reject(err))
stream.on("data", chunk => hash.update(chunk)) stream.on("data", (chunk) => hash.update(chunk))
stream.on("end", () => resolve(hash.digest("hex"))) stream.on("end", () => resolve(hash.digest("hex")))
}) })
} }
@ -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) {
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`) 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()
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`) 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

@ -1,5 +1,9 @@
import * as core from "@actions/core" import * as core from "@actions/core"
import { exec } from "child_process" 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 { promisify } from "util"
import { restoreCache, saveCache } from "./cache" import { restoreCache, saveCache } from "./cache"
@ -7,26 +11,91 @@ import { installGo, installLint } from "./install"
import { findLintVersion } from "./version" import { findLintVersion } from "./version"
const execShellCommand = promisify(exec) const execShellCommand = promisify(exec)
const writeFile = promisify(fs.writeFile)
const createTempDir = promisify(dir)
async function prepareLint(): Promise<string> { async function prepareLint(): Promise<string> {
const versionConfig = await findLintVersion() const versionConfig = await findLintVersion()
return await installLint(versionConfig) 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 = github.getOctokit(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() const startedAt = Date.now()
// 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()
const installGoPromise = installGo() const installGoPromise = installGo()
const patchPromise = fetchPatch()
const lintPath = await prepareLintPromise const lintPath = await prepareLintPromise
await installGoPromise await installGoPromise
await restoreCachePromise await restoreCachePromise
const patchPath = await patchPromise
core.info(`Prepared env in ${Date.now() - startedAt}ms`) core.info(`Prepared env in ${Date.now() - startedAt}ms`)
return lintPath return { lintPath, patchPath }
} }
type ExecRes = { type ExecRes = {
@ -43,23 +112,62 @@ 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`) 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`)
printOutput(res) printOutput(res)
} }
const args = core.getInput(`args`) const userArgs = core.getInput(`args`)
if (args.includes(`-out-format`)) { 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`) 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`)
const cmd = `${lintPath} run --out-format=github-actions ${args}`.trimRight() if (patchPath) {
core.info(`Running [${cmd}] ...`) 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=`)
}
const workingDirectory = core.getInput(`working-directory`)
const cmdArgs: ExecOptions = {}
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`)
}
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 || ``}] ...`)
const startedAt = Date.now() const startedAt = Date.now()
try { try {
const res = await execShellCommand(cmd) const res = await execShellCommand(cmd, cmdArgs)
printOutput(res) printOutput(res)
core.info(`golangci-lint found no issues`) core.info(`golangci-lint found no issues`)
} catch (exc) { } catch (exc) {
@ -79,8 +187,8 @@ async function runLint(lintPath: string): Promise<void> {
export async function run(): Promise<void> { export async function run(): Promise<void> {
try { try {
const lintPath = await core.group(`prepare environment`, prepareEnv) const { lintPath, patchPath } = await core.group(`prepare environment`, prepareEnv)
await core.group(`run golangci-lint`, () => runLint(lintPath)) await core.group(`run golangci-lint`, () => runLint(lintPath, patchPath))
} 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)

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])
}

View File

@ -6,11 +6,14 @@ export type Version = {
major: number major: number
minor: number minor: number
patch: number | null patch: number | null
} } | null
const versionRe = /^v(\d+)\.(\d+)(?:\.(\d+))?$/ const versionRe = /^v(\d+)\.(\d+)(?:\.(\d+))?$/
const parseVersion = (s: string): Version => { const parseVersion = (s: string): Version => {
if (s == "latest" || s == "") {
return null
}
const match = s.match(versionRe) const match = s.match(versionRe)
if (!match) { if (!match) {
throw new Error(`invalid version string '${s}', expected format v1.2 or v1.2.3`) 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 = { const minVersion = {
major: 1, major: 1,
minor: 14, minor: 28,
patch: 0, patch: 3,
} }
const isLessVersion = (a: Version, b: Version): boolean => { const isLessVersion = (a: Version, b: Version): boolean => {
if (a == null) {
return true
}
if (b == null) {
return false
}
if (a.major != b.major) { if (a.major != b.major) {
return a.major < b.major return a.major < b.major
} }
if (a.minor != b.minor) { // 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 return a.minor < b.minor
}
if (a.patch === null || b.patch === null) {
return true
}
return a.patch < b.patch
} }
const getRequestedLintVersion = (): Version => { const getRequestedLintVersion = (): Version => {
const requestedLintVersion = core.getInput(`version`, { required: true }) const requestedLintVersion = core.getInput(`version`)
const parsedRequestedLintVersion = parseVersion(requestedLintVersion) const parsedRequestedLintVersion = parseVersion(requestedLintVersion)
if (parsedRequestedLintVersion == null) {
return null
}
if (parsedRequestedLintVersion.patch !== null) { if (parsedRequestedLintVersion.patch !== null) {
throw new Error( throw new Error(
`requested golangci-lint version '${requestedLintVersion}' was specified with the patch version, need specify only minor version` `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> { export async function findLintVersion(): Promise<VersionConfig> {
core.info(`Finding needed golangci-lint version...`) core.info(`Finding needed golangci-lint version...`)
const startedAt = Date.now() const startedAt = Date.now()
const reqLintVersion = getRequestedLintVersion()
const config = await getConfig() const config = await getConfig()
if (!config.MinorVersionToConfig) { if (!config.MinorVersionToConfig) {
core.warning(JSON.stringify(config)) core.warning(JSON.stringify(config))
throw new Error(`invalid config: no MinorVersionToConfig field`) throw new Error(`invalid config: no MinorVersionToConfig field`)
} }
const reqLintVersion = getRequestedLintVersion()
const versionConfig = config.MinorVersionToConfig[stringifyVersion(reqLintVersion)] const versionConfig = config.MinorVersionToConfig[stringifyVersion(reqLintVersion)]
if (!versionConfig) { if (!versionConfig) {
throw new Error(`requested golangci-lint version '${stringifyVersion(reqLintVersion)}' doesn't exist`) throw new Error(`requested golangci-lint version '${stringifyVersion(reqLintVersion)}' doesn't exist`)
@ -118,8 +128,9 @@ export async function findLintVersion(): Promise<VersionConfig> {
} }
core.info( core.info(
`Requested golangci-lint '${stringifyVersion(reqLintVersion)}', using '${versionConfig.TargetVersion}', calculation took ${Date.now() - `Requested golangci-lint '${stringifyVersion(reqLintVersion)}', using '${versionConfig.TargetVersion}', calculation took ${
startedAt}ms` Date.now() - startedAt
}ms`
) )
return versionConfig return versionConfig
} }