Compare commits

..

57 Commits

Author SHA1 Message Date
aaa42aa062 feat: allow to skip golangci-lint installation (#1079) 2024-07-30 00:16:22 +02:00
9ec89731c3 build(deps): bump @types/node from 20.14.11 to 22.0.0 in the dependencies group (#1078) 2024-07-29 14:51:39 +02:00
58838cffc6 build(deps-dev): bump the dev-dependencies group with 3 updates (#1077) 2024-07-29 14:51:11 +02:00
9f3ba2c3a8 build(deps): bump @types/node from 20.14.10 to 20.14.11 in the dependencies group (#1075) 2024-07-22 13:13:46 +02:00
2bd7a04e91 build(deps-dev): bump the dev-dependencies group with 3 updates (#1074) 2024-07-22 13:13:20 +02:00
db819a10bd build(deps-dev): bump the dev-dependencies group with 3 updates (#1073) 2024-07-15 12:41:18 +02:00
d09fb0808a build(deps): bump @types/node from 20.14.9 to 20.14.10 in the dependencies group (#1072) 2024-07-08 13:50:27 +02:00
605617a3e2 build(deps-dev): bump the dev-dependencies group with 4 updates (#1071) 2024-07-08 13:50:01 +02:00
66f63c74bb chore: generate 2024-07-03 01:03:27 +02:00
2c01d264ab fix: home dir on Windows 2024-07-03 00:49:42 +02:00
d8028e1f20 build(deps): bump @types/node from 20.14.8 to 20.14.9 in the dependencies group (#1068) 2024-07-01 14:38:39 +02:00
a0231c4ff0 build(deps-dev): bump the dev-dependencies group with 2 updates (#1067) 2024-07-01 14:38:19 +02:00
e43020d72a build(deps-dev): bump the dev-dependencies group with 3 updates (#1065)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
2024-06-24 14:17:02 +02:00
9e57efc106 build(deps): bump @types/node from 20.14.2 to 20.14.8 in the dependencies group (#1066) 2024-06-24 14:08:00 +02:00
27d925f9c0 docs: fix workflow example 2024-06-22 22:40:58 +02:00
24b3d93762 docs: fix workflow example path 2024-06-22 22:37:29 +02:00
26b1e83940 docs: clarify workflow example path 2024-06-22 22:36:44 +02:00
081b216ccf docs: add Go workspace examples (#1064) 2024-06-22 22:34:31 +02:00
0d98fecd83 build(deps-dev): bump the dev-dependencies group with 3 updates (#1063) 2024-06-17 14:07:20 +02:00
031a2fcd4a build(deps): bump @types/node from 20.14.0 to 20.14.2 in the dependencies group (#1062) 2024-06-10 12:55:17 +02:00
96843aea6d build(deps-dev): bump the dev-dependencies group with 3 updates (#1061) 2024-06-10 12:54:48 +02:00
8032b26298 build(deps-dev): bump the dev-dependencies group across 1 directory with 3 updates (#1053) 2024-06-03 12:25:39 +00:00
dfd6a77317 build(deps): bump @types/node from 20.12.12 to 20.14.0 in the dependencies group (#1051) 2024-06-03 14:13:35 +02:00
e1ff6fb1c1 docs: improve examples 2024-05-27 04:48:36 +02:00
4145754745 docs: add sponsoring links 2024-05-27 02:12:12 +02:00
16507ab8ef docs: improve workflow example 2024-05-26 21:19:24 +02:00
725e01551b docs: improve option examples 2024-05-26 21:16:11 +02:00
32b7e669bc chore: update lock (nodejs 20) 2024-05-24 20:13:29 +02:00
e2918bb1f8 build(deps-dev): bump the dev-dependencies group with 2 updates (#1047) 2024-05-24 19:50:28 +02:00
3f51204e49 chore: improve issues chooser 2024-05-24 19:22:56 +02:00
b7f3daa60e chore: fix typo 2024-05-24 19:20:15 +02:00
952b7b2e57 chore: improve issues chooser 2024-05-24 19:16:52 +02:00
7a82e5f967 chore: groups dependabot updates 2024-05-24 19:16:09 +02:00
4655d13902 chore: add contributing guide 2024-05-23 18:32:17 +02:00
182ce0be58 build(deps-dev): bump @typescript-eslint/parser from 7.8.0 to 7.9.0 (#1044) 2024-05-20 18:37:21 +02:00
bc05d62e37 docs: add explanation for github-token option 2024-05-20 18:31:17 +02:00
8a8f91e859 build(deps): bump @types/node from 20.12.11 to 20.12.12 (#1043) 2024-05-20 14:29:30 +02:00
34be59169b build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.8.0 to 7.9.0 (#1042) 2024-05-20 14:29:08 +02:00
abbeba8940 build(deps): bump @types/node from 20.12.8 to 20.12.11 (#1041) 2024-05-13 12:09:47 +02:00
d7e9c664d4 docs: use a fixed version 2024-05-12 22:03:15 +02:00
42ebe7fde9 chore: generate 2024-05-10 03:49:44 +02:00
7b547992bc fix: remove debug logs 2024-05-10 03:47:36 +02:00
a4f60bb28d fix: use 3-dots syntax for diff on push (#1040) 2024-05-08 05:51:20 +02:00
5815a4b917 doc: improve readme 2024-05-07 02:02:33 +02:00
23faadfdeb doc: improve readme 2024-05-07 01:56:19 +02:00
b556f25b3c doc: improve readme 2024-05-07 01:44:28 +02:00
789f114c52 feat: rewrite format handling (#1038) 2024-05-07 01:40:17 +02:00
d36b91c294 build(deps-dev): bump @typescript-eslint/parser from 7.7.1 to 7.8.0 (#1035) 2024-05-06 15:48:38 +02:00
a9eb115348 build(deps): bump @types/node from 20.12.7 to 20.12.8 (#1036) 2024-05-06 15:42:05 +02:00
bd4fa7c900 build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.7.1 to 7.8.0 (#1034) 2024-05-06 15:41:21 +02:00
38e1018663 feat: improve log about pwd/cwd (#1033) 2024-05-05 01:13:21 +02:00
21e9e6b47f feat: use OS and working-directory as cache key (#1032) 2024-05-04 18:43:48 +02:00
dbe4fc23f1 chore: use getBooleanInput 2024-05-04 17:49:04 +02:00
dbb7ebcd4c feat: add option to control cache invalidation interval (#1031) 2024-05-04 17:47:25 +02:00
ecb32920c6 feat: uses 2 dots compare syntax for push diff (#1030) 2024-05-04 16:54:30 +02:00
046435d14c doc: improve options documentation 2024-05-04 02:42:39 +02:00
ca8befdfb6 doc: improve options documentation 2024-05-04 02:36:06 +02:00
17 changed files with 12170 additions and 13678 deletions

25
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,25 @@
## How to contribute
### Did you find a bug?
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/golangci/golangci-lint-action/issues).
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/golangci/golangci-lint-action/issues/new).
Be sure to include a **title and clear description**, as much relevant information as possible,
and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
* **Do not open up a GitHub issue if the bug is a security vulnerability**,
and instead to refer to our [security policy](https://github.com/golangci/golangci-lint-action?tab=security-ov-file).
### Do you intend to add a new feature or change an existing one?
* Suggest your change inside an [issue](https://github.com/golangci/golangci-lint-action/issues).
* Do not open a pull request on GitHub until you have collected positive feedback about the change.
### Did you write a patch that fixes a bug?
* Open a new GitHub pull request with the patch.
* Ensure the PR description clearly describes the problem and solution.
Include the relevant issue number if applicable.

View File

@ -1,4 +1,4 @@
name: Bug Report name: 🐞 Bug Report
description: "Create a report to help us improve." description: "Create a report to help us improve."
body: body:
- type: checkboxes - type: checkboxes
@ -36,14 +36,29 @@ body:
required: true required: true
- type: textarea - type: textarea
id: config id: workflow-file
attributes: attributes:
label: Workflow file label: Workflow file
value: |- value: |-
<details> <details>
```yml
<add your file content here>
``` ```
<add you file here>
</details>
validations:
required: true
- type: textarea
id: config
attributes:
label: Golangci-lint configuration
value: |-
<details>
```yml
<add your file content here>
``` ```
</details> </details>

View File

@ -1,11 +1,14 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Questions - name: 📖 Golangci-lint documentation
url: https://github.com/golangci/golangci-lint-action/discussions
about: If you have a question, or are looking for advice, please post on our Discussions forum!
- name: golangci-lint main repository
url: https://github.com/golangci/golangci-lint
about: The main repository of golangci-lint.
- name: golangci-lint documentation
url: https://golangci-lint.run url: https://golangci-lint.run
about: Please take a look to our documentation. about: Please take a look to our documentation.
- name: ❓ Questions
url: https://github.com/golangci/golangci-lint-action/discussions
about: If you have a question, or are looking for advice, please post on our Discussions forum!
- name: 💬 Chat on Slack
url: https://gophers.slack.com/archives/CS0TBRKPC
about: Maybe chatting with the community can help
- name: 🏡 Golangci-lint main repository
url: https://github.com/golangci/golangci-lint
about: The main repository of golangci-lint.

View File

@ -1,4 +1,4 @@
name: Feature request name: 💡 Feature request
description: "Suggest an idea for this project." description: "Suggest an idea for this project."
body: body:
- type: checkboxes - type: checkboxes

View File

@ -6,5 +6,10 @@ updates:
interval: weekly interval: weekly
- package-ecosystem: npm - package-ecosystem: npm
directory: "/" directory: "/"
groups:
dev-dependencies:
dependency-type: development
dependencies:
dependency-type: production
schedule: schedule:
interval: weekly interval: weekly

402
README.md
View File

@ -8,19 +8,28 @@ The action runs [golangci-lint](https://github.com/golangci/golangci-lint) and r
![GitHub Annotations](./static/annotations.png) ![GitHub Annotations](./static/annotations.png)
## Compatibility ![Logs](./static/colored-line-number.png)
* `v5.0.0+` removes `skip-pkg-cache` and `skip-build-cache` because the cache related to Go itself is already handled by `actions/setup-go`. ## Supporting Us
* `v4.0.0+` requires an explicit `actions/setup-go` installation step before using this action: `uses: actions/setup-go@v5`.
The `skip-go-installation` option has been removed. <!-- [![GitHub Sponsors](https://img.shields.io/badge/GitHub-Donate-blue?logo=github&style=for-the-badge)](https://github.com/sponsors/golangci) -->
* `v2.0.0+` works with `golangci-lint` version >= `v1.28.3` [![Open Collective backers and sponsors](https://img.shields.io/badge/OpenCollective-Donate-blue?logo=opencollective&style=for-the-badge)](https://opencollective.com/golangci-lint)
* `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)) [![Linter Authors](https://img.shields.io/badge/Linter_Authors-Donate-blue?style=for-the-badge)](https://golangci-lint.run/product/thanks/)
* `v1.2.1` works with `golangci-lint` version >= `v1.14.0` ([issue](https://github.com/golangci/golangci-lint-action/issues/39))
`golangci-lint` is a free and open-source project built by volunteers.
If you value it, consider supporting us, we appreciate it! :heart:
## How to use ## How to use
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).
Add `.github/workflows/golangci-lint.yml` with the following contents: Add `.github/workflows/golangci-lint.yml` with the following contents:
<details>
<summary>Simple Example</summary>
```yaml ```yaml
name: golangci-lint name: golangci-lint
on: on:
@ -43,21 +52,17 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version: '1.22' go-version: stable
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
version: latest version: v1.59
``` ```
We recommend running this action in a job separate from other jobs (`go test`, etc.) </details>
because different jobs [run in parallel](https://help.github.com/en/actions/getting-started-with-github-actions/core-concepts-for-github-actions#job).
### Multiple OS Support <details>
<summary>Multiple OS Example</summary>
If you need to run linters for specific operating systems, you will need to use the action `>=v2`.
Here is a sample configuration file:
```yaml ```yaml
name: golangci-lint name: golangci-lint
@ -77,7 +82,7 @@ jobs:
golangci: golangci:
strategy: strategy:
matrix: matrix:
go: ['1.22'] go: [stable]
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
name: lint name: lint
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -87,9 +92,9 @@ jobs:
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
version: latest version: v1.59
``` ```
You will also likely need to add the following `.gitattributes` file to ensure that line endings for Windows builds are properly formatted: You will also likely need to add the following `.gitattributes` file to ensure that line endings for Windows builds are properly formatted:
@ -98,93 +103,373 @@ You will also likely need to add the following `.gitattributes` file to ensure t
*.go text eol=lf *.go text eol=lf
``` ```
</details>
<details>
<summary>Go Workspace Example</summary>
```yaml
name: golangci-lint
on:
pull_request:
push:
branches:
- "main"
- "master"
env:
GO_VERSION: stable
GOLANGCI_LINT_VERSION: v1.59
jobs:
detect-modules:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- id: set-modules
run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT
golangci-lint:
needs: detect-modules
runs-on: ubuntu-latest
strategy:
matrix:
modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v6
with:
version: ${{ env.GOLANGCI_LINT_VERSION }}
working-directory: ${{ matrix.modules }}
```
</details>
<details>
<summary>Go Workspace Example (Multiple OS)</summary>
```yaml
# ./.github/workflows/golangci-lint.yml
name: golangci-lint (multi OS)
on:
pull_request:
push:
branches:
- "main"
- "master"
jobs:
golangci-lint:
strategy:
matrix:
go-version: [ stable, oldstable ]
os: [ubuntu-latest, macos-latest, windows-latest]
uses: ./.github/workflows/.golangci-lint-reusable.yml
with:
os: ${{ matrix.os }}
go-version: ${{ matrix.go-version }}
golangci-lint-version: v1.59
```
```yaml
# ./.github/workflows/.golangci-lint-reusable.yml
name: golangci-lint-reusable
on:
workflow_call:
inputs:
os:
description: 'OS'
required: true
type: string
go-version:
description: 'Go version'
required: true
type: string
default: stable
golangci-lint-version:
description: 'Golangci-lint version'
type: string
default: 'v1.59.1'
jobs:
detect-modules:
runs-on: ${{ inputs.os }}
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ inputs.go-version }}
- id: set-modules
shell: bash # require for Windows to be able to use $GITHUB_OUTPUT https://github.com/actions/runner/issues/2224
run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT
golangci-lint:
needs: detect-modules
runs-on: ${{ inputs.os }}
strategy:
matrix:
modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ inputs.go-version }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v6
with:
version: ${{ inputs.golangci-lint-version }}
working-directory: ${{ matrix.modules }}
```
You will also likely need to add the following `.gitattributes` file to ensure that line endings for Windows builds are properly formatted:
```.gitattributes
*.go text eol=lf
```
</details>
## Compatibility
* `v6.0.0+` removes `annotations` option, removes the default output format (`github-actions`).
* `v5.0.0+` removes `skip-pkg-cache` and `skip-build-cache` because the cache related to Go itself is already handled by `actions/setup-go`.
* `v4.0.0+` requires an explicit `actions/setup-go` installation step before using this action: `uses: actions/setup-go@v5`.
The `skip-go-installation` option has been removed.
* `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))
## Options ## Options
`version`: (required) The version of golangci-lint to use. ### `version`
* When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
* When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. (required)
The version of golangci-lint to use.
When `install-mode` is:
* `binary` (default): the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
* `goinstall`: the value can be v1.2.3, `latest`, or the hash of a commit.
* `none`: the value is ignored.
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
version: latest version: v1.58
# ... # ...
``` ```
`install-mode`: (optional) The mode to install golangci-lint. </details>
It can be `binary` or `goinstall`.
### `install-mode`
(optional)
The mode to install golangci-lint: it can be `binary`, `goinstall`, or `none`.
The default value is `binary`. The default value is `binary`.
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
install-mode: "goinstall" install-mode: "goinstall"
# ... # ...
``` ```
`only-new-issues`: (optional) Show only new issues. </details>
If you are using `merge_group` event (merge queue) you should add the option `fetch-depth: 0` to `actions/checkout` step.
The default value is `false`. ### `github-token`
(optional)
When using `only-new-issues` option, the GitHub API is used, so a token is required.
By default, it uses the `github.token` from the action.
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with:
github-token: xxx
# ...
```
</details>
### `only-new-issues`
(optional)
Show only new issues.
The default value is `false`.
* `pull_request` and `pull_request_target`: the action gets the diff of the PR content from the [GitHub API](https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#get-a-pull-request) and use it with `--new-from-patch`.
* `push`: the action gets the diff of the push content (difference between commits before and after the push) from the [GitHub API](https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#compare-two-commits) and use it with `--new-from-patch`.
* `merge_group`: the action gets the diff by using `--new-from-rev` option (relies on git).
You should add the option `fetch-depth: 0` to `actions/checkout` step.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v6
with: with:
only-new-issues: true only-new-issues: true
# ... # ...
``` ```
`working-directory`: (optional) working directory, useful for monorepos. </details>
### `working-directory`
(optional)
Working directory, useful for monorepos.
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
working-directory: somedir working-directory: somedir
# ... # ...
``` ```
`skip-cache`: (optional) If set to `true`, then all caching functionality will be completely disabled, </details>
takes precedence over all other caching options.
The default value is `false`. ### `args`
(optional)
golangci-lint command line arguments.
Note: By default, the `.golangci.yml` file should be at the root of the repository.
The location of the configuration file can be changed by using `--config=`
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with:
args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
# ...
```
</details>
### `problem-matchers`
(optional)
Force the usage of the embedded problem matchers.
By default, the [problem matcher of Go (`actions/setup-go`)](https://github.com/actions/setup-go/blob/main/matchers.json) already handles the golangci-lint output (`colored-line-number`).
Works only with `colored-line-number` (the golangci-lint default).
https://golangci-lint.run/usage/configuration/#output-configuration
The default value is `false`.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v6
with:
problem-matchers: true
# ...
```
</details>
### `skip-cache`
(optional)
If set to `true`, then all caching functionality will be completely disabled,
takes precedence over all other caching options.
The default value is `false`.
<details>
<summary>Example</summary>
```yml
uses: golangci/golangci-lint-action@v6
with: with:
skip-cache: true skip-cache: true
# ... # ...
``` ```
`skip-save-cache`: (optional) If set to `true`, caches will not be saved, but they may still be restored, required `skip-cache: false`. </details>
### `skip-save-cache`
(optional)
If set to `true`, caches will not be saved, but they may still be restored, required `skip-cache: false`.
The default value is `false`. The default value is `false`.
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
skip-save-cache: true skip-save-cache: true
# ... # ...
``` ```
`annotations`: (optional) To enable/disable GitHub Action annotations. </details>
If disabled (`false`), the output format(s) will follow the golangci-lint configuration file and use the same default as golangci-lint (i.e. `colored-line-number`).
https://golangci-lint.run/usage/configuration/#output-configuration ### `cache-invalidation-interval`
The default value is `true`.
(optional)
Periodically invalidate the cache every `cache-invalidation-interval` days to ensure that outdated data is removed and fresh data is loaded.
The default value is `7`.
If set the number is `<= 0`, the cache will be always invalidate (Not recommended).
<details>
<summary>Example</summary>
```yml ```yml
uses: golangci/golangci-lint-action@v5 uses: golangci/golangci-lint-action@v6
with: with:
annotations: false cache-invalidation-interval: 15
# ... # ...
``` ```
`args`: (optional) golangci-lint command line arguments. </details>
Note: By default, the `.golangci.yml` file should be at the root of the repository.
The location of the configuration file can be changed by using `--config=`
```yml
uses: golangci/golangci-lint-action@v5
with:
args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
# ...
```
## Annotations ## Annotations
@ -246,10 +531,11 @@ Inside our action, we perform 3 steps:
### Caching internals ### Caching internals
1. We save and restore the following directory: `~/.cache/golangci-lint`. 1. We save and restore the following directory: `~/.cache/golangci-lint`.
2. The primary caching key looks like `golangci-lint.cache-{interval_number}-{go.mod_hash}`. 2. The primary caching key looks like `golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-{go.mod_hash}`.
Interval number ensures that we periodically invalidate our cache (every 7 days). 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. `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}-`. 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-{runner_os}-{working_directory}-{interval_number}-`.
GitHub matches keys by prefix if we have no exact match for the primary cache. GitHub matches keys by prefix if we have no exact match for the primary cache.
This scheme is basic and needs improvements. Pull requests and ideas are welcome. This scheme is basic and needs improvements. Pull requests and ideas are welcome.

View File

@ -6,11 +6,13 @@ inputs:
version: version:
description: | description: |
The version of golangci-lint to use. The version of golangci-lint to use.
When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. When `install-mode` is:
When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. - `binary` (default): the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
- `goinstall`: the value can be v1.2.3, `latest`, or the hash of a commit.
- `none`: the value is ignored.
required: false required: false
install-mode: install-mode:
description: "The mode to install golangci-lint. It can be 'binary' or 'goinstall'." description: "The mode to install golangci-lint. It can be 'binary', 'goinstall', or 'none'."
default: "binary" default: "binary"
required: false required: false
working-directory: working-directory:
@ -36,14 +38,18 @@ inputs:
restore existing caches, subject to other options. restore existing caches, subject to other options.
default: 'false' default: 'false'
required: false required: false
annotations: problem-matchers:
description: "To Enable/disable GitHub Action annotations" description: "Force the usage of the embedded problem matchers"
default: 'true' default: 'false'
required: false required: false
args: args:
description: "golangci-lint command line arguments" description: "golangci-lint command line arguments"
default: "" default: ""
required: false required: false
cache-invalidation-interval:
description: "Periodically invalidate a cache because a new code being added. (number of days)"
default: '7'
required: false
runs: runs:
using: "node20" using: "node20"
main: "dist/run/index.js" main: "dist/run/index.js"

10165
dist/post_run/index.js generated vendored

File diff suppressed because it is too large Load Diff

10165
dist/run/index.js generated vendored

File diff suppressed because it is too large Load Diff

4891
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,21 +30,23 @@
"@actions/github": "^6.0.0", "@actions/github": "^6.0.0",
"@actions/http-client": "^2.2.1", "@actions/http-client": "^2.2.1",
"@actions/tool-cache": "^2.0.1", "@actions/tool-cache": "^2.0.1",
"@types/node": "^20.12.7", "@types/node": "^22.0.0",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"@types/tmp": "^0.2.6", "@types/tmp": "^0.2.6",
"tmp": "^0.2.3" "@types/which": "^3.0.4",
"tmp": "^0.2.3",
"which": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/eslint-plugin": "^7.17.0",
"@typescript-eslint/parser": "^7.7.1", "@typescript-eslint/parser": "^7.17.0",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-simple-import-sort": "^12.1.1",
"prettier": "^3.2.5", "prettier": "^3.3.3",
"typescript": "^5.4.5" "typescript": "^5.5.4"
} }
} }

17
problem-matchers.json Normal file
View File

@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "golangci-lint-colored-line-number",
"severity": "error",
"pattern": [
{
"regexp": "^([^:]+):(\\d+):(?:(\\d+):)?\\s+(.+ \\(.+\\))$",
"file": 1,
"line": 2,
"column": 3,
"message": 4
}
]
}
]
}

View File

@ -20,11 +20,18 @@ function checksumFile(hashName: string, path: string): Promise<string> {
const pathExists = async (path: string): Promise<boolean> => !!(await fs.promises.stat(path).catch(() => false)) const pathExists = async (path: string): Promise<boolean> => !!(await fs.promises.stat(path).catch(() => false))
const getLintCacheDir = (): string => { const getLintCacheDir = (): string => {
return path.resolve(`${process.env.HOME}/.cache/golangci-lint`) const home = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME
return path.resolve(`${home}`, `.cache`, `golangci-lint`)
} }
const getIntervalKey = (invalidationIntervalDays: number): string => { const getIntervalKey = (invalidationIntervalDays: number): string => {
const now = new Date() const now = new Date()
if (invalidationIntervalDays <= 0) {
return `${now.getTime()}`
}
const secondsSinceEpoch = now.getTime() / 1000 const secondsSinceEpoch = now.getTime() / 1000
const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400)) const intervalNumber = Math.floor(secondsSinceEpoch / (invalidationIntervalDays * 86400))
return intervalNumber.toString() return intervalNumber.toString()
@ -32,28 +39,42 @@ const getIntervalKey = (invalidationIntervalDays: number): string => {
async function buildCacheKeys(): Promise<string[]> { async function buildCacheKeys(): Promise<string[]> {
const keys = [] const keys = []
// Periodically invalidate a cache because a new code being added.
// TODO: configure it via inputs. // Cache by OS.
let cacheKey = `golangci-lint.cache-${getIntervalKey(7)}-` let cacheKey = `golangci-lint.cache-${process.env?.RUNNER_OS}-`
keys.push(cacheKey)
// Get working directory from input // Get working directory from input
const workingDirectory = core.getInput(`working-directory`) const workingDirectory = core.getInput(`working-directory`)
if (workingDirectory) {
cacheKey += `${workingDirectory}-`
}
// Periodically invalidate a cache because a new code being added.
const invalidationIntervalDays = parseInt(core.getInput(`cache-invalidation-interval`, { required: true }).trim())
cacheKey += `${getIntervalKey(invalidationIntervalDays)}-`
keys.push(cacheKey)
// create path to go.mod prepending the workingDirectory if it exists // create path to go.mod prepending the workingDirectory if it exists
const goModPath = path.join(workingDirectory, `go.mod`) const goModPath = path.join(workingDirectory, `go.mod`)
core.info(`Checking for go.mod: ${goModPath}`) core.info(`Checking for go.mod: ${goModPath}`)
if (await pathExists(goModPath)) { if (await pathExists(goModPath)) {
// Add checksum to key to invalidate a cache when dependencies change. // Add checksum to key to invalidate a cache when dependencies change.
cacheKey += await checksumFile(`sha1`, goModPath) cacheKey += await checksumFile(`sha1`, goModPath)
} else { } else {
cacheKey += `nogomod` cacheKey += `nogomod`
} }
keys.push(cacheKey) keys.push(cacheKey)
return keys return keys
} }
export async function restoreCache(): Promise<void> { export async function restoreCache(): Promise<void> {
if (core.getInput(`skip-cache`, { required: true }).trim() == "true") return if (core.getBooleanInput(`skip-cache`, { required: true })) return
if (!utils.isValidEvent()) { if (!utils.isValidEvent()) {
utils.logWarning( utils.logWarning(
@ -95,8 +116,8 @@ export async function restoreCache(): Promise<void> {
} }
export async function saveCache(): Promise<void> { export async function saveCache(): Promise<void> {
if (core.getInput(`skip-cache`, { required: true }).trim() == "true") return if (core.getBooleanInput(`skip-cache`, { required: true })) return
if (core.getInput(`skip-save-cache`, { required: true }).trim() == "true") return if (core.getBooleanInput(`skip-save-cache`, { required: true })) return
// Validate inputs, this can cause task failure // Validate inputs, this can cause task failure
if (!utils.isValidEvent()) { if (!utils.isValidEvent()) {

View File

@ -38,6 +38,7 @@ const getAssetURL = (versionConfig: VersionConfig): string => {
export enum InstallMode { export enum InstallMode {
Binary = "binary", Binary = "binary",
GoInstall = "goinstall", GoInstall = "goinstall",
None = "none",
} }
type ExecRes = { type ExecRes = {

View File

@ -6,6 +6,7 @@ import * as fs from "fs"
import * as path from "path" import * as path from "path"
import { dir } from "tmp" import { dir } from "tmp"
import { promisify } from "util" import { promisify } from "util"
import which from "which"
import { restoreCache, saveCache } from "./cache" import { restoreCache, saveCache } from "./cache"
import { installLint, InstallMode } from "./install" import { installLint, InstallMode } from "./install"
@ -17,17 +18,20 @@ const writeFile = promisify(fs.writeFile)
const createTempDir = promisify(dir) const createTempDir = promisify(dir)
function isOnlyNewIssues(): boolean { function isOnlyNewIssues(): boolean {
const onlyNewIssues = core.getInput(`only-new-issues`, { required: true }).trim() return core.getBooleanInput(`only-new-issues`, { required: true })
if (onlyNewIssues !== `false` && onlyNewIssues !== `true`) {
throw new Error(`invalid value of "only-new-issues": "${onlyNewIssues}", expected "true" or "false"`)
}
return onlyNewIssues === `true`
} }
async function prepareLint(): Promise<string> { async function prepareLint(): Promise<string> {
const mode = core.getInput("install-mode").toLowerCase() const mode = core.getInput("install-mode").toLowerCase()
if (mode === InstallMode.None) {
const bin = await which("golangci-lint", { nothrow: true })
if (!bin) {
throw new Error("golangci-lint binary not found in the PATH")
}
return bin
}
const versionConfig = await findLintVersion(<InstallMode>mode) const versionConfig = await findLintVersion(<InstallMode>mode)
return await installLint(versionConfig, <InstallMode>mode) return await installLint(versionConfig, <InstallMode>mode)
@ -47,7 +51,6 @@ async function fetchPatch(): Promise<string> {
case `push`: case `push`:
return await fetchPushPatch(ctx) return await fetchPushPatch(ctx)
case `merge_group`: case `merge_group`:
core.info(JSON.stringify(ctx.payload))
return `` return ``
default: default:
core.info(`Not fetching patch for showing only new issues because it's not a pull request context: event name is ${ctx.eventName}`) core.info(`Not fetching patch for showing only new issues because it's not a pull request context: event name is ${ctx.eventName}`)
@ -104,11 +107,10 @@ async function fetchPushPatch(ctx: Context): Promise<string> {
let patch: string let patch: string
try { try {
const patchResp = await octokit.rest.repos.compareCommits({ const patchResp = await octokit.rest.repos.compareCommitsWithBasehead({
owner: ctx.repo.owner, owner: ctx.repo.owner,
repo: ctx.repo.repo, repo: ctx.repo.repo,
base: ctx.payload.before, basehead: `${ctx.payload.before}...${ctx.payload.after}`,
head: ctx.payload.after,
mediaType: { mediaType: {
format: `diff`, format: `diff`,
}, },
@ -192,21 +194,32 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
const userArgsMap = new Map<string, string>(userArgsList) const userArgsMap = new Map<string, string>(userArgsList)
const userArgNames = new Set<string>(userArgsList.map(([key]) => key)) const userArgNames = new Set<string>(userArgsList.map(([key]) => key))
const annotations = core.getInput(`annotations`).trim() !== "false" const problemMatchers = core.getBooleanInput(`problem-matchers`)
if (annotations) { if (problemMatchers) {
const formats = (userArgsMap.get("out-format") || "") const matchersPath = path.join(__dirname, "../..", "problem-matchers.json")
.trim() if (fs.existsSync(matchersPath)) {
.split(",") // Adds problem matchers.
.filter((f) => f.length > 0) // https://github.com/actions/setup-go/blob/cdcb36043654635271a94b9a6d1392de5bb323a7/src/main.ts#L81-L83
.filter((f) => !f.startsWith(`github-actions`)) core.info(`##[add-matcher]${matchersPath}`)
.concat("github-actions") }
.join(",")
addedArgs.push(`--out-format=${formats}`)
userArgs = userArgs.replace(/--out-format=\S*/gi, "").trim()
} }
const formats = (userArgsMap.get("out-format") || "")
.trim()
.split(",")
.filter((f) => f.length > 0)
.filter((f) => !f.startsWith(`github-actions`)) // Removes `github-actions` format.
.join(",")
if (formats) {
// Adds formats but without `github-actions` format.
addedArgs.push(`--out-format=${formats}`)
}
// Removes `--out-format` from the user flags because it's already inside `addedArgs`.
userArgs = userArgs.replace(/--out-format=\S*/gi, "").trim()
if (isOnlyNewIssues()) { if (isOnlyNewIssues()) {
if (userArgNames.has(`new`) || userArgNames.has(`new-from-rev`) || userArgNames.has(`new-from-patch`)) { 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`) throw new Error(`please, don't specify manually --new* args when requesting only new issues`)
@ -240,8 +253,9 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
} }
} }
const workingDirectory = core.getInput(`working-directory`)
const cmdArgs: ExecOptions = {} const cmdArgs: ExecOptions = {}
const workingDirectory = core.getInput(`working-directory`)
if (workingDirectory) { if (workingDirectory) {
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`)
@ -254,7 +268,7 @@ async function runLint(lintPath: string, patchPath: string): Promise<void> {
const cmd = `${lintPath} run ${addedArgs.join(` `)} ${userArgs}`.trimEnd() const cmd = `${lintPath} run ${addedArgs.join(` `)} ${userArgs}`.trimEnd()
core.info(`Running [${cmd}] in [${cmdArgs.cwd || ``}] ...`) core.info(`Running [${cmd}] in [${cmdArgs.cwd || process.cwd()}] ...`)
const startedAt = Date.now() const startedAt = Date.now()
try { try {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB