From e30c2fed6290add16008e677d9cc18001ef1b768 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 24 Aug 2026 19:53:17 +0000 Subject: [PATCH] chore: update deps, adapt lint, use json v2 (#1185) - Raised go to 1.27 - Adopted json v2 - Sync lint config from gitea - Fixed all issues Co-authored-by: silverwind Reviewed-on: https://gitea.com/gitea/runner/pulls/1185 Reviewed-by: bircni Co-authored-by: Renovate Bot --- .gitea/workflows/release-nightly.yml | 2 +- .gitea/workflows/release-tag.yml | 2 +- .golangci.yml | 14 +-- Dockerfile | 6 +- Makefile | 8 +- act/artifactcache/handler.go | 12 +-- act/artifactcache/handler_test.go | 32 +++---- act/artifactcache/handler_v2.go | 40 +++++++-- act/artifactcache/handler_v2_test.go | 6 +- act/artifacts/server.go | 4 +- act/artifacts/server_test.go | 2 +- act/common/executor.go | 2 +- act/common/git/git.go | 7 +- act/common/line_writer.go | 12 +-- act/container/docker_cli.go | 9 +- act/container/docker_create_flags.go | 4 +- act/container/docker_logger.go | 13 +-- act/container/docker_network_test.go | 6 +- act/container/docker_run.go | 12 +-- act/container/docker_run_test.go | 46 +++++----- act/container/host_environment.go | 3 +- act/container/parse_env_file.go | 7 +- act/runner/action.go | 2 +- act/runner/action_composite.go | 2 +- act/runner/expression.go | 2 +- act/runner/job_executor.go | 2 +- act/runner/job_hooks.go | 4 +- act/runner/logger.go | 31 ++++--- act/runner/run_context.go | 13 +-- act/runner/run_context_test.go | 11 ++- act/runner/runner.go | 2 +- act/runner/step_action_remote.go | 11 +-- act/runner/step_docker_test.go | 4 +- act/runner/step_factory.go | 4 +- act/runner/step_factory_test.go | 2 +- act/runner/step_test.go | 20 ++--- e2e/gitea_api.go | 2 +- go.mod | 61 ++++++-------- go.sum | 117 +++++++++++++------------- internal/app/cmd/daemon.go | 14 +-- internal/app/cmd/exec.go | 16 ++-- internal/app/cmd/register.go | 11 +-- internal/app/run/health_check.go | 3 +- internal/app/run/post_task_script.go | 3 +- internal/app/run/runner.go | 4 +- internal/app/run/runner_cache_test.go | 4 +- internal/pkg/config/registration.go | 13 +-- 47 files changed, 319 insertions(+), 288 deletions(-) diff --git a/.gitea/workflows/release-nightly.yml b/.gitea/workflows/release-nightly.yml index b9baf97f..c406bd37 100644 --- a/.gitea/workflows/release-nightly.yml +++ b/.gitea/workflows/release-nightly.yml @@ -77,7 +77,7 @@ jobs: uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 - name: Set up Docker BuildX - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4 - name: Login to DockerHub uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 diff --git a/.gitea/workflows/release-tag.yml b/.gitea/workflows/release-tag.yml index d60f8173..0bc7fe73 100644 --- a/.gitea/workflows/release-tag.yml +++ b/.gitea/workflows/release-tag.yml @@ -80,7 +80,7 @@ jobs: uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 - name: Set up Docker BuildX - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4 - name: Login to DockerHub uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 diff --git a/.golangci.yml b/.golangci.yml index 428426f1..29a2d61e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -46,8 +46,7 @@ linters: gocritic: enabled-checks: - equalFold - disabled-checks: - - ifElseChain + disabled-checks: [] revive: severity: error rules: @@ -71,10 +70,14 @@ linters: - name: unexported-return - name: var-declaration - name: var-naming + arguments: + - [] # AllowList - do not remove as args for the rule are positional and won't work without lists first + - [] # DenyList + - - skip-initialism-name-checks: true staticcheck: checks: - all - - -ST1005 + testifylint: {} usetesting: os-temp-dir: true perfsprint: @@ -92,8 +95,6 @@ linters: generated: lax presets: - comments - - common-false-positives - - legacy - std-error-handling rules: - linters: @@ -118,7 +119,8 @@ formatters: - blank - default gofumpt: - extra-rules: true + extra: + group-params: true exclusions: generated: lax run: diff --git a/Dockerfile b/Dockerfile index 9fcbeb87..8a927a89 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ### BUILDER STAGE # # -FROM golang:1.26-alpine3.23 AS builder +FROM golang:1.27-alpine3.23 AS builder # Do not remove `git` here, it is required for getting runner version when executing `make build` RUN apk add --no-cache make git @@ -17,7 +17,7 @@ RUN make clean && make build ### DIND VARIANT # # -FROM docker:29.7.1-dind AS dind +FROM docker:29.7.2-dind AS dind ARG VERSION=dev @@ -37,7 +37,7 @@ ENTRYPOINT ["s6-svscan","/etc/s6"] ### DIND-ROOTLESS VARIANT # # -FROM docker:29.7.1-dind-rootless AS dind-rootless +FROM docker:29.7.2-dind-rootless AS dind-rootless ARG VERSION=dev diff --git a/Makefile b/Makefile index 8caa2bca..4fac2b0a 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ GO ?= go SHASUM ?= shasum -a 256 HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) XGO_PACKAGE ?= src.techknowlogick.com/xgo@v1.9.0 # renovate: datasource=go -XGO_VERSION := go-1.26.x +XGO_VERSION := go-1.27.x GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.16 # renovate: datasource=go LINUX_ARCHS ?= linux/amd64,linux/arm64 @@ -18,8 +18,8 @@ DOCKER_TAG ?= nightly DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) DOCKER_ROOTLESS_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)-dind-rootless -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 # renovate: datasource=go -GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.6.0 # renovate: datasource=go +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.1 # renovate: datasource=go +GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.7.0 # renovate: datasource=go GOTEST_FLAGS ?= -race -timeout 20m -parallel 8 @@ -137,7 +137,7 @@ lint-pr-title: ## lint PR title against Conventional Commits (set PR_TITLE=...) .PHONY: security-check security-check: - GOEXPERIMENT= $(GO) run $(GOVULNCHECK_PACKAGE) -show color ./... || true + $(GO) run $(GOVULNCHECK_PACKAGE) -show color ./... || true .PHONY: tidy tidy: ## run go mod tidy diff --git a/act/artifactcache/handler.go b/act/artifactcache/handler.go index 3354aea1..9894d58e 100644 --- a/act/artifactcache/handler.go +++ b/act/artifactcache/handler.go @@ -11,7 +11,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/hex" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" @@ -357,8 +357,8 @@ func (h *Handler) Close() error { func (h *Handler) openDB() (*bolthold.Store, error) { return bolthold.Open(filepath.Join(h.dir, "bolt.db"), 0o644, &bolthold.Options{ - Encoder: json.Marshal, - Decoder: json.Unmarshal, + Encoder: func(value any) ([]byte, error) { return json.Marshal(value) }, + Decoder: func(data []byte, value any) error { return json.Unmarshal(data, value) }, Options: &bbolt.Options{ Timeout: 5 * time.Second, NoGrowSync: bbolt.DefaultOptions.NoGrowSync, @@ -422,7 +422,7 @@ func (h *Handler) lookupCache(db *bolthold.Store, repo string, keys []string, ve func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { cred := credFromContext(r.Context()) api := &Request{} - if err := json.NewDecoder(r.Body).Decode(api); err != nil { + if err := json.UnmarshalRead(r.Body, api); err != nil { h.responseJSON(w, r, 400, err) return } @@ -692,7 +692,7 @@ func (h *Handler) ResultsURL(cred JobCredential) string { func (h *Handler) internalRegister(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var body internalRegisterBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + if err := json.UnmarshalRead(r.Body, &body); err != nil { h.responseJSON(w, r, http.StatusBadRequest, err) return } @@ -708,7 +708,7 @@ func (h *Handler) internalRegister(w http.ResponseWriter, r *http.Request, _ htt // POST /_internal/revoke func (h *Handler) internalRevoke(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var body internalRevokeBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + if err := json.UnmarshalRead(r.Body, &body); err != nil { h.responseJSON(w, r, http.StatusBadRequest, err) return } diff --git a/act/artifactcache/handler_test.go b/act/artifactcache/handler_test.go index 9fdc5b24..20ced3f6 100644 --- a/act/artifactcache/handler_test.go +++ b/act/artifactcache/handler_test.go @@ -7,7 +7,7 @@ package artifactcache import ( "bytes" "crypto/rand" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" @@ -136,7 +136,7 @@ func TestHandler(t *testing.T) { defer resp.Body.Close() assert.Equal(t, 200, resp.StatusCode) - require.NoError(t, json.NewDecoder(resp.Body).Decode(&first)) + require.NoError(t, json.UnmarshalRead(resp.Body, &first)) assert.NotZero(t, first.CacheID) } { @@ -151,7 +151,7 @@ func TestHandler(t *testing.T) { defer resp.Body.Close() assert.Equal(t, 200, resp.StatusCode) - require.NoError(t, json.NewDecoder(resp.Body).Decode(&second)) + require.NoError(t, json.UnmarshalRead(resp.Body, &second)) assert.NotZero(t, second.CacheID) } @@ -204,7 +204,7 @@ func TestHandler(t *testing.T) { got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } { @@ -259,7 +259,7 @@ func TestHandler(t *testing.T) { got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } { @@ -315,7 +315,7 @@ func TestHandler(t *testing.T) { got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } { @@ -362,7 +362,7 @@ func TestHandler(t *testing.T) { got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } @@ -413,7 +413,7 @@ func TestHandler(t *testing.T) { got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } { @@ -493,7 +493,7 @@ func TestHandler(t *testing.T) { ArchiveLocation string `json:"archiveLocation"` CacheKey string `json:"cacheKey"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, "hit", got.Result) assert.Equal(t, keys[except], got.CacheKey) @@ -528,7 +528,7 @@ func TestHandler(t *testing.T) { ArchiveLocation string `json:"archiveLocation"` CacheKey string `json:"cacheKey"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, "hit", got.Result) assert.Equal(t, key, got.CacheKey) assert.NotEqual(t, strings.ToLower(key), got.CacheKey) @@ -577,7 +577,7 @@ func TestHandler(t *testing.T) { ArchiveLocation string `json:"archiveLocation"` CacheKey string `json:"cacheKey"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, keys[expect], got.CacheKey) contentResp, err := testClient.Get(got.ArchiveLocation) @@ -633,7 +633,7 @@ func TestHandler(t *testing.T) { ArchiveLocation string `json:"archiveLocation"` CacheKey string `json:"cacheKey"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, keys[expect], got.CacheKey) contentResp, err := testClient.Get(got.ArchiveLocation) @@ -677,7 +677,7 @@ func uploadCacheNormally(t *testing.T, base, key, version string, content []byte got := struct { CacheID uint64 `json:"cacheId"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) id = got.CacheID } { @@ -708,7 +708,7 @@ func uploadCacheNormally(t *testing.T, base, key, version string, content []byte ArchiveLocation string `json:"archiveLocation"` CacheKey string `json:"cacheKey"` }{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, "hit", got.Result) assert.Equal(t, key, got.CacheKey) archiveLocation = got.ArchiveLocation @@ -1197,7 +1197,7 @@ func TestHandler_CrossRepoIsolation(t *testing.T) { var reserved struct { CacheID uint64 `json:"cacheId"` } - require.NoError(t, json.NewDecoder(resp.Body).Decode(&reserved)) + require.NoError(t, json.UnmarshalRead(resp.Body, &reserved)) resp.Body.Close() require.NotZero(t, reserved.CacheID) @@ -1331,7 +1331,7 @@ func TestHandler_ArtifactSignatureDownload(t *testing.T) { var hit struct { ArchiveLocation string `json:"archiveLocation"` } - require.NoError(t, json.NewDecoder(resp.Body).Decode(&hit)) + require.NoError(t, json.UnmarshalRead(resp.Body, &hit)) resp.Body.Close() require.Contains(t, hit.ArchiveLocation, "sig=") diff --git a/act/artifactcache/handler_v2.go b/act/artifactcache/handler_v2.go index 26f13ea9..5f6127cd 100644 --- a/act/artifactcache/handler_v2.go +++ b/act/artifactcache/handler_v2.go @@ -5,7 +5,8 @@ package artifactcache import ( "cmp" - "encoding/json" + "encoding/json/jsontext" + "encoding/json/v2" "encoding/xml" "errors" "fmt" @@ -128,7 +129,7 @@ func (h *Handler) v2FinalizeCacheEntryUpload(w http.ResponseWriter, r *http.Requ } db.Close() // commitCache needs the store closed - cache.Size, _ = cmp.Or(req.SizeBytes, req.SizeBytesCamel).Int64() + cache.Size = int64(cmp.Or(req.SizeBytes, req.SizeBytesCamel)) if err := h.commitCache(cache); err != nil { h.logger.Errorf("finalize cache %d (%s): %v", cache.ID, cache.Key, err) h.twirpNotOK(w, r) @@ -245,10 +246,10 @@ type ( } v2FinalizeRequest struct { - Key string `json:"key"` - Version string `json:"version"` - SizeBytes json.Number `json:"size_bytes"` - SizeBytesCamel json.Number `json:"sizeBytes"` + Key string `json:"key"` + Version string `json:"version"` + SizeBytes twirpInt64 `json:"size_bytes"` + SizeBytesCamel twirpInt64 `json:"sizeBytes"` } v2DownloadRequest struct { @@ -259,6 +260,31 @@ type ( } ) +// twirpInt64 accepts its value as the JSON string the mapping prescribes or as a bare number. +type twirpInt64 int64 + +func (n *twirpInt64) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + val, err := dec.ReadValue() + if err != nil { + return err + } + digits := []byte(val) + switch val.Kind() { + case 'n': // absent, keep the zero value + return nil + case '"': + if digits, err = jsontext.AppendUnquote(nil, val); err != nil { + return err + } + } + parsed, err := strconv.ParseInt(string(digits), 10, 64) + if err != nil { + return err + } + *n = twirpInt64(parsed) + return nil +} + func (d v2DownloadRequest) keys() []string { restoreKeys := d.RestoreKeys if len(restoreKeys) == 0 { @@ -269,6 +295,6 @@ func (d v2DownloadRequest) keys() []string { func decodeTwirpRequest[T any](r *http.Request) (T, error) { var req T - err := json.NewDecoder(io.LimitReader(r.Body, 1<<20)).Decode(&req) + err := json.UnmarshalRead(io.LimitReader(r.Body, 1<<20), &req) return req, err } diff --git a/act/artifactcache/handler_v2_test.go b/act/artifactcache/handler_v2_test.go index eab1fd09..dab5cda7 100644 --- a/act/artifactcache/handler_v2_test.go +++ b/act/artifactcache/handler_v2_test.go @@ -6,7 +6,7 @@ package artifactcache import ( "bytes" "encoding/base64" - "encoding/json" + "encoding/json/v2" "fmt" "io" "net/http" @@ -32,7 +32,7 @@ func v2Call(t *testing.T, handler *Handler, client *http.Client, method string, require.Equal(t, http.StatusOK, resp.StatusCode) got := map[string]any{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) return got } @@ -227,7 +227,7 @@ func TestCacheServiceV2Lookups(t *testing.T) { require.Equal(t, http.StatusOK, resp.StatusCode) got := map[string]any{} - require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) + require.NoError(t, json.UnmarshalRead(resp.Body, &got)) assert.Equal(t, "deps-abc", got["cacheKey"]) assert.NotEmpty(t, got["archiveLocation"]) }) diff --git a/act/artifacts/server.go b/act/artifacts/server.go index e6d27efd..df2cf1de 100644 --- a/act/artifacts/server.go +++ b/act/artifacts/server.go @@ -6,7 +6,7 @@ package artifacts import ( "context" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" @@ -100,7 +100,7 @@ func uploads(router *httprouter.Router, baseDir string) { } defer file.Close() if req.Body == nil { - panic(errors.New("No body given")) + panic(errors.New("no body given")) } _, err = io.Copy(file, req.Body) diff --git a/act/artifacts/server_test.go b/act/artifacts/server_test.go index 6db43d4a..ccb6c15e 100644 --- a/act/artifacts/server_test.go +++ b/act/artifacts/server_test.go @@ -7,7 +7,7 @@ package artifacts import ( "bytes" "compress/gzip" - "encoding/json" + "encoding/json/v2" "io" "maps" "net/http" diff --git a/act/common/executor.go b/act/common/executor.go index 1e33c79b..05799039 100644 --- a/act/common/executor.go +++ b/act/common/executor.go @@ -171,7 +171,7 @@ func (e Executor) Finally(finally Executor) Executor { err := e(ctx) err2 := finally(ctx) if err2 != nil { - return fmt.Errorf("Error occurred running finally: %v (original error: %v)", err2, err) + return fmt.Errorf("error occurred running finally: %v (original error: %v)", err2, err) } return err } diff --git a/act/common/git/git.go b/act/common/git/git.go index 974bf58f..69769f9a 100644 --- a/act/common/git/git.go +++ b/act/common/git/git.go @@ -274,11 +274,12 @@ func CloneIfRequired(ctx context.Context, refName plumbing.ReferenceName, input return r, true, nil } - if err != nil { + switch { + case err != nil: logger.Debugf("Removing cached clone at %s because origin cannot be read: %v", input.Dir, err) - } else if len(remote.Config().URLs) == 0 { + case len(remote.Config().URLs) == 0: logger.Debugf("Removing cached clone at %s because origin has no URL", input.Dir) - } else { + default: logger.Debugf("Removing cached clone at %s because origin URL changed from %s to %s", input.Dir, remote.Config().URLs[0], input.URL) } if err := os.RemoveAll(input.Dir); err != nil { diff --git a/act/common/line_writer.go b/act/common/line_writer.go index 7bdd3f1f..71a6b9d6 100644 --- a/act/common/line_writer.go +++ b/act/common/line_writer.go @@ -46,14 +46,14 @@ func (lw *lineWriter) Write(p []byte) (n int, err error) { line, err := pBuf.ReadString('\n') w, _ := lw.buffer.WriteString(line) written += w - if err == nil { - lw.handleLine(lw.buffer.String()) - lw.buffer.Reset() - } else if err == io.EOF { - break - } else { + if err != nil { + if err == io.EOF { + break + } return written, err } + lw.handleLine(lw.buffer.String()) + lw.buffer.Reset() } return written, nil diff --git a/act/container/docker_cli.go b/act/container/docker_cli.go index d1066737..26e0b11e 100644 --- a/act/container/docker_cli.go +++ b/act/container/docker_cli.go @@ -17,8 +17,7 @@ package container import ( - "bytes" - "encoding/json" + "encoding/json/jsontext" "errors" "fmt" "net" @@ -959,11 +958,11 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) { if err != nil { return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %w", v, err) } - var b bytes.Buffer - if err := json.Compact(&b, f); err != nil { + profile := jsontext.Value(f) + if err := profile.Compact(); err != nil { return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", v, err) } - securityOpts[key] = "seccomp=" + b.String() + securityOpts[key] = "seccomp=" + string(profile) } } } diff --git a/act/container/docker_create_flags.go b/act/container/docker_create_flags.go index 07fcefab..82796cc2 100644 --- a/act/container/docker_create_flags.go +++ b/act/container/docker_create_flags.go @@ -55,11 +55,11 @@ func parseContainerOptions(options string) (*pflag.FlagSet, *containerOptions, * args, err := shellquote.Split(options) if err != nil { - return flags, copts, cf, fmt.Errorf("Cannot split container options: '%s': '%w'", options, err) + return flags, copts, cf, fmt.Errorf("cannot split container options: '%s': '%w'", options, err) } if err := flags.Parse(args); err != nil { - return flags, copts, cf, fmt.Errorf("Cannot parse container options: '%s': '%w'", options, err) + return flags, copts, cf, fmt.Errorf("cannot parse container options: '%s': '%w'", options, err) } return flags, copts, cf, nil diff --git a/act/container/docker_logger.go b/act/container/docker_logger.go index 96d59432..c76c9d49 100644 --- a/act/container/docker_logger.go +++ b/act/container/docker_logger.go @@ -8,7 +8,7 @@ package container import ( "bufio" - "encoding/json" + "encoding/json/v2" "errors" "io" @@ -20,8 +20,8 @@ type dockerMessage struct { Stream string `json:"stream"` Error string `json:"error"` ErrorDetail struct { - Message string - } + Message string `json:"message"` + } `json:"errorDetail"` Status string `json:"status"` Progress string `json:"progress"` } @@ -60,15 +60,16 @@ func logDockerResponse(logger logrus.FieldLogger, dockerResponse io.ReadCloser, return errors.New(msg.ErrorDetail.Message) } - if msg.Status != "" { + switch { + case msg.Status != "": if msg.Progress != "" { writeLog(logger, isError, "%s :: %s :: %s\n", msg.Status, msg.ID, msg.Progress) } else { writeLog(logger, isError, "%s :: %s\n", msg.Status, msg.ID) } - } else if msg.Stream != "" { + case msg.Stream != "": writeLog(logger, isError, "%s", msg.Stream) - } else { + default: writeLog(logger, false, "Unable to handle line: %s", string(line)) } } diff --git a/act/container/docker_network_test.go b/act/container/docker_network_test.go index 5a92dd8c..cf2d72f1 100644 --- a/act/container/docker_network_test.go +++ b/act/container/docker_network_test.go @@ -32,9 +32,9 @@ func TestRemoveOrphanNetworks(t *testing.T) { client.On("NetworkList", ctx, mobyclient.NetworkListOptions{ Filters: make(mobyclient.Filters).Add("label", runnerUUIDLabel+"=runner-1"), }).Return(mobyclient.NetworkListResult{Items: []network.Summary{ - {Network: network.Network{ID: "orphan"}}, - {Network: network.Network{ID: "busy"}}, - {Network: network.Network{ID: "starting"}}, + {ID: "orphan"}, + {ID: "busy"}, + {ID: "starting"}, }}, nil) client.On("NetworkInspect", ctx, "orphan", mobyclient.NetworkInspectOptions{}). Return(mobyclient.NetworkInspectResult{}, nil) diff --git a/act/container/docker_run.go b/act/container/docker_run.go index 8110cc61..c7dfca5f 100644 --- a/act/container/docker_run.go +++ b/act/container/docker_run.go @@ -539,14 +539,14 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config } if err := cf.validate(); err != nil { - return nil, nil, fmt.Errorf("Cannot process container options: '%s': '%w'", input.Options, err) + return nil, nil, fmt.Errorf("cannot process container options: '%s': '%w'", input.Options, err) } // FIXME: If everything is fine after gitea/act v0.260.0, remove the following comment. // In the old fork version, the code is // if len(copts.netMode.Value()) == 0 { // if err = copts.netMode.Set("host"); err != nil { - // return nil, nil, fmt.Errorf("Cannot parse networkmode=host. This is an internal error and should not happen: '%w'", err) + // return nil, nil, fmt.Errorf("cannot parse networkmode=host. This is an internal error and should not happen: '%w'", err) // } // } // And it has been commented with: @@ -558,7 +558,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config if len(copts.netMode.Value()) == 0 { if err = copts.netMode.Set(cr.input.NetworkMode); err != nil { - return nil, nil, fmt.Errorf("Cannot parse networkmode=%s. This is an internal error and should not happen: '%w'", cr.input.NetworkMode, err) + return nil, nil, fmt.Errorf("cannot parse networkmode=%s. This is an internal error and should not happen: '%w'", cr.input.NetworkMode, err) } } @@ -570,7 +570,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config containerConfig, err := parse(flags, copts, runtime.GOOS) if err != nil { - return nil, nil, fmt.Errorf("Cannot process container options: '%s': '%w'", input.Options, err) + return nil, nil, fmt.Errorf("cannot process container options: '%s': '%w'", input.Options, err) } // For Gitea @@ -587,7 +587,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config err = mergo.Merge(config, containerConfig.Config, mergo.WithOverride, mergo.WithAppendSlice) if err != nil { - return nil, nil, fmt.Errorf("Cannot merge container.Config options: '%s': '%w'", input.Options, err) + return nil, nil, fmt.Errorf("cannot merge container.Config options: '%s': '%w'", input.Options, err) } logger.Debugf("Merged container.Config ==> %+v", config) @@ -599,7 +599,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config networkMode := hostConfig.NetworkMode err = mergo.Merge(hostConfig, containerConfig.HostConfig, mergo.WithOverride) if err != nil { - return nil, nil, fmt.Errorf("Cannot merge container.HostConfig options: '%s': '%w'", input.Options, err) + return nil, nil, fmt.Errorf("cannot merge container.HostConfig options: '%s': '%w'", input.Options, err) } hostConfig.Binds = binds hostConfig.Mounts = mounts diff --git a/act/container/docker_run_test.go b/act/container/docker_run_test.go index 9917918a..641d9be6 100644 --- a/act/container/docker_run_test.go +++ b/act/container/docker_run_test.go @@ -186,10 +186,8 @@ func TestDockerExecAbort(t *testing.T) { client := &mockDockerClient{} client.On("ExecCreate", ctx, "123", mock.AnythingOfType("client.ExecCreateOptions")).Return(mobyclient.ExecCreateResult{ID: "id"}, nil) client.On("ExecAttach", ctx, "id", mock.AnythingOfType("client.ExecAttachOptions")).Return(mobyclient.ExecAttachResult{ - HijackedResponse: mobyclient.HijackedResponse{ - Conn: conn, - Reader: bufio.NewReader(reader), - }, + Conn: conn, + Reader: bufio.NewReader(reader), }, nil) cr := &containerReference{ @@ -225,10 +223,8 @@ func TestDockerExecFailure(t *testing.T) { client := &mockDockerClient{} client.On("ExecCreate", ctx, "123", mock.AnythingOfType("client.ExecCreateOptions")).Return(mobyclient.ExecCreateResult{ID: "id"}, nil) client.On("ExecAttach", ctx, "id", mock.AnythingOfType("client.ExecAttachOptions")).Return(mobyclient.ExecAttachResult{ - HijackedResponse: mobyclient.HijackedResponse{ - Conn: conn, - Reader: bufio.NewReader(strings.NewReader("output")), - }, + Conn: conn, + Reader: bufio.NewReader(strings.NewReader("output")), }, nil) client.On("ExecInspect", ctx, "id", mobyclient.ExecInspectOptions{}).Return(mobyclient.ExecInspectResult{ ExitCode: 1, @@ -280,10 +276,8 @@ func TestDockerAttachFlushesTrailingLine(t *testing.T) { client := &mockDockerClient{} client.On("ContainerAttach", ctx, "123", mock.AnythingOfType("client.ContainerAttachOptions")). Return(mobyclient.ContainerAttachResult{ - HijackedResponse: mobyclient.HijackedResponse{ - Conn: &mockConn{}, - Reader: bufio.NewReader(framed), - }, + Conn: &mockConn{}, + Reader: bufio.NewReader(framed), }, nil) statusCh := make(chan container.WaitResponse, 1) @@ -594,21 +588,19 @@ func TestSanitizeOptionsHostConfig(t *testing.T) { dangerous := func() *container.HostConfig { return &container.HostConfig{ - PidMode: "host", - IpcMode: "host", - UTSMode: "host", - CgroupnsMode: "host", - UsernsMode: "host", - CapAdd: []string{"ALL"}, - SecurityOpt: []string{"seccomp=unconfined", "apparmor=unconfined"}, - VolumesFrom: []string{"other"}, - Runtime: "runc", - Resources: container.Resources{ - CgroupParent: "/custom", - Devices: []container.DeviceMapping{{PathOnHost: "/dev/sda", PathInContainer: "/dev/sda", CgroupPermissions: "rwm"}}, - DeviceCgroupRules: []string{"a *:* rwm"}, - }, - Sysctls: map[string]string{"net.ipv4.ip_forward": "1"}, + PidMode: "host", + IpcMode: "host", + UTSMode: "host", + CgroupnsMode: "host", + UsernsMode: "host", + CapAdd: []string{"ALL"}, + SecurityOpt: []string{"seccomp=unconfined", "apparmor=unconfined"}, + VolumesFrom: []string{"other"}, + Runtime: "runc", + CgroupParent: "/custom", + Devices: []container.DeviceMapping{{PathOnHost: "/dev/sda", PathInContainer: "/dev/sda", CgroupPermissions: "rwm"}}, + DeviceCgroupRules: []string{"a *:* rwm"}, + Sysctls: map[string]string{"net.ipv4.ip_forward": "1"}, } } diff --git a/act/container/host_environment.go b/act/container/host_environment.go index dd99064b..20b02ddf 100644 --- a/act/container/host_environment.go +++ b/act/container/host_environment.go @@ -351,8 +351,7 @@ func (e *HostEnvironment) exec(ctx context.Context, command []string, cmdline st } err = cmd.Wait() if err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { return ExitCodeError(exitErr.ExitCode()) } return err diff --git a/act/container/parse_env_file.go b/act/container/parse_env_file.go index ec8f1545..593ddb1c 100644 --- a/act/container/parse_env_file.go +++ b/act/container/parse_env_file.go @@ -46,9 +46,10 @@ func parseEnvFile(e Container, srcPath string, env *map[string]string) common.Ex } singleLineEnv := strings.Index(line, "=") multiLineEnv := strings.Index(line, "<<") - if singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv) { + switch { + case singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv): localEnv[line[:singleLineEnv]] = line[singleLineEnv+1:] - } else if multiLineEnv != -1 { + case multiLineEnv != -1: multiLineEnvContent := "" multiLineEnvDelimiter := line[multiLineEnv+2:] delimiterFound := false @@ -70,7 +71,7 @@ func parseEnvFile(e Container, srcPath string, env *map[string]string) common.Ex return fmt.Errorf("invalid format delimiter '%v' not found before end of file", multiLineEnvDelimiter) } localEnv[line[:multiLineEnv]] = multiLineEnvContent - } else { + default: return fmt.Errorf("invalid format '%v', expected a line with '=' or '<<'", line) } } diff --git a/act/runner/action.go b/act/runner/action.go index a44c7cd5..9ea82cd1 100644 --- a/act/runner/action.go +++ b/act/runner/action.go @@ -219,7 +219,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction rc.JobContainer.Exec(execArgs, *step.getEnv(), "", ""), )(ctx) default: - return fmt.Errorf("The runs.using key must be one of: %v, got %s", []string{ + return fmt.Errorf("the runs.using key must be one of: %v, got %s", []string{ model.ActionRunsUsingDocker, model.ActionRunsUsingNode12, model.ActionRunsUsingNode16, diff --git a/act/runner/action_composite.go b/act/runner/action_composite.go index 2be93c71..74cb7e5c 100644 --- a/act/runner/action_composite.go +++ b/act/runner/action_composite.go @@ -55,7 +55,7 @@ func newCompositeRunContext(ctx context.Context, parent *RunContext, step action env := evaluateCompositeInputAndEnv(ctx, parent, step) // run with the global config but without secrets - configCopy := *(parent.Config) + configCopy := *parent.Config configCopy.Secrets = nil // create a run context for the composite action to run in diff --git a/act/runner/expression.go b/act/runner/expression.go index b791cce0..197af546 100644 --- a/act/runner/expression.go +++ b/act/runner/expression.go @@ -170,7 +170,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect. followSymlink = true continue } - return "", fmt.Errorf("Invalid glob option %s, available option: '--follow-symbolic-links'", s) + return "", fmt.Errorf("invalid glob option %s, available option: '--follow-symbolic-links'", s) } } patterns = append(patterns, s) diff --git a/act/runner/job_executor.go b/act/runner/job_executor.go index 222b50f9..66ac5d70 100644 --- a/act/runner/job_executor.go +++ b/act/runner/job_executor.go @@ -9,7 +9,7 @@ import ( "bytes" "context" "encoding/base64" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" diff --git a/act/runner/job_hooks.go b/act/runner/job_hooks.go index e39ee739..ace98324 100644 --- a/act/runner/job_hooks.go +++ b/act/runner/job_hooks.go @@ -64,7 +64,9 @@ func (rc *RunContext) runJobHook(ctx context.Context, hookPath, name string) err } // Processed even on failure, so a hook that exports what it managed to set up before // failing still hands it to the job. - err = cmp.Or(err, rc.processHookFileCommands(ctx)) + if processErr := rc.processHookFileCommands(ctx); err == nil { + err = processErr + } if err == nil { return nil } diff --git a/act/runner/logger.go b/act/runner/logger.go index 80affca0..0c633f07 100644 --- a/act/runner/logger.go +++ b/act/runner/logger.go @@ -8,7 +8,8 @@ import ( "bytes" "context" "encoding/base64" - "encoding/json" + "encoding/json/jsontext" + "encoding/json/v2" "fmt" "io" "net/url" @@ -78,7 +79,7 @@ type JobLoggerFactory interface { type jobLoggerFactoryContextKey string -var jobLoggerFactoryContextKeyVal = (jobLoggerFactoryContextKey)("jobloggerkey") +var jobLoggerFactoryContextKeyVal = jobLoggerFactoryContextKey("jobloggerkey") func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context.Context { return context.WithValue(ctx, jobLoggerFactoryContextKeyVal, factory) @@ -215,7 +216,7 @@ func base64ShiftEncoder(shift int) func(string) string { // escapes <, >, & (as act's own toJSON does); the non-HTML variant below covers the runtimes // that do not. When v has none of those characters both forms are equal and deduplicated. func jsonStringEscape(v string) string { - encoded, err := json.Marshal(v) + encoded, err := json.Marshal(v, jsontext.EscapeForHTML(true)) if err != nil { return v } @@ -226,15 +227,11 @@ func jsonStringEscape(v string) string { // JavaScript (JSON.stringify) or .NET action emits, so a secret containing < > or & is // masked in that form too. func jsonStringEscapeNoHTML(v string) string { - var buf bytes.Buffer - enc := json.NewEncoder(&buf) - enc.SetEscapeHTML(false) - if err := enc.Encode(v); err != nil { + encoded, err := json.Marshal(v) + if err != nil { return v } - // Encode appends a newline; drop it along with the surrounding quotes. - encoded := strings.TrimRight(buf.String(), "\n") - return encoded[1 : len(encoded)-1] + return string(encoded[1 : len(encoded)-1]) } func AppendSecretMasker(oldnew []string, v string) []string { @@ -366,15 +363,16 @@ func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) { debugFlag = "[DEBUG] " } - if entry.Data[rawOutputField] == true { + switch { + case entry.Data[rawOutputField] == true: if entry.Data[scriptLineCyanField] == true { fmt.Fprintf(b, "\x1b[%dm|\x1b[0m \x1b[36;1m%s\x1b[0m", f.color, entry.Message) } else { fmt.Fprintf(b, "\x1b[%dm|\x1b[0m %s", f.color, entry.Message) } - } else if entry.Data["dryrun"] == true { + case entry.Data["dryrun"] == true: fmt.Fprintf(b, "\x1b[1m\x1b[%dm\x1b[7m*DRYRUN*\x1b[0m \x1b[%dm[%s] \x1b[0m%s%s", gray, f.color, job, debugFlag, entry.Message) - } else { + default: fmt.Fprintf(b, "\x1b[%dm[%s] \x1b[0m%s%s", f.color, job, debugFlag, entry.Message) } } @@ -389,11 +387,12 @@ func (f *jobLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) { debugFlag = "[DEBUG] " } - if entry.Data[rawOutputField] == true { + switch { + case entry.Data[rawOutputField] == true: fmt.Fprintf(b, "[%s] | %s", job, entry.Message) - } else if entry.Data["dryrun"] == true { + case entry.Data["dryrun"] == true: fmt.Fprintf(b, "*DRYRUN* [%s] %s%s", job, debugFlag, entry.Message) - } else { + default: fmt.Fprintf(b, "[%s] %s%s", job, debugFlag, entry.Message) } } diff --git a/act/runner/run_context.go b/act/runner/run_context.go index 7510c321..d4ed7bbc 100644 --- a/act/runner/run_context.go +++ b/act/runner/run_context.go @@ -11,7 +11,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/hex" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" @@ -198,14 +198,15 @@ func (rc *RunContext) networkNameForGitea() (string, bool) { func getDockerDaemonSocketMountPath(daemonPath string) string { if before, after, ok := strings.Cut(daemonPath, "://"); ok { scheme := before - if strings.EqualFold(scheme, "npipe") { + switch { + case strings.EqualFold(scheme, "npipe"): // linux container mount on windows, use the default socket path of the VM / wsl2 return "/var/run/docker.sock" - } else if strings.EqualFold(scheme, "unix") { + case strings.EqualFold(scheme, "unix"): return after - } else if strings.IndexFunc(scheme, func(r rune) bool { + case strings.IndexFunc(scheme, func(r rune) bool { return (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') - }) == -1 { + }) == -1: // unknown protocol use default return "/var/run/docker.sock" } @@ -550,7 +551,7 @@ func (rc *RunContext) startJobContainer() common.Executor { AllocatePTY: rc.Config.AllocatePTY, }) if rc.JobContainer == nil { - return errors.New("Failed to create job container") + return errors.New("failed to create job container") } rc.jobNetworkName = networkName diff --git a/act/runner/run_context_test.go b/act/runner/run_context_test.go index dbbef269..ea32423c 100644 --- a/act/runner/run_context_test.go +++ b/act/runner/run_context_test.go @@ -214,11 +214,14 @@ type fakeContainer struct { container.ExecutionsEnvironment } -func (fakeContainer) Pull(bool) common.Executor { return func(context.Context) error { return nil } } +func (fakeContainer) Pull(bool) common.Executor { return func(context.Context) error { return nil } } + func (fakeContainer) Start(bool) common.Executor { return func(context.Context) error { return nil } } -func (fakeContainer) Remove() common.Executor { return func(context.Context) error { return nil } } -func (fakeContainer) Close() common.Executor { return func(context.Context) error { return nil } } -func (fakeContainer) GetActPath() string { return "/var/run/act" } + +func (fakeContainer) Remove() common.Executor { return func(context.Context) error { return nil } } + +func (fakeContainer) Close() common.Executor { return func(context.Context) error { return nil } } +func (fakeContainer) GetActPath() string { return "/var/run/act" } func (fakeContainer) Create([]string, []string) common.Executor { return func(context.Context) error { return nil } } diff --git a/act/runner/runner.go b/act/runner/runner.go index e61f93d8..08cf1e72 100644 --- a/act/runner/runner.go +++ b/act/runner/runner.go @@ -306,7 +306,7 @@ func handleFailure(plan *model.Plan) common.Executor { for _, stage := range plan.Stages { for _, run := range stage.Runs { if run.Job().Result == "failure" && !run.Job().ContinueOnError { - return fmt.Errorf("Job '%s' failed", run.String()) + return fmt.Errorf("job '%s' failed", run.String()) } } } diff --git a/act/runner/step_action_remote.go b/act/runner/step_action_remote.go index 3861d1c9..4ac30bd2 100644 --- a/act/runner/step_action_remote.go +++ b/act/runner/step_action_remote.go @@ -60,7 +60,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor { sar.remoteAction = newRemoteAction(sar.Step.Uses) } if sar.remoteAction == nil { - return fmt.Errorf("Expected format {org}/{repo}[/path]@ref or %s{path}. Actual '%s' Input string was not in a correct format", selfRepoPrefix, sar.Step.Uses) + return fmt.Errorf("expected format {org}/{repo}[/path]@ref or %s{path}. Actual '%s' Input string was not in a correct format", selfRepoPrefix, sar.Step.Uses) } if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { @@ -94,12 +94,13 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor { var ntErr common.Executor if err := gitClone(ctx); err != nil { var refErr *git.Error - if errors.As(err, &refErr) && errors.Is(err, git.ErrShortRef) { - return fmt.Errorf("Unable to resolve action `%s`, the provided ref `%s` is the shortened version of a commit SHA, which is not supported. Please use the full commit SHA `%s` instead", + switch { + case errors.As(err, &refErr) && errors.Is(err, git.ErrShortRef): + return fmt.Errorf("unable to resolve action `%s`, the provided ref `%s` is the shortened version of a commit SHA, which is not supported. Please use the full commit SHA `%s` instead", sar.Step.Uses, sar.remoteAction.Ref, refErr.Commit()) - } else if errors.Is(err, gogit.ErrForceNeeded) { // TODO: figure out if it will be easy to shadow/alias go-git err's + case errors.Is(err, gogit.ErrForceNeeded): // TODO: figure out if it will be easy to shadow/alias go-git err's ntErr = common.NewInfoExecutor("Non-terminating error while running 'git clone': %v", err) - } else { + default: return err } } diff --git a/act/runner/step_docker_test.go b/act/runner/step_docker_test.go index 18c31e1c..ff159f7e 100644 --- a/act/runner/step_docker_test.go +++ b/act/runner/step_docker_test.go @@ -29,9 +29,9 @@ func TestStepDockerMain(t *testing.T) { input = containerInput return cm } - defer (func() { + defer func() { ContainerNewContainer = origContainerNewContainer - })() + }() ctx := context.Background() diff --git a/act/runner/step_factory.go b/act/runner/step_factory.go index 953a9025..5aede212 100644 --- a/act/runner/step_factory.go +++ b/act/runner/step_factory.go @@ -19,7 +19,7 @@ type stepFactoryImpl struct{} func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step, error) { switch stepModel.Type() { case model.StepTypeInvalid: - return nil, fmt.Errorf("Invalid run/uses syntax for job:%s step:%+v", rc.Run, stepModel) + return nil, fmt.Errorf("invalid run/uses syntax for job:%s step:%+v", rc.Run, stepModel) case model.StepTypeRun: return &stepRun{ Step: stepModel, @@ -46,5 +46,5 @@ func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step, }, nil } - return nil, fmt.Errorf("Unable to determine how to run job:%s step:%+v", rc.Run, stepModel) + return nil, fmt.Errorf("unable to determine how to run job:%s step:%+v", rc.Run, stepModel) } diff --git a/act/runner/step_factory_test.go b/act/runner/step_factory_test.go index a124a77b..55cea0d8 100644 --- a/act/runner/step_factory_test.go +++ b/act/runner/step_factory_test.go @@ -65,7 +65,7 @@ func TestStepFactoryNewStep(t *testing.T) { step, err := sf.newStep(tt.model, &RunContext{}) - assert.True(t, tt.check((step))) + assert.True(t, tt.check(step)) assert.NoError(t, err) }) } diff --git a/act/runner/step_test.go b/act/runner/step_test.go index e7536453..8076ae1e 100644 --- a/act/runner/step_test.go +++ b/act/runner/step_test.go @@ -160,17 +160,17 @@ func TestSetupEnv(t *testing.T) { setupEnv(context.Background(), sm) // These are commit or system specific - delete((env), "GITHUB_REF") - delete((env), "GITHUB_REF_NAME") - delete((env), "GITHUB_REF_TYPE") - delete((env), "GITHUB_SHA") - delete((env), "GITHUB_WORKSPACE") - delete((env), "GITHUB_REPOSITORY") - delete((env), "GITHUB_REPOSITORY_OWNER") - delete((env), "GITHUB_ACTOR") + delete(env, "GITHUB_REF") + delete(env, "GITHUB_REF_NAME") + delete(env, "GITHUB_REF_TYPE") + delete(env, "GITHUB_SHA") + delete(env, "GITHUB_WORKSPACE") + delete(env, "GITHUB_REPOSITORY") + delete(env, "GITHUB_REPOSITORY_OWNER") + delete(env, "GITHUB_ACTOR") // Host-dependent, asserted in TestRunContextWithGithubEnvRunnerValues instead. - delete((env), "RUNNER_NAME") - delete((env), "RUNNER_WORKSPACE") + delete(env, "RUNNER_NAME") + delete(env, "RUNNER_WORKSPACE") assert.Equal(t, map[string]string{ "ACT": "true", diff --git a/e2e/gitea_api.go b/e2e/gitea_api.go index 1f28ecde..4987cec6 100644 --- a/e2e/gitea_api.go +++ b/e2e/gitea_api.go @@ -9,7 +9,7 @@ import ( "bytes" "context" "encoding/base64" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "io" diff --git a/go.mod b/go.mod index 7638c084..03aa4d6e 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module gitea.com/gitea/runner -go 1.26.0 +go 1.27 -toolchain go1.26.6 +toolchain go1.27.0 require ( connectrpc.com/connect v1.20.0 @@ -12,7 +12,7 @@ require ( github.com/containerd/errdefs v1.0.0 github.com/creack/pty v1.1.24 github.com/distribution/reference v0.6.0 - github.com/docker/cli v29.7.1+incompatible + github.com/docker/cli v29.7.2+incompatible github.com/docker/go-connections v0.8.1 github.com/docker/go-units v0.5.0 github.com/go-git/go-billy/v5 v5.9.1 @@ -23,7 +23,7 @@ require ( github.com/julienschmidt/httprouter v1.3.0 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mattn/go-isatty v0.0.24 - github.com/moby/go-archive v0.3.2 + github.com/moby/go-archive v0.3.3 github.com/moby/moby/api v1.55.0 github.com/moby/moby/client v0.5.1 github.com/moby/patternmatcher v0.6.1 @@ -31,42 +31,41 @@ require ( github.com/opencontainers/selinux v1.15.1 github.com/prometheus/client_golang v1.24.1 github.com/prometheus/client_model v0.6.2 - github.com/sirupsen/logrus v1.9.4 + github.com/sirupsen/logrus v1.10.1 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 - github.com/stretchr/testify v1.11.1 + github.com/stretchr/testify v1.12.1 github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928 go.etcd.io/bbolt v1.5.0 go.yaml.in/yaml/v4 v4.0.0-rc.3 - golang.org/x/net v0.57.0 + golang.org/x/net v0.58.0 golang.org/x/sync v0.22.0 golang.org/x/sys v0.47.0 golang.org/x/term v0.45.0 - golang.org/x/text v0.40.0 - google.golang.org/protobuf v1.36.11 + golang.org/x/text v0.41.0 + google.golang.org/protobuf v1.36.12 gotest.tools/v3 v3.5.2 tags.cncf.io/container-device-interface v1.1.0 ) require ( - cyphar.com/go-pathrs v0.2.3 // indirect + cyphar.com/go-pathrs v0.2.5 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.3.0 // indirect + github.com/ProtonMail/go-crypto v1.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect - github.com/cloudflare/circl v1.6.3 // indirect + github.com/cloudflare/circl v1.6.5 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/cyphar/filepath-securejoin v0.6.1 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/docker-credential-helpers v0.9.6 // indirect + github.com/cyphar/filepath-securejoin v0.7.0 // indirect + github.com/docker/docker-credential-helpers v0.9.8 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/color v1.19.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect @@ -74,19 +73,18 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.6.0 // indirect - github.com/klauspost/compress v1.19.1 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-runewidth v0.0.21 // indirect - github.com/mattn/go-shellwords v1.0.12 // indirect + github.com/klauspost/compress v1.19.2 // indirect + github.com/klauspost/cpuid/v2 v2.4.0 // indirect + github.com/mattn/go-colorable v0.1.15 // indirect + github.com/mattn/go-runewidth v0.0.28 // indirect + github.com/mattn/go-shellwords v1.0.14 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/sequential v0.7.0 // indirect github.com/moby/sys/user v0.4.1 // indirect - github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/sys/userns v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pjbgf/sha1cd v0.6.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/common v0.70.1 // indirect github.com/prometheus/procfs v0.21.1 // indirect github.com/rhysd/actionlint v1.7.12 // indirect @@ -99,14 +97,11 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.43.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.54.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/crypto v0.55.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 88c79d5f..21200c37 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= -cyphar.com/go-pathrs v0.2.3 h1:0pH8gep37wB0BgaXrEaN1OtZhUMeS7VvaejSr6i822o= -cyphar.com/go-pathrs v0.2.3/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= +cyphar.com/go-pathrs v0.2.5 h1:SnX9FBvnoyn3lUs1dkMgZ52bAETpirNu3FTRh5HlRik= +cyphar.com/go-pathrs v0.2.5/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= gitea.dev/actionslib v0.7.0 h1:JCV8eeIGwjlXcuSr7ojEdQC22VoE2466+K+D9vuQWKQ= @@ -11,8 +11,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= -github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM= +github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -27,8 +27,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= -github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= -github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= +github.com/cloudflare/circl v1.6.5 h1:O64F26HEqNhznd/hrC5KZXVKYuKM2rx4deZDTc4ihQA= +github.com/cloudflare/circl v1.6.5/go.mod h1:h5LNyxAc5nTue9DS5jT+48en2PSDYt3zdGnz5OstK6c= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= @@ -38,17 +38,16 @@ github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= -github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= +github.com/cyphar/filepath-securejoin v0.7.0 h1:s0Y3ITPy6sQn5xt54DuYvTF8hu134ooYLUb58DX/HjE= +github.com/cyphar/filepath-securejoin v0.7.0/go.mod h1:ymLGms/u3BYaviIiuKFnUx8EkQEZeK6cInNoAPJA3o4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v29.7.1+incompatible h1:ILZpP6B7fedIr6ANy824QkDp1WMJuouIq0O2SrBkB2w= -github.com/docker/cli v29.7.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker-credential-helpers v0.9.6 h1:cT2PbRPSlnMmNTfT2TDMXRyQ1KMWHG7xoTLBcn1ZNv0= -github.com/docker/docker-credential-helpers v0.9.6/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= +github.com/docker/cli v29.7.2+incompatible h1:dlkwallR8XqfeVnA2ELEhdwvb4lsSwuB4IgsG8Q9cLY= +github.com/docker/cli v29.7.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker-credential-helpers v0.9.8 h1:bIREROb7So6PRlq6KTtdS9MPEjC29OQRkFNlvK2OX8Q= +github.com/docker/docker-credential-helpers v0.9.8/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= github.com/docker/go-connections v0.8.1 h1:JibmG5hULs5qXSr/cp/w3Pw5fZuStt4MOHMUExb29/M= github.com/docker/go-connections v0.8.1/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -59,8 +58,8 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= +github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -72,8 +71,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod github.com/go-git/go-git/v5 v5.19.2 h1:wkfn7vOlUBu8ivAWKBWisTiwJK4jYHzTF8Ndv1LyGqY= github.com/go-git/go-git/v5 v5.19.2/go.mod h1:QqCBE1EFN5ddFmrliLQ3/ntRCUjZU3EJuwuB/jWEHjk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= @@ -100,10 +99,10 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY= github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= -github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= -github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= +github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -113,30 +112,34 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= +github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= -github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= -github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-runewidth v0.0.28 h1:rPyg2ybwEKPebvpzVWe1gKBkH8EQFkxO4Y0hjBeLaBU= +github.com/mattn/go-runewidth v0.0.28/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8= +github.com/mattn/go-shellwords v1.0.14 h1:yUKzIgsCnosndOASY6/enly1EAuaXeFSQ7cdyA3OuYg= +github.com/mattn/go-shellwords v1.0.14/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/go-archive v0.3.2 h1:x893kC3zRygv2C+k4Y9kMxYRPLCj4XEJB0srbAP06Hw= -github.com/moby/go-archive v0.3.2/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= +github.com/moby/go-archive v0.3.3 h1:OxxR9paxsluYi+zDUEXTTaIxtkK3viymW+Ka7vRhhME= +github.com/moby/go-archive v0.3.3/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= github.com/moby/moby/api v1.55.0 h1:2/sexvQyqIWS8pRSCFddBfpW2qE7vR7FCL+vN8pxwMc= github.com/moby/moby/api v1.55.0/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= github.com/moby/moby/client v0.5.1 h1:tYNaJno4c0HXz12y5BiqEDy0rVTYkWzI26lGvnTMiJw= github.com/moby/moby/client v0.5.1/go.mod h1:odLstlZ6uSnfvAgVxMpvgmb8SUdd+siH2T0GBuxVAlM= github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U= github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/mount v0.3.5 h1:eS3fsZTjHaBihwjp4/+5Z3jxqLXYsbwxqpVSfFv3M00= +github.com/moby/sys/mount v0.3.5/go.mod h1:WUQDO+/uCiCIkIztx8SrwIDVn2dtMFRBebRhpDFT71M= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.7.0 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8= github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o= github.com/moby/sys/user v0.4.1 h1:RgjRlaDKi/Xmyrz4t8lyzXT6v2ooFeO/7xtchmhVWE0= github.com/moby/sys/user v0.4.1/go.mod h1:E9QsW5WRe1kUAf7kW8hXKwu1uhsZEAdPLYHYSDudF4Y= -github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/sys/userns v0.2.0 h1:nEtDtp7NCV/6dutSklNe8FrENPwFdc4mXnZqC/JWgXM= +github.com/moby/sys/userns v0.2.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= @@ -151,7 +154,6 @@ github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU= github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU= github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= @@ -171,8 +173,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= -github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= +github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg= github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -191,8 +193,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928 h1:zjNCuOOhh1TKRU0Ru3PPPJt80z7eReswCao91gBLk00= github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928/go.mod h1:PCFYfAEfKT+Nd6zWvUpsXduMR1bXFLf0uGSlEF05MCI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -210,34 +212,35 @@ go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -254,11 +257,11 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= -golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/internal/app/cmd/daemon.go b/internal/app/cmd/daemon.go index b70463c7..1259d71a 100644 --- a/internal/app/cmd/daemon.go +++ b/internal/app/cmd/daemon.go @@ -54,15 +54,16 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu // processes with the same identity are indistinguishable to Gitea and // end up cancelling each other's jobs. releaseLock, err := lock.TryLock(cfg.Runner.File) - if errors.Is(err, lock.ErrLocked) { + switch { + case errors.Is(err, lock.ErrLocked): log.Errorf("another gitea-runner process is already using %q; each runner process needs its own runner file (runner.file)", cfg.Runner.File) return err - } else if err != nil { + case err != nil: // Best-effort guard: if the lock file can't be created (e.g. a // read-only runner-file mount), warn and start anyway rather than // refusing to run. log.Warnf("could not lock runner file %q, continuing without the single-process guard: %v", cfg.Runner.File, err) - } else { + default: // Held until shutdown finishes: the draining runner still owns this // identity on the server, so releasing early would let a restart // reintroduce the duplicate-identity job cancellations. @@ -170,13 +171,14 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu // declare the labels of the runner before fetching tasks resp, err := runner.Declare(ctx, ls.Names()) - if err != nil && connect.CodeOf(err) == connect.CodeUnimplemented { + switch { + case err != nil && connect.CodeOf(err) == connect.CodeUnimplemented: log.Errorf("Your Gitea version is too old to support runner declare, please upgrade to v1.21 or later") return err - } else if err != nil { + case err != nil: log.WithError(err).Error("fail to invoke Declare") return err - } else { + default: log.Infof("runner: %s, with version: %s, with labels: %v, declare successfully", resp.Msg.Runner.Name, resp.Msg.Runner.Version, resp.Msg.Runner.Labels) } diff --git a/internal/app/cmd/exec.go b/internal/app/cmd/exec.go index bf5c7340..91eb3515 100644 --- a/internal/app/cmd/exec.go +++ b/internal/app/cmd/exec.go @@ -303,19 +303,20 @@ func runExecList(planner model.WorkflowPlanner, execArgs *executeArgs) error { } var err error - if execArgs.job != "" { + switch { + case execArgs.job != "": log.Infof("Preparing plan with a job: %s", execArgs.job) filterPlan, err = planner.PlanJob(execArgs.job) if err != nil { return err } - } else if filterEventName != "" { + case filterEventName != "": log.Infof("Preparing plan for a event: %s", filterEventName) filterPlan, err = planner.PlanEvent(filterEventName) if err != nil { return err } - } else { + default: log.Infof("Preparing plan with all jobs") filterPlan, err = planner.PlanAll() if err != nil { @@ -348,18 +349,19 @@ func runExec(ctx context.Context, execArgs *executeArgs) func(cmd *cobra.Command // collect all events from loaded workflows events := planner.GetEvents() - if len(execArgs.event) > 0 { + switch { + case len(execArgs.event) > 0: log.Infof("Using chosed event for filtering: %s", execArgs.event) eventName = execArgs.event - } else if len(events) == 1 && len(events[0]) > 0 { + case len(events) == 1 && len(events[0]) > 0: log.Infof("Using the only detected workflow event: %s", events[0]) eventName = events[0] - } else if execArgs.autodetectEvent && len(events) > 0 && len(events[0]) > 0 { + case execArgs.autodetectEvent && len(events) > 0 && len(events[0]) > 0: // set default event type to first event from many available // this way user dont have to specify the event. log.Infof("Using first detected workflow event: %s", events[0]) eventName = events[0] - } else { + default: log.Infof("Using default workflow event: push") eventName = "push" } diff --git a/internal/app/cmd/register.go b/internal/app/cmd/register.go index 59a36254..16408ff7 100644 --- a/internal/app/cmd/register.go +++ b/internal/app/cmd/register.go @@ -276,7 +276,7 @@ func registerInteractive(ctx context.Context, configFile string, regArgs *regist if stage == StageWaitingForRegistration { log.Infof("Registering runner, name=%s, instance=%s, labels=%v.", inputs.RunnerName, inputs.InstanceAddr, inputs.Labels) if err := doRegister(ctx, cfg, inputs); err != nil { - return fmt.Errorf("Failed to register runner: %w", err) + return fmt.Errorf("failed to register runner: %w", err) } log.Infof("Runner registered successfully.") return nil @@ -340,7 +340,7 @@ func registerNoInteractive(ctx context.Context, configFile string, regArgs *regi return err } if err := doRegister(ctx, cfg, inputs); err != nil { - return fmt.Errorf("Failed to register runner: %w", err) + return fmt.Errorf("failed to register runner: %w", err) } log.Infof("Runner registered successfully.") return nil @@ -349,14 +349,15 @@ func registerNoInteractive(ctx context.Context, configFile string, regArgs *regi func doRegister(ctx context.Context, cfg *config.Config, inputs *registerInputs) error { // Refuse to rewrite the runner file while another process is using it. releaseLock, err := lock.TryLock(cfg.Runner.File) - if errors.Is(err, lock.ErrLocked) { + switch { + case errors.Is(err, lock.ErrLocked): return fmt.Errorf("another process is already using %q; stop it before re-registering", cfg.Runner.File) - } else if err != nil { + case err != nil: // Best-effort guard: if the lock file can't be created, warn and // register anyway; writing the runner file will surface any real // permission problem with a clearer error. log.Warnf("could not lock runner file %q, continuing without the single-process guard: %v", cfg.Runner.File, err) - } else { + default: defer func() { _ = releaseLock() }() } diff --git a/internal/app/run/health_check.go b/internal/app/run/health_check.go index 5b00ee50..438abd97 100644 --- a/internal/app/run/health_check.go +++ b/internal/app/run/health_check.go @@ -87,8 +87,7 @@ func executeHealthCheck(ctx context.Context, script string, timeout time.Duratio if err == nil { return nil } - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { return fmt.Errorf("exited with code %d", exitErr.ExitCode()) } return err diff --git a/internal/app/run/post_task_script.go b/internal/app/run/post_task_script.go index 6b054ee0..89ef2cc2 100644 --- a/internal/app/run/post_task_script.go +++ b/internal/app/run/post_task_script.go @@ -74,8 +74,7 @@ func (r *Runner) runPostTaskScript(ctx context.Context, reporter *report.Reporte log.Warnf("post-task script %q for task %d: %v", script, task.Id, err) return } - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { log.Warnf("post-task script %q for task %d exited with code %d", script, task.Id, exitErr.ExitCode()) return } diff --git a/internal/app/run/runner.go b/internal/app/run/runner.go index 948eb5de..f0fdd0b0 100644 --- a/internal/app/run/runner.go +++ b/internal/app/run/runner.go @@ -6,7 +6,7 @@ package run import ( "bytes" "context" - "encoding/json" + "encoding/json/v2" "errors" "fmt" "maps" @@ -676,7 +676,7 @@ func postInternalCache(url, secret string, body map[string]any) (map[string]any, } answer := map[string]any{} // A server too old to answer with a body is not an error, it simply tells us nothing. - _ = json.NewDecoder(resp.Body).Decode(&answer) + _ = json.UnmarshalRead(resp.Body, &answer) return answer, nil } diff --git a/internal/app/run/runner_cache_test.go b/internal/app/run/runner_cache_test.go index 9cd7e47c..b14f2f38 100644 --- a/internal/app/run/runner_cache_test.go +++ b/internal/app/run/runner_cache_test.go @@ -5,7 +5,7 @@ package run import ( "bytes" - "encoding/json" + "encoding/json/v2" "fmt" "io" "net/http" @@ -152,7 +152,7 @@ func TestRunner_CacheFullFlow_MatchesToolkit(t *testing.T) { func decodeJSON(resp *http.Response, v any) error { defer resp.Body.Close() - return json.NewDecoder(resp.Body).Decode(v) + return json.UnmarshalRead(resp.Body, v) } // End-to-end against a remote cache-server: token unknown → 401, register → diff --git a/internal/pkg/config/registration.go b/internal/pkg/config/registration.go index aff26dc2..464f4a5a 100644 --- a/internal/pkg/config/registration.go +++ b/internal/pkg/config/registration.go @@ -4,7 +4,8 @@ package config import ( - "encoding/json" + "encoding/json/jsontext" + "encoding/json/v2" "os" ) @@ -31,7 +32,7 @@ func LoadRegistration(file string) (*Registration, error) { defer f.Close() var reg Registration - if err := json.NewDecoder(f).Decode(®); err != nil { + if err := json.UnmarshalRead(f, ®); err != nil { return nil, err } @@ -49,7 +50,9 @@ func SaveRegistration(file string, reg *Registration) error { reg.Warning = registrationWarning - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - return enc.Encode(reg) + if err := json.MarshalWrite(f, reg, jsontext.WithIndent(" ")); err != nil { + return err + } + _, err = f.WriteString("\n") + return err }