golangci / golangci-lint

Fast linters runner for Go
https://golangci-lint.run
GNU General Public License v3.0
15.65k stars 1.39k forks source link

Could not find file '/tmp/golangci-lint-action-problem-matchers.json' #4695

Closed d-honeybadger closed 6 months ago

d-honeybadger commented 6 months ago

Welcome

Description of the problem

In the 1.58.0 release, github-actions output print fails w/ the following error: (GHA logs)

Error: Unable to process command '::add-matcher::/tmp/golangci-lint-action-problem-matchers.json' successfully.
Error: Could not find file '/tmp/golangci-lint-action-problem-matchers.json'

The same linting action is working fine w/ golangci-lint v1.57

Version of golangci-lint

```console $ golangci-lint --version golangci-lint has version 1.58.0 built with go1.22.2 from 28b3813c on 2024-05-03T18:05:38Z ```

Configuration

```bash --out-format=github-actions --path-prefix=src/core/kpp-api --config=../../.golangci.yml --timeout=10m ``` ```yml linters: enable: - bodyclose - containedctx - decorder - depguard - dogsled - dupword - errcheck - errchkjson - errname - errorlint - exhaustive - goconst - gocritic - gofmt - goimports - gomodguard - gosec - gosimple - govet - maintidx - makezero - misspell - musttag - nakedret - nilerr - nilnil - noctx - nolintlint - nosprintfhostport - revive - thelper - typecheck - unconvert - unused - usestdlibvars - whitespace issues: include: - EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments exclude-rules: - path: '(.+)_test\.go' linters: # table-driven tests have growing lists of test cases # which trigger maintidx's "too complex" verdict - maintidx linters-settings: depguard: rules: main: allow: - $gostd - bits.linode.com - helm.sh - k8s.io - sigs.k8s.io - dario.cat/mergo - filippo.io/age - github.com/aws/aws-sdk-go - github.com/gin-gonic/gin - github.com/gin-contrib/logger - github.com/go-logr - github.com/hashicorp - github.com/helm/helm/pkg/engine - github.com/linode - github.com/rs/zerolog - github.com/spf13 - github.com/stretchr/testify/assert - github.com/go-git/go-billy/v5/osfs - github.com/go-git/go-git/v5 - github.com/ianschenck/envflag - github.com/gin-contrib/logger - github.com/gin-contrib/graceful - github.com/swaggo - github.com/google - github.com/akamai/AkamaiOPEN-edgegrid-golang/v7 - github.com/apex/log - github.com/crossplane/crossplane-runtime - github.com/prometheus/client_golang/prometheus - github.com/prometheus/common/expfmt - github.com/fsnotify/fsnotify revive: rules: - name: exported arguments: ["checkPrivateReceivers", "disableStutteringCheck"] ```

Go environment

```console $ go version && go env go version go1.21.5 linux/amd64 GO111MODULE='' GOARCH='amd64' GOBIN='' GOCACHE='/tmp/tmp.g37yoMdf3y/gocache' GOENV='/github/home/.config/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='amd64' GOHOSTOS='linux' GOINSECURE='' GOMODCACHE='/tmp/tmp.g37yoMdf3y/gomodcache' GONOPROXY='' GONOSUMDB='' GOOS='linux' GOPATH='/github/home/go' GOPRIVATE='' GOPROXY='https://proxy.golang.org,direct' GOROOT='/__t/go/1.21.5/x64' GOSUMDB='sum.golang.org' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/__t/go/1.21.5/x64/pkg/tool/linux_amd64' GOVCS='' GOVERSION='go1.21.5' GCCGO='gccgo' GOAMD64='v1' AR='ar' CC='gcc' CXX='g++' CGO_ENABLED='0' GOMOD='/dev/null' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' ```

Verbose output of running

```console $ golangci-lint cache clean $ golangci-lint run -v Running [/github/home/golangci-lint-1.58.0-linux-amd64/golangci-lint run --out-format=github-actions --path-prefix=src/core/kpp-api --config=${GITHUB_WORKSPACE}/src/.golangci.yml --timeout=10m --verbose] in [/__w/kpp-services/kpp-services/src/core/kpp-api] ... Error: Unable to process command '::add-matcher::/tmp/golangci-lint-action-problem-matchers.json' successfully. Error: Could not find file '/tmp/golangci-lint-action-problem-matchers.json'. level=info msg="[config_reader] Used config file ../../.golangci.yml" level=info msg="[lintersdb] Active 37 linters: [bodyclose containedctx decorder depguard dogsled dupword errcheck errchkjson errname errorlint exhaustive goconst gocritic gofmt goimports gomodguard gosec gosimple govet ineffassign maintidx makezero misspell musttag nakedret nilerr nilnil noctx nolintlint nosprintfhostport revive staticcheck thelper unconvert unused usestdlibvars whitespace]" level=info msg="[loader] Go packages loading at mode 575 (files|imports|name|exports_file|deps|types_sizes|compiled_files) took 39.4366455[31](https://bits.linode.com/CNS/kpp-services/actions/runs/263033/job/705302?pr=519#step:7:33)s" level=info msg="[runner/filename_unadjuster] Pre-built 0 adjustments in 9.265609ms" level=info msg="[linters_context/goanalysis] analyzers took 1m38.335811263s with top 10 stages: buildir: 1m16.889408652s, exhaustive: 3.512448189s, inspect: 3.473982183s, fact_deprecated: 2.290792748s, nilness: 2.204405153s, ctrlflow: 2.04248517s, printf: 1.796923649s, fact_purity: 1.476338989s, typedness: 796.471927ms, SA5012: 717.462302ms" level=info msg="[runner] Issues before processing: 19, after processing: 0" level=info msg="[runner] Processors filtering stat (out/in): cgo: 19/19, filename_unadjuster: 19/19, skip_dirs: 19/19, identifier_marker: 19/19, exclude-rules: 0/19, invalid_issue: 19/19, path_prettifier: 19/19, skip_files: 19/19, autogenerated_exclude: 19/19, exclude: 19/19" level=info msg="[runner] processing took 2.[32](https://bits.linode.com/CNS/kpp-services/actions/runs/263033/job/705302?pr=519#step:7:34)4684ms with stages: exclude-rules: 943.336µs, identifier_marker: 766.101µs, path_prettifier: 295.378µs, autogenerated_exclude: 187.176µs, skip_dirs: 80.122µs, filename_unadjuster: 36.801µs, cgo: 8.59µs, invalid_issue: 2.58µs, max_same_issues: 800ns, nolint: 780ns, uniq_by_line: 550ns, skip_files: 480ns, fixer: [35](https://bits.linode.com/CNS/kpp-services/actions/runs/263033/job/705302?pr=519#step:7:37)0ns, exclude: 260ns, sort_results: 220ns, diff: 190ns, severity-rules: 190ns, max_from_linter: 180ns, path_prefixer: 180ns, source_code: 150ns, path_shortener: 140ns, max_per_file_from_linter: 130ns" level=info msg="[runner] linters took 18.751607084s with stages: goanalysis_metalinter: 18.748486136s" level=info msg="File cache stats: 20 entries of total size 264.7KiB" level=info msg="Memory: 573 samples, avg is 358.4MB, max is 1583.7MB" level=info msg="Execution took 58.205542098s" golangci-lint found no issues Ran golangci-lint in 58474ms ```

A minimal reproducible example or link to a public repository

The issue isn't about any specific linting rule :shr

Validation

boring-cyborg[bot] commented 6 months ago

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

ldez commented 6 months ago

Hello,

/tmp/golangci-lint-action-problem-matchers.json is a new element of v1.58, this file didn't exist before.

The file is created by the golangci-lint (only for the specific GitHub action format) before the print and the file is never removed.

I'll investigate, but if anyone has the same problem on the public repository, I'm interested in a link to your CI.

ldez commented 6 months ago

@d-honeybadger can I have your GHA workflow file?

sfc-gh-raram commented 6 months ago

I'm also experiencing this same issue. Curious to see what the issue is.

ldez commented 6 months ago

If you are facing the same problem, the best way to contribute is to provide the following information:

kranurag7 commented 6 months ago

adding my workflow if it helps in reproducing this error.

Workflow file: https://github.com/syself/cluster-api-provider-hetzner/blob/d5283ddad87bd2046ab4e48f28f9dbf73f5301f2/.github/workflows/pr-lint.yml

Job: https://github.com/syself/cluster-api-provider-hetzner/actions/runs/8950020631/job/24614442431

PR introducing update to 1.58.0: https://github.com/syself/cluster-api-provider-hetzner/pull/1288

We use renovate to update golangci-lint and above PR introduced the change and CI reported the error mentioned above.

No rush, please take your time fixing this. Thank you for all the work you do.

ldez commented 6 months ago

You are not using the GitHub Action but the Docker image or the binary. I think it's a bad idea to use --out-format=github-actions in this context.

https://github.com/syself/cluster-api-provider-hetzner/blob/d5283ddad87bd2046ab4e48f28f9dbf73f5301f2/Makefile#L689-L700

kranurag7 commented 6 months ago

Yes, we want to use the same thing locally and in CI that's why we run the workflow inside a container. I'll look into updating the output format.

ldez commented 6 months ago

github-actions format has a lot of limitations (ex: max 10 annotations), I think the default output format (i.e. colored-line-number) will be better in your context.

In all cases, thank you for providing a reproducible context :heart:

d-honeybadger commented 6 months ago

Sorry for the delay @ldez It's on enterprize GHA (fwiw this could be part of the issue :shrug: ), so here's the workflow file snippet:

name: Lint, test, build - reusable

on:
  workflow_call:
    # inputs here, shouldn't be relevant

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    runs-on: self-hosted
    container: debian:bullseye-slim
    steps:
      - uses: actions/checkout@v3
      # Default GOCACHE/GOMODCACHE paths are in ${HOME} which is mounted from
      # host and may contain partially written fragments (e.g a module with some files missing)
      # if the mount snapshot is taken at the time of installing packages/building
      - name: Set Go Cache Paths
        run: |
          CACHE_DIR=$(mktemp -d)
          mkdir ${CACHE_DIR}/gocache
          mkdir ${CACHE_DIR}/gomodcache
          echo "GOCACHE=${CACHE_DIR}/gocache" >> ${GITHUB_ENV}
          echo "GOMODCACHE=${CACHE_DIR}/gomodcache" >> ${GITHUB_ENV}
      - uses: actions/setup-go@v4
        with:
          go-version-file: 'src/go.mod'
          cache: true
          cache-dependency-path: 'src/go.sum'
        # Go stamps binaries with version control (read: git) info,
        # and when the git repo is messed up, the build fails.
        # This also affects linting.
        # And git repo is currently messed up when running checkout within a container:
        # https://github.com/actions/checkout/issues/1169
      - name: Fix for https://github.com/actions/checkout/issues/1169
        run: |
          apt update && apt install -y git ca-certificates
          git config --system --add safe.directory $(pwd)
      - name: Lint
        uses: actions/golangci-lint@v3
        with:
          working-directory: ${{ inputs.path }}
          args: --config=${GITHUB_WORKSPACE}/src/.golangci.yml --timeout=10m

# more jobs here, but the workflow fails even with those other jobs skipped
d-honeybadger commented 6 months ago

The error is intermittent btw, though I get more failures than successes

ldez commented 6 months ago

can you try to update actions/golangci-lint@v3 to actions/golangci-lint@v5?

Note: I recommend updating:

vcabbage commented 6 months ago

In our case the error happened because we run commands inside a Docker container inside the runner (ie, executing docker run ... in the runner). Since /tmp wasn't mounted in the container the matchers JSON file wasn't visible to the runner. I realize this is unusual, though we do have our reasons. We've worked around this by mounting /tmp into the container.

It would be helpful to to be able to explicitly specify the path the file is written to so we don't have to mount all of /tmp or assume that the file will always be /tmp/golangci-lint-action-problem-matchers.json.

d-honeybadger commented 6 months ago

can you try to update actions/golangci-lint@v3 to actions/golangci-lint@v5?

Didn't help unfortunately

d-honeybadger commented 6 months ago

Here's the container setup btw

/usr/bin/docker create --name c6df9175981f4befaa7b629a8fc34ac0_debianbullseyeslim_e9979d --label 90e3d9 --workdir /__w/kpp-services/kpp-services --network github_network_361e39776d24465b946a473126b88bee  -e "HOME=/github/home" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/opt/actions-runner/_work":"/__w" -v "/opt/actions-runner/externals":"/__e":ro -v "/opt/actions-runner/_work/_temp":"/__w/_temp" -v "/opt/actions-runner/_work/_actions":"/__w/_actions" -v "/opt/hostedtoolcache":"/__t" -v "/opt/actions-runner/_work/_temp/_github_home":"/github/home" -v "/opt/actions-runner/_work/_temp/_github_workflow":"/github/workflow" --entrypoint "tail" debian:bullseye-slim "-f" "/dev/null"

I've had an issue w/ shared go cache directories inside $HOME, where unrelated actions would interfere w/ each other, but from what I can tell so far /tmp isn't shared across containers :thinking:

ldez commented 6 months ago

I don't really know how a self-hosted containerized agent works, but if it uses instances by step it's a problem.

The documentation about problem matchers is weak and it's difficult to know when the file is used by the CI.

You can try to enable the debug logging: https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md#file-property-getting-dropped


As a temporary workaround, you can disable annotations: https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#annotations.

Another possibility is to create the file /tmp/golangci-lint-action-problem-matchers.json with the following content:

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

Do you really use annotations? If yes can you explain why exactly? (It's to better understand the usage of annotations)

Same question for @vcabbage

d-honeybadger commented 6 months ago

The container is per-job, so checkout, setup-go, and linting all run in the same one. Is the problem matchers file created by golangci-lint itself?

Do you really use annotations? If yes can you explain why exactly?

Annotations in github are handy just cause it's faster than opening up job logs and finding all the linting errors by filename and line.

Thanks for the workaround suggestions! So far I just set the version to 1.57 but going to poke around more in the github runner to get to the bottom of this later, will report if I find anything. Unless you beat me with https://github.com/golangci/golangci-lint/pull/4699 :smile: in which case will be a happy user of the "old" github-actions format

ldez commented 6 months ago

Is the problem matchers file created by golangci-lint itself?

The problem is the container: the file is created inside the container but the GitHub Action system doesn't have access to this file (because it's not on the file system)

ldez commented 6 months ago

After digging more around problem matchers and the annotations system, I think that having "annotations format" (old or new) inside golangci-lint was not a good idea.

The majority of GitHub Actions uses an internal system to handle that instead of relying on the GitHub format produced by a binary.

For example, the actions/setup-go uses problem matchers: https://github.com/actions/setup-go/blob/main/matchers.json This is only inside the GHA and not inside Go :smile_cat:, and I think it's the right approach.

I'm thinking of deprecating github-actions format and parsing the output inside the official GitHub action for golangci-lint.

ldez commented 6 months ago

To share some thoughts: in fact, the format github-actions is useless because (based on tests on GitHub Actions) the CI can handle that without this specific format. The format colored-line-number is automatically parsed by GitHub, and based on that it creates the annotations.

ldez commented 6 months ago

I know why the colored-line-number is already handled by GitHub Actions: it's because the output match with problem matchers of actions/setup-go.

If I disable the problem matchers of Go (echo "::remove-matcher owner=go::") the annotations disappear.

I will:

I still think that the github-actions format is useless, problem matchers are the official solution to play with annotations, so the format will be deprecated inside golangci-lint.

In conclusion: