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 <me@silverwind.io>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1185
Reviewed-by: bircni <bircni@icloud.com>
Co-authored-by: Renovate Bot <renovate-bot@gitea.com>
This commit is contained in:
Renovate Bot
2026-08-24 19:53:17 +00:00
committed by bircni
parent 7b4356c746
commit e30c2fed62
47 changed files with 319 additions and 288 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ jobs:
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
- name: Set up Docker BuildX - name: Set up Docker BuildX
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
+1 -1
View File
@@ -80,7 +80,7 @@ jobs:
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
- name: Set up Docker BuildX - name: Set up Docker BuildX
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
+8 -6
View File
@@ -46,8 +46,7 @@ linters:
gocritic: gocritic:
enabled-checks: enabled-checks:
- equalFold - equalFold
disabled-checks: disabled-checks: []
- ifElseChain
revive: revive:
severity: error severity: error
rules: rules:
@@ -71,10 +70,14 @@ linters:
- name: unexported-return - name: unexported-return
- name: var-declaration - name: var-declaration
- name: var-naming - 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: staticcheck:
checks: checks:
- all - all
- -ST1005 testifylint: {}
usetesting: usetesting:
os-temp-dir: true os-temp-dir: true
perfsprint: perfsprint:
@@ -92,8 +95,6 @@ linters:
generated: lax generated: lax
presets: presets:
- comments - comments
- common-false-positives
- legacy
- std-error-handling - std-error-handling
rules: rules:
- linters: - linters:
@@ -118,7 +119,8 @@ formatters:
- blank - blank
- default - default
gofumpt: gofumpt:
extra-rules: true extra:
group-params: true
exclusions: exclusions:
generated: lax generated: lax
run: run:
+3 -3
View File
@@ -1,7 +1,7 @@
### BUILDER STAGE ### 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` # Do not remove `git` here, it is required for getting runner version when executing `make build`
RUN apk add --no-cache make git RUN apk add --no-cache make git
@@ -17,7 +17,7 @@ RUN make clean && make build
### DIND VARIANT ### DIND VARIANT
# #
# #
FROM docker:29.7.1-dind AS dind FROM docker:29.7.2-dind AS dind
ARG VERSION=dev ARG VERSION=dev
@@ -37,7 +37,7 @@ ENTRYPOINT ["s6-svscan","/etc/s6"]
### DIND-ROOTLESS VARIANT ### 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 ARG VERSION=dev
+4 -4
View File
@@ -5,7 +5,7 @@ GO ?= go
SHASUM ?= shasum -a 256 SHASUM ?= shasum -a 256
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) 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_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 GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.16 # renovate: datasource=go
LINUX_ARCHS ?= linux/amd64,linux/arm64 LINUX_ARCHS ?= linux/amd64,linux/arm64
@@ -18,8 +18,8 @@ DOCKER_TAG ?= nightly
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
DOCKER_ROOTLESS_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)-dind-rootless 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 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.6.0 # renovate: datasource=go GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.7.0 # renovate: datasource=go
GOTEST_FLAGS ?= -race -timeout 20m -parallel 8 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 .PHONY: security-check
security-check: security-check:
GOEXPERIMENT= $(GO) run $(GOVULNCHECK_PACKAGE) -show color ./... || true $(GO) run $(GOVULNCHECK_PACKAGE) -show color ./... || true
.PHONY: tidy .PHONY: tidy
tidy: ## run go mod tidy tidy: ## run go mod tidy
+6 -6
View File
@@ -11,7 +11,7 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -357,8 +357,8 @@ func (h *Handler) Close() error {
func (h *Handler) openDB() (*bolthold.Store, error) { func (h *Handler) openDB() (*bolthold.Store, error) {
return bolthold.Open(filepath.Join(h.dir, "bolt.db"), 0o644, &bolthold.Options{ return bolthold.Open(filepath.Join(h.dir, "bolt.db"), 0o644, &bolthold.Options{
Encoder: json.Marshal, Encoder: func(value any) ([]byte, error) { return json.Marshal(value) },
Decoder: json.Unmarshal, Decoder: func(data []byte, value any) error { return json.Unmarshal(data, value) },
Options: &bbolt.Options{ Options: &bbolt.Options{
Timeout: 5 * time.Second, Timeout: 5 * time.Second,
NoGrowSync: bbolt.DefaultOptions.NoGrowSync, 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) { func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
cred := credFromContext(r.Context()) cred := credFromContext(r.Context())
api := &Request{} 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) h.responseJSON(w, r, 400, err)
return return
} }
@@ -692,7 +692,7 @@ func (h *Handler) ResultsURL(cred JobCredential) string {
func (h *Handler) internalRegister(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (h *Handler) internalRegister(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var body internalRegisterBody 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) h.responseJSON(w, r, http.StatusBadRequest, err)
return return
} }
@@ -708,7 +708,7 @@ func (h *Handler) internalRegister(w http.ResponseWriter, r *http.Request, _ htt
// POST /_internal/revoke // POST /_internal/revoke
func (h *Handler) internalRevoke(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (h *Handler) internalRevoke(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
var body internalRevokeBody 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) h.responseJSON(w, r, http.StatusBadRequest, err)
return return
} }
+16 -16
View File
@@ -7,7 +7,7 @@ package artifactcache
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -136,7 +136,7 @@ func TestHandler(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(t, 200, resp.StatusCode) 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) assert.NotZero(t, first.CacheID)
} }
{ {
@@ -151,7 +151,7 @@ func TestHandler(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(t, 200, resp.StatusCode) 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) assert.NotZero(t, second.CacheID)
} }
@@ -204,7 +204,7 @@ func TestHandler(t *testing.T) {
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
{ {
@@ -259,7 +259,7 @@ func TestHandler(t *testing.T) {
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
{ {
@@ -315,7 +315,7 @@ func TestHandler(t *testing.T) {
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
{ {
@@ -362,7 +362,7 @@ func TestHandler(t *testing.T) {
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
@@ -413,7 +413,7 @@ func TestHandler(t *testing.T) {
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
{ {
@@ -493,7 +493,7 @@ func TestHandler(t *testing.T) {
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"` 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, "hit", got.Result)
assert.Equal(t, keys[except], got.CacheKey) assert.Equal(t, keys[except], got.CacheKey)
@@ -528,7 +528,7 @@ func TestHandler(t *testing.T) {
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"` 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, "hit", got.Result)
assert.Equal(t, key, got.CacheKey) assert.Equal(t, key, got.CacheKey)
assert.NotEqual(t, strings.ToLower(key), got.CacheKey) assert.NotEqual(t, strings.ToLower(key), got.CacheKey)
@@ -577,7 +577,7 @@ func TestHandler(t *testing.T) {
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"` 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) assert.Equal(t, keys[expect], got.CacheKey)
contentResp, err := testClient.Get(got.ArchiveLocation) contentResp, err := testClient.Get(got.ArchiveLocation)
@@ -633,7 +633,7 @@ func TestHandler(t *testing.T) {
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"` 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) assert.Equal(t, keys[expect], got.CacheKey)
contentResp, err := testClient.Get(got.ArchiveLocation) contentResp, err := testClient.Get(got.ArchiveLocation)
@@ -677,7 +677,7 @@ func uploadCacheNormally(t *testing.T, base, key, version string, content []byte
got := struct { got := struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
}{} }{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
id = got.CacheID id = got.CacheID
} }
{ {
@@ -708,7 +708,7 @@ func uploadCacheNormally(t *testing.T, base, key, version string, content []byte
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"` 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, "hit", got.Result)
assert.Equal(t, key, got.CacheKey) assert.Equal(t, key, got.CacheKey)
archiveLocation = got.ArchiveLocation archiveLocation = got.ArchiveLocation
@@ -1197,7 +1197,7 @@ func TestHandler_CrossRepoIsolation(t *testing.T) {
var reserved struct { var reserved struct {
CacheID uint64 `json:"cacheId"` CacheID uint64 `json:"cacheId"`
} }
require.NoError(t, json.NewDecoder(resp.Body).Decode(&reserved)) require.NoError(t, json.UnmarshalRead(resp.Body, &reserved))
resp.Body.Close() resp.Body.Close()
require.NotZero(t, reserved.CacheID) require.NotZero(t, reserved.CacheID)
@@ -1331,7 +1331,7 @@ func TestHandler_ArtifactSignatureDownload(t *testing.T) {
var hit struct { var hit struct {
ArchiveLocation string `json:"archiveLocation"` ArchiveLocation string `json:"archiveLocation"`
} }
require.NoError(t, json.NewDecoder(resp.Body).Decode(&hit)) require.NoError(t, json.UnmarshalRead(resp.Body, &hit))
resp.Body.Close() resp.Body.Close()
require.Contains(t, hit.ArchiveLocation, "sig=") require.Contains(t, hit.ArchiveLocation, "sig=")
+31 -5
View File
@@ -5,7 +5,8 @@ package artifactcache
import ( import (
"cmp" "cmp"
"encoding/json" "encoding/json/jsontext"
"encoding/json/v2"
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt" "fmt"
@@ -128,7 +129,7 @@ func (h *Handler) v2FinalizeCacheEntryUpload(w http.ResponseWriter, r *http.Requ
} }
db.Close() // commitCache needs the store closed 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 { if err := h.commitCache(cache); err != nil {
h.logger.Errorf("finalize cache %d (%s): %v", cache.ID, cache.Key, err) h.logger.Errorf("finalize cache %d (%s): %v", cache.ID, cache.Key, err)
h.twirpNotOK(w, r) h.twirpNotOK(w, r)
@@ -247,8 +248,8 @@ type (
v2FinalizeRequest struct { v2FinalizeRequest struct {
Key string `json:"key"` Key string `json:"key"`
Version string `json:"version"` Version string `json:"version"`
SizeBytes json.Number `json:"size_bytes"` SizeBytes twirpInt64 `json:"size_bytes"`
SizeBytesCamel json.Number `json:"sizeBytes"` SizeBytesCamel twirpInt64 `json:"sizeBytes"`
} }
v2DownloadRequest struct { 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 { func (d v2DownloadRequest) keys() []string {
restoreKeys := d.RestoreKeys restoreKeys := d.RestoreKeys
if len(restoreKeys) == 0 { if len(restoreKeys) == 0 {
@@ -269,6 +295,6 @@ func (d v2DownloadRequest) keys() []string {
func decodeTwirpRequest[T any](r *http.Request) (T, error) { func decodeTwirpRequest[T any](r *http.Request) (T, error) {
var req T 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 return req, err
} }
+3 -3
View File
@@ -6,7 +6,7 @@ package artifactcache
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json/v2"
"fmt" "fmt"
"io" "io"
"net/http" "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) require.Equal(t, http.StatusOK, resp.StatusCode)
got := map[string]any{} got := map[string]any{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got)) require.NoError(t, json.UnmarshalRead(resp.Body, &got))
return got return got
} }
@@ -227,7 +227,7 @@ func TestCacheServiceV2Lookups(t *testing.T) {
require.Equal(t, http.StatusOK, resp.StatusCode) require.Equal(t, http.StatusOK, resp.StatusCode)
got := map[string]any{} 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.Equal(t, "deps-abc", got["cacheKey"])
assert.NotEmpty(t, got["archiveLocation"]) assert.NotEmpty(t, got["archiveLocation"])
}) })
+2 -2
View File
@@ -6,7 +6,7 @@ package artifacts
import ( import (
"context" "context"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -100,7 +100,7 @@ func uploads(router *httprouter.Router, baseDir string) {
} }
defer file.Close() defer file.Close()
if req.Body == nil { if req.Body == nil {
panic(errors.New("No body given")) panic(errors.New("no body given"))
} }
_, err = io.Copy(file, req.Body) _, err = io.Copy(file, req.Body)
+1 -1
View File
@@ -7,7 +7,7 @@ package artifacts
import ( import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"encoding/json" "encoding/json/v2"
"io" "io"
"maps" "maps"
"net/http" "net/http"
+1 -1
View File
@@ -171,7 +171,7 @@ func (e Executor) Finally(finally Executor) Executor {
err := e(ctx) err := e(ctx)
err2 := finally(ctx) err2 := finally(ctx)
if err2 != nil { 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 return err
} }
+4 -3
View File
@@ -274,11 +274,12 @@ func CloneIfRequired(ctx context.Context, refName plumbing.ReferenceName, input
return r, true, nil 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) 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) 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) 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 { if err := os.RemoveAll(input.Dir); err != nil {
+5 -5
View File
@@ -46,14 +46,14 @@ func (lw *lineWriter) Write(p []byte) (n int, err error) {
line, err := pBuf.ReadString('\n') line, err := pBuf.ReadString('\n')
w, _ := lw.buffer.WriteString(line) w, _ := lw.buffer.WriteString(line)
written += w written += w
if err == nil { if err != nil {
lw.handleLine(lw.buffer.String()) if err == io.EOF {
lw.buffer.Reset()
} else if err == io.EOF {
break break
} else { }
return written, err return written, err
} }
lw.handleLine(lw.buffer.String())
lw.buffer.Reset()
} }
return written, nil return written, nil
+4 -5
View File
@@ -17,8 +17,7 @@
package container package container
import ( import (
"bytes" "encoding/json/jsontext"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"net" "net"
@@ -959,11 +958,11 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) {
if err != nil { if err != nil {
return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %w", v, err) return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %w", v, err)
} }
var b bytes.Buffer profile := jsontext.Value(f)
if err := json.Compact(&b, f); err != nil { if err := profile.Compact(); err != nil {
return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", v, err) return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", v, err)
} }
securityOpts[key] = "seccomp=" + b.String() securityOpts[key] = "seccomp=" + string(profile)
} }
} }
} }
+2 -2
View File
@@ -55,11 +55,11 @@ func parseContainerOptions(options string) (*pflag.FlagSet, *containerOptions, *
args, err := shellquote.Split(options) args, err := shellquote.Split(options)
if err != nil { 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 { 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 return flags, copts, cf, nil
+7 -6
View File
@@ -8,7 +8,7 @@ package container
import ( import (
"bufio" "bufio"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"io" "io"
@@ -20,8 +20,8 @@ type dockerMessage struct {
Stream string `json:"stream"` Stream string `json:"stream"`
Error string `json:"error"` Error string `json:"error"`
ErrorDetail struct { ErrorDetail struct {
Message string Message string `json:"message"`
} } `json:"errorDetail"`
Status string `json:"status"` Status string `json:"status"`
Progress string `json:"progress"` Progress string `json:"progress"`
} }
@@ -60,15 +60,16 @@ func logDockerResponse(logger logrus.FieldLogger, dockerResponse io.ReadCloser,
return errors.New(msg.ErrorDetail.Message) return errors.New(msg.ErrorDetail.Message)
} }
if msg.Status != "" { switch {
case msg.Status != "":
if msg.Progress != "" { if msg.Progress != "" {
writeLog(logger, isError, "%s :: %s :: %s\n", msg.Status, msg.ID, msg.Progress) writeLog(logger, isError, "%s :: %s :: %s\n", msg.Status, msg.ID, msg.Progress)
} else { } else {
writeLog(logger, isError, "%s :: %s\n", msg.Status, msg.ID) writeLog(logger, isError, "%s :: %s\n", msg.Status, msg.ID)
} }
} else if msg.Stream != "" { case msg.Stream != "":
writeLog(logger, isError, "%s", msg.Stream) writeLog(logger, isError, "%s", msg.Stream)
} else { default:
writeLog(logger, false, "Unable to handle line: %s", string(line)) writeLog(logger, false, "Unable to handle line: %s", string(line))
} }
} }
+3 -3
View File
@@ -32,9 +32,9 @@ func TestRemoveOrphanNetworks(t *testing.T) {
client.On("NetworkList", ctx, mobyclient.NetworkListOptions{ client.On("NetworkList", ctx, mobyclient.NetworkListOptions{
Filters: make(mobyclient.Filters).Add("label", runnerUUIDLabel+"=runner-1"), Filters: make(mobyclient.Filters).Add("label", runnerUUIDLabel+"=runner-1"),
}).Return(mobyclient.NetworkListResult{Items: []network.Summary{ }).Return(mobyclient.NetworkListResult{Items: []network.Summary{
{Network: network.Network{ID: "orphan"}}, {ID: "orphan"},
{Network: network.Network{ID: "busy"}}, {ID: "busy"},
{Network: network.Network{ID: "starting"}}, {ID: "starting"},
}}, nil) }}, nil)
client.On("NetworkInspect", ctx, "orphan", mobyclient.NetworkInspectOptions{}). client.On("NetworkInspect", ctx, "orphan", mobyclient.NetworkInspectOptions{}).
Return(mobyclient.NetworkInspectResult{}, nil) Return(mobyclient.NetworkInspectResult{}, nil)
+6 -6
View File
@@ -539,14 +539,14 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config
} }
if err := cf.validate(); err != nil { 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. // FIXME: If everything is fine after gitea/act v0.260.0, remove the following comment.
// In the old fork version, the code is // In the old fork version, the code is
// if len(copts.netMode.Value()) == 0 { // if len(copts.netMode.Value()) == 0 {
// if err = copts.netMode.Set("host"); err != nil { // 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: // 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 len(copts.netMode.Value()) == 0 {
if err = copts.netMode.Set(cr.input.NetworkMode); err != nil { 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) containerConfig, err := parse(flags, copts, runtime.GOOS)
if err != nil { 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 // For Gitea
@@ -587,7 +587,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config
err = mergo.Merge(config, containerConfig.Config, mergo.WithOverride, mergo.WithAppendSlice) err = mergo.Merge(config, containerConfig.Config, mergo.WithOverride, mergo.WithAppendSlice)
if err != nil { 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) logger.Debugf("Merged container.Config ==> %+v", config)
@@ -599,7 +599,7 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config
networkMode := hostConfig.NetworkMode networkMode := hostConfig.NetworkMode
err = mergo.Merge(hostConfig, containerConfig.HostConfig, mergo.WithOverride) err = mergo.Merge(hostConfig, containerConfig.HostConfig, mergo.WithOverride)
if err != nil { 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.Binds = binds
hostConfig.Mounts = mounts hostConfig.Mounts = mounts
-8
View File
@@ -186,10 +186,8 @@ func TestDockerExecAbort(t *testing.T) {
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ExecCreate", ctx, "123", mock.AnythingOfType("client.ExecCreateOptions")).Return(mobyclient.ExecCreateResult{ID: "id"}, nil) 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{ client.On("ExecAttach", ctx, "id", mock.AnythingOfType("client.ExecAttachOptions")).Return(mobyclient.ExecAttachResult{
HijackedResponse: mobyclient.HijackedResponse{
Conn: conn, Conn: conn,
Reader: bufio.NewReader(reader), Reader: bufio.NewReader(reader),
},
}, nil) }, nil)
cr := &containerReference{ cr := &containerReference{
@@ -225,10 +223,8 @@ func TestDockerExecFailure(t *testing.T) {
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ExecCreate", ctx, "123", mock.AnythingOfType("client.ExecCreateOptions")).Return(mobyclient.ExecCreateResult{ID: "id"}, nil) 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{ client.On("ExecAttach", ctx, "id", mock.AnythingOfType("client.ExecAttachOptions")).Return(mobyclient.ExecAttachResult{
HijackedResponse: mobyclient.HijackedResponse{
Conn: conn, Conn: conn,
Reader: bufio.NewReader(strings.NewReader("output")), Reader: bufio.NewReader(strings.NewReader("output")),
},
}, nil) }, nil)
client.On("ExecInspect", ctx, "id", mobyclient.ExecInspectOptions{}).Return(mobyclient.ExecInspectResult{ client.On("ExecInspect", ctx, "id", mobyclient.ExecInspectOptions{}).Return(mobyclient.ExecInspectResult{
ExitCode: 1, ExitCode: 1,
@@ -280,10 +276,8 @@ func TestDockerAttachFlushesTrailingLine(t *testing.T) {
client := &mockDockerClient{} client := &mockDockerClient{}
client.On("ContainerAttach", ctx, "123", mock.AnythingOfType("client.ContainerAttachOptions")). client.On("ContainerAttach", ctx, "123", mock.AnythingOfType("client.ContainerAttachOptions")).
Return(mobyclient.ContainerAttachResult{ Return(mobyclient.ContainerAttachResult{
HijackedResponse: mobyclient.HijackedResponse{
Conn: &mockConn{}, Conn: &mockConn{},
Reader: bufio.NewReader(framed), Reader: bufio.NewReader(framed),
},
}, nil) }, nil)
statusCh := make(chan container.WaitResponse, 1) statusCh := make(chan container.WaitResponse, 1)
@@ -603,11 +597,9 @@ func TestSanitizeOptionsHostConfig(t *testing.T) {
SecurityOpt: []string{"seccomp=unconfined", "apparmor=unconfined"}, SecurityOpt: []string{"seccomp=unconfined", "apparmor=unconfined"},
VolumesFrom: []string{"other"}, VolumesFrom: []string{"other"},
Runtime: "runc", Runtime: "runc",
Resources: container.Resources{
CgroupParent: "/custom", CgroupParent: "/custom",
Devices: []container.DeviceMapping{{PathOnHost: "/dev/sda", PathInContainer: "/dev/sda", CgroupPermissions: "rwm"}}, Devices: []container.DeviceMapping{{PathOnHost: "/dev/sda", PathInContainer: "/dev/sda", CgroupPermissions: "rwm"}},
DeviceCgroupRules: []string{"a *:* rwm"}, DeviceCgroupRules: []string{"a *:* rwm"},
},
Sysctls: map[string]string{"net.ipv4.ip_forward": "1"}, Sysctls: map[string]string{"net.ipv4.ip_forward": "1"},
} }
} }
+1 -2
View File
@@ -351,8 +351,7 @@ func (e *HostEnvironment) exec(ctx context.Context, command []string, cmdline st
} }
err = cmd.Wait() err = cmd.Wait()
if err != nil { if err != nil {
var exitErr *exec.ExitError if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
if errors.As(err, &exitErr) {
return ExitCodeError(exitErr.ExitCode()) return ExitCodeError(exitErr.ExitCode())
} }
return err return err
+4 -3
View File
@@ -46,9 +46,10 @@ func parseEnvFile(e Container, srcPath string, env *map[string]string) common.Ex
} }
singleLineEnv := strings.Index(line, "=") singleLineEnv := strings.Index(line, "=")
multiLineEnv := 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:] localEnv[line[:singleLineEnv]] = line[singleLineEnv+1:]
} else if multiLineEnv != -1 { case multiLineEnv != -1:
multiLineEnvContent := "" multiLineEnvContent := ""
multiLineEnvDelimiter := line[multiLineEnv+2:] multiLineEnvDelimiter := line[multiLineEnv+2:]
delimiterFound := false 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) return fmt.Errorf("invalid format delimiter '%v' not found before end of file", multiLineEnvDelimiter)
} }
localEnv[line[:multiLineEnv]] = multiLineEnvContent localEnv[line[:multiLineEnv]] = multiLineEnvContent
} else { default:
return fmt.Errorf("invalid format '%v', expected a line with '=' or '<<'", line) return fmt.Errorf("invalid format '%v', expected a line with '=' or '<<'", line)
} }
} }
+1 -1
View File
@@ -219,7 +219,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
rc.JobContainer.Exec(execArgs, *step.getEnv(), "", ""), rc.JobContainer.Exec(execArgs, *step.getEnv(), "", ""),
)(ctx) )(ctx)
default: 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.ActionRunsUsingDocker,
model.ActionRunsUsingNode12, model.ActionRunsUsingNode12,
model.ActionRunsUsingNode16, model.ActionRunsUsingNode16,
+1 -1
View File
@@ -55,7 +55,7 @@ func newCompositeRunContext(ctx context.Context, parent *RunContext, step action
env := evaluateCompositeInputAndEnv(ctx, parent, step) env := evaluateCompositeInputAndEnv(ctx, parent, step)
// run with the global config but without secrets // run with the global config but without secrets
configCopy := *(parent.Config) configCopy := *parent.Config
configCopy.Secrets = nil configCopy.Secrets = nil
// create a run context for the composite action to run in // create a run context for the composite action to run in
+1 -1
View File
@@ -170,7 +170,7 @@ func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.
followSymlink = true followSymlink = true
continue 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) patterns = append(patterns, s)
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
+3 -1
View File
@@ -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 // Processed even on failure, so a hook that exports what it managed to set up before
// failing still hands it to the job. // 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 { if err == nil {
return nil return nil
} }
+15 -16
View File
@@ -8,7 +8,8 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json/jsontext"
"encoding/json/v2"
"fmt" "fmt"
"io" "io"
"net/url" "net/url"
@@ -78,7 +79,7 @@ type JobLoggerFactory interface {
type jobLoggerFactoryContextKey string type jobLoggerFactoryContextKey string
var jobLoggerFactoryContextKeyVal = (jobLoggerFactoryContextKey)("jobloggerkey") var jobLoggerFactoryContextKeyVal = jobLoggerFactoryContextKey("jobloggerkey")
func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context.Context { func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context.Context {
return context.WithValue(ctx, jobLoggerFactoryContextKeyVal, factory) 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 // 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. // that do not. When v has none of those characters both forms are equal and deduplicated.
func jsonStringEscape(v string) string { func jsonStringEscape(v string) string {
encoded, err := json.Marshal(v) encoded, err := json.Marshal(v, jsontext.EscapeForHTML(true))
if err != nil { if err != nil {
return v return v
} }
@@ -226,15 +227,11 @@ func jsonStringEscape(v string) string {
// JavaScript (JSON.stringify) or .NET action emits, so a secret containing < > or & is // JavaScript (JSON.stringify) or .NET action emits, so a secret containing < > or & is
// masked in that form too. // masked in that form too.
func jsonStringEscapeNoHTML(v string) string { func jsonStringEscapeNoHTML(v string) string {
var buf bytes.Buffer encoded, err := json.Marshal(v)
enc := json.NewEncoder(&buf) if err != nil {
enc.SetEscapeHTML(false)
if err := enc.Encode(v); err != nil {
return v return v
} }
// Encode appends a newline; drop it along with the surrounding quotes. return string(encoded[1 : len(encoded)-1])
encoded := strings.TrimRight(buf.String(), "\n")
return encoded[1 : len(encoded)-1]
} }
func AppendSecretMasker(oldnew []string, v string) []string { func AppendSecretMasker(oldnew []string, v string) []string {
@@ -366,15 +363,16 @@ func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) {
debugFlag = "[DEBUG] " debugFlag = "[DEBUG] "
} }
if entry.Data[rawOutputField] == true { switch {
case entry.Data[rawOutputField] == true:
if entry.Data[scriptLineCyanField] == true { if entry.Data[scriptLineCyanField] == true {
fmt.Fprintf(b, "\x1b[%dm|\x1b[0m \x1b[36;1m%s\x1b[0m", f.color, entry.Message) fmt.Fprintf(b, "\x1b[%dm|\x1b[0m \x1b[36;1m%s\x1b[0m", f.color, entry.Message)
} else { } else {
fmt.Fprintf(b, "\x1b[%dm|\x1b[0m %s", f.color, entry.Message) 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) 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) 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] " debugFlag = "[DEBUG] "
} }
if entry.Data[rawOutputField] == true { switch {
case entry.Data[rawOutputField] == true:
fmt.Fprintf(b, "[%s] | %s", job, entry.Message) 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) fmt.Fprintf(b, "*DRYRUN* [%s] %s%s", job, debugFlag, entry.Message)
} else { default:
fmt.Fprintf(b, "[%s] %s%s", job, debugFlag, entry.Message) fmt.Fprintf(b, "[%s] %s%s", job, debugFlag, entry.Message)
} }
} }
+7 -6
View File
@@ -11,7 +11,7 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -198,14 +198,15 @@ func (rc *RunContext) networkNameForGitea() (string, bool) {
func getDockerDaemonSocketMountPath(daemonPath string) string { func getDockerDaemonSocketMountPath(daemonPath string) string {
if before, after, ok := strings.Cut(daemonPath, "://"); ok { if before, after, ok := strings.Cut(daemonPath, "://"); ok {
scheme := before 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 // linux container mount on windows, use the default socket path of the VM / wsl2
return "/var/run/docker.sock" return "/var/run/docker.sock"
} else if strings.EqualFold(scheme, "unix") { case strings.EqualFold(scheme, "unix"):
return after 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') return (r < 'a' || r > 'z') && (r < 'A' || r > 'Z')
}) == -1 { }) == -1:
// unknown protocol use default // unknown protocol use default
return "/var/run/docker.sock" return "/var/run/docker.sock"
} }
@@ -550,7 +551,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
AllocatePTY: rc.Config.AllocatePTY, AllocatePTY: rc.Config.AllocatePTY,
}) })
if rc.JobContainer == nil { if rc.JobContainer == nil {
return errors.New("Failed to create job container") return errors.New("failed to create job container")
} }
rc.jobNetworkName = networkName rc.jobNetworkName = networkName
+3
View File
@@ -215,8 +215,11 @@ type fakeContainer struct {
} }
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) 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) Remove() common.Executor { return func(context.Context) error { return nil } }
func (fakeContainer) Close() 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) GetActPath() string { return "/var/run/act" }
func (fakeContainer) Create([]string, []string) common.Executor { func (fakeContainer) Create([]string, []string) common.Executor {
+1 -1
View File
@@ -306,7 +306,7 @@ func handleFailure(plan *model.Plan) common.Executor {
for _, stage := range plan.Stages { for _, stage := range plan.Stages {
for _, run := range stage.Runs { for _, run := range stage.Runs {
if run.Job().Result == "failure" && !run.Job().ContinueOnError { if run.Job().Result == "failure" && !run.Job().ContinueOnError {
return fmt.Errorf("Job '%s' failed", run.String()) return fmt.Errorf("job '%s' failed", run.String())
} }
} }
} }
+6 -5
View File
@@ -60,7 +60,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
sar.remoteAction = newRemoteAction(sar.Step.Uses) sar.remoteAction = newRemoteAction(sar.Step.Uses)
} }
if sar.remoteAction == nil { 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 { 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 var ntErr common.Executor
if err := gitClone(ctx); err != nil { if err := gitClone(ctx); err != nil {
var refErr *git.Error var refErr *git.Error
if errors.As(err, &refErr) && errors.Is(err, git.ErrShortRef) { switch {
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", 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()) 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) ntErr = common.NewInfoExecutor("Non-terminating error while running 'git clone': %v", err)
} else { default:
return err return err
} }
} }
+2 -2
View File
@@ -29,9 +29,9 @@ func TestStepDockerMain(t *testing.T) {
input = containerInput input = containerInput
return cm return cm
} }
defer (func() { defer func() {
ContainerNewContainer = origContainerNewContainer ContainerNewContainer = origContainerNewContainer
})() }()
ctx := context.Background() ctx := context.Background()
+2 -2
View File
@@ -19,7 +19,7 @@ type stepFactoryImpl struct{}
func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step, error) { func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step, error) {
switch stepModel.Type() { switch stepModel.Type() {
case model.StepTypeInvalid: 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: case model.StepTypeRun:
return &stepRun{ return &stepRun{
Step: stepModel, Step: stepModel,
@@ -46,5 +46,5 @@ func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step,
}, nil }, 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)
} }
+1 -1
View File
@@ -65,7 +65,7 @@ func TestStepFactoryNewStep(t *testing.T) {
step, err := sf.newStep(tt.model, &RunContext{}) step, err := sf.newStep(tt.model, &RunContext{})
assert.True(t, tt.check((step))) assert.True(t, tt.check(step))
assert.NoError(t, err) assert.NoError(t, err)
}) })
} }
+10 -10
View File
@@ -160,17 +160,17 @@ func TestSetupEnv(t *testing.T) {
setupEnv(context.Background(), sm) setupEnv(context.Background(), sm)
// These are commit or system specific // These are commit or system specific
delete((env), "GITHUB_REF") delete(env, "GITHUB_REF")
delete((env), "GITHUB_REF_NAME") delete(env, "GITHUB_REF_NAME")
delete((env), "GITHUB_REF_TYPE") delete(env, "GITHUB_REF_TYPE")
delete((env), "GITHUB_SHA") delete(env, "GITHUB_SHA")
delete((env), "GITHUB_WORKSPACE") delete(env, "GITHUB_WORKSPACE")
delete((env), "GITHUB_REPOSITORY") delete(env, "GITHUB_REPOSITORY")
delete((env), "GITHUB_REPOSITORY_OWNER") delete(env, "GITHUB_REPOSITORY_OWNER")
delete((env), "GITHUB_ACTOR") delete(env, "GITHUB_ACTOR")
// Host-dependent, asserted in TestRunContextWithGithubEnvRunnerValues instead. // Host-dependent, asserted in TestRunContextWithGithubEnvRunnerValues instead.
delete((env), "RUNNER_NAME") delete(env, "RUNNER_NAME")
delete((env), "RUNNER_WORKSPACE") delete(env, "RUNNER_WORKSPACE")
assert.Equal(t, map[string]string{ assert.Equal(t, map[string]string{
"ACT": "true", "ACT": "true",
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"io" "io"
+28 -33
View File
@@ -1,8 +1,8 @@
module gitea.com/gitea/runner module gitea.com/gitea/runner
go 1.26.0 go 1.27
toolchain go1.26.6 toolchain go1.27.0
require ( require (
connectrpc.com/connect v1.20.0 connectrpc.com/connect v1.20.0
@@ -12,7 +12,7 @@ require (
github.com/containerd/errdefs v1.0.0 github.com/containerd/errdefs v1.0.0
github.com/creack/pty v1.1.24 github.com/creack/pty v1.1.24
github.com/distribution/reference v0.6.0 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-connections v0.8.1
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
github.com/go-git/go-billy/v5 v5.9.1 github.com/go-git/go-billy/v5 v5.9.1
@@ -23,7 +23,7 @@ require (
github.com/julienschmidt/httprouter v1.3.0 github.com/julienschmidt/httprouter v1.3.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-isatty v0.0.24 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/api v1.55.0
github.com/moby/moby/client v0.5.1 github.com/moby/moby/client v0.5.1
github.com/moby/patternmatcher v0.6.1 github.com/moby/patternmatcher v0.6.1
@@ -31,42 +31,41 @@ require (
github.com/opencontainers/selinux v1.15.1 github.com/opencontainers/selinux v1.15.1
github.com/prometheus/client_golang v1.24.1 github.com/prometheus/client_golang v1.24.1
github.com/prometheus/client_model v0.6.2 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/cobra v1.10.2
github.com/spf13/pflag v1.0.10 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 github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928
go.etcd.io/bbolt v1.5.0 go.etcd.io/bbolt v1.5.0
go.yaml.in/yaml/v4 v4.0.0-rc.3 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/sync v0.22.0
golang.org/x/sys v0.47.0 golang.org/x/sys v0.47.0
golang.org/x/term v0.45.0 golang.org/x/term v0.45.0
golang.org/x/text v0.40.0 golang.org/x/text v0.41.0
google.golang.org/protobuf v1.36.11 google.golang.org/protobuf v1.36.12
gotest.tools/v3 v3.5.2 gotest.tools/v3 v3.5.2
tags.cncf.io/container-device-interface v1.1.0 tags.cncf.io/container-device-interface v1.1.0
) )
require ( 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/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/beorn7/perks v1.0.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.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/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/cyphar/filepath-securejoin v0.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/docker-credential-helpers v0.9.8 // indirect
github.com/docker/docker-credential-helpers v0.9.6 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.19.0 // 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-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-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // 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/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.6.0 // indirect github.com/kevinburke/ssh_config v1.6.0 // indirect
github.com/klauspost/compress v1.19.1 // indirect github.com/klauspost/compress v1.19.2 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/cpuid/v2 v2.4.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-runewidth v0.0.21 // indirect github.com/mattn/go-runewidth v0.0.28 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.14 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/sequential v0.7.0 // indirect github.com/moby/sys/sequential v0.7.0 // indirect
github.com/moby/sys/user v0.4.1 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pjbgf/sha1cd v0.6.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/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect github.com/prometheus/procfs v0.21.1 // indirect
github.com/rhysd/actionlint v1.7.12 // 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/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // 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/contrib/instrumentation/net/http/otelhttp v0.70.0 // indirect
go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel v1.45.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/otel/metric v1.45.0 // indirect
go.opentelemetry.io/otel/sdk v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.45.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect golang.org/x/crypto v0.55.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.54.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )
+60 -57
View File
@@ -1,7 +1,7 @@
connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ=
connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= 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.5 h1:SnX9FBvnoyn3lUs1dkMgZ52bAETpirNu3FTRh5HlRik=
cyphar.com/go-pathrs v0.2.3/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= 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 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
gitea.dev/actionslib v0.7.0 h1:JCV8eeIGwjlXcuSr7ojEdQC22VoE2466+K+D9vuQWKQ= 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.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 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.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= 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 h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= 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= 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/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 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= 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.5 h1:O64F26HEqNhznd/hrC5KZXVKYuKM2rx4deZDTc4ihQA=
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= 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 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= 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/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 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= 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.7.0 h1:s0Y3ITPy6sQn5xt54DuYvTF8hu134ooYLUb58DX/HjE=
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= 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.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/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 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= 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.2+incompatible h1:dlkwallR8XqfeVnA2ELEhdwvb4lsSwuB4IgsG8Q9cLY=
github.com/docker/cli v29.7.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v29.7.2+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.8 h1:bIREROb7So6PRlq6KTtdS9MPEjC29OQRkFNlvK2OX8Q=
github.com/docker/docker-credential-helpers v0.9.6/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= 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 h1:JibmG5hULs5qXSr/cp/w3Pw5fZuStt4MOHMUExb29/M=
github.com/docker/go-connections v0.8.1/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-connections v0.8.1/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= 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/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 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= 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.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 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 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= 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= 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 h1:wkfn7vOlUBu8ivAWKBWisTiwJK4jYHzTF8Ndv1LyGqY=
github.com/go-git/go-git/v5 v5.19.2/go.mod h1:QqCBE1EFN5ddFmrliLQ3/ntRCUjZU3EJuwuB/jWEHjk= 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.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.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 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 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 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= 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/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 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY=
github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= 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.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 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.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/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 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 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.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 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 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= 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.28 h1:rPyg2ybwEKPebvpzVWe1gKBkH8EQFkxO4Y0hjBeLaBU=
github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.28/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.14 h1:yUKzIgsCnosndOASY6/enly1EAuaXeFSQ7cdyA3OuYg=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= 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 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= 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.3 h1:OxxR9paxsluYi+zDUEXTTaIxtkK3viymW+Ka7vRhhME=
github.com/moby/go-archive v0.3.2/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= 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 h1:2/sexvQyqIWS8pRSCFddBfpW2qE7vR7FCL+vN8pxwMc=
github.com/moby/moby/api v1.55.0/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= 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 h1:tYNaJno4c0HXz12y5BiqEDy0rVTYkWzI26lGvnTMiJw=
github.com/moby/moby/client v0.5.1/go.mod h1:odLstlZ6uSnfvAgVxMpvgmb8SUdd+siH2T0GBuxVAlM= 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 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U=
github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= 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 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8=
github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o= 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 h1:RgjRlaDKi/Xmyrz4t8lyzXT6v2ooFeO/7xtchmhVWE0=
github.com/moby/sys/user v0.4.1/go.mod h1:E9QsW5WRe1kUAf7kW8hXKwu1uhsZEAdPLYHYSDudF4Y= 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.2.0 h1:nEtDtp7NCV/6dutSklNe8FrENPwFdc4mXnZqC/JWgXM=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= 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 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= 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/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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/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 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= 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 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 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.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= 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 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg=
github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= 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.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.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.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 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 h1:zjNCuOOhh1TKRU0Ru3PPPJt80z7eReswCao91gBLk00=
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928/go.mod h1:PCFYfAEfKT+Nd6zWvUpsXduMR1bXFLf0uGSlEF05MCI= 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= 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.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 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= 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.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= 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 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 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 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= 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.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 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= 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.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= 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 h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM=
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= 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.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.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= 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 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= 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= 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 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= 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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= 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= 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.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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 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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+8 -6
View File
@@ -54,15 +54,16 @@ func runDaemon(ctx context.Context, daemArgs *daemonArgs, configFile *string) fu
// processes with the same identity are indistinguishable to Gitea and // processes with the same identity are indistinguishable to Gitea and
// end up cancelling each other's jobs. // end up cancelling each other's jobs.
releaseLock, err := lock.TryLock(cfg.Runner.File) 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) 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 return err
} else if err != nil { case err != nil:
// Best-effort guard: if the lock file can't be created (e.g. a // 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 // read-only runner-file mount), warn and start anyway rather than
// refusing to run. // refusing to run.
log.Warnf("could not lock runner file %q, continuing without the single-process guard: %v", cfg.Runner.File, err) 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 // Held until shutdown finishes: the draining runner still owns this
// identity on the server, so releasing early would let a restart // identity on the server, so releasing early would let a restart
// reintroduce the duplicate-identity job cancellations. // 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 // declare the labels of the runner before fetching tasks
resp, err := runner.Declare(ctx, ls.Names()) 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") log.Errorf("Your Gitea version is too old to support runner declare, please upgrade to v1.21 or later")
return err return err
} else if err != nil { case err != nil:
log.WithError(err).Error("fail to invoke Declare") log.WithError(err).Error("fail to invoke Declare")
return err return err
} else { default:
log.Infof("runner: %s, with version: %s, with labels: %v, declare successfully", log.Infof("runner: %s, with version: %s, with labels: %v, declare successfully",
resp.Msg.Runner.Name, resp.Msg.Runner.Version, resp.Msg.Runner.Labels) resp.Msg.Runner.Name, resp.Msg.Runner.Version, resp.Msg.Runner.Labels)
} }
+9 -7
View File
@@ -303,19 +303,20 @@ func runExecList(planner model.WorkflowPlanner, execArgs *executeArgs) error {
} }
var err error var err error
if execArgs.job != "" { switch {
case execArgs.job != "":
log.Infof("Preparing plan with a job: %s", execArgs.job) log.Infof("Preparing plan with a job: %s", execArgs.job)
filterPlan, err = planner.PlanJob(execArgs.job) filterPlan, err = planner.PlanJob(execArgs.job)
if err != nil { if err != nil {
return err return err
} }
} else if filterEventName != "" { case filterEventName != "":
log.Infof("Preparing plan for a event: %s", filterEventName) log.Infof("Preparing plan for a event: %s", filterEventName)
filterPlan, err = planner.PlanEvent(filterEventName) filterPlan, err = planner.PlanEvent(filterEventName)
if err != nil { if err != nil {
return err return err
} }
} else { default:
log.Infof("Preparing plan with all jobs") log.Infof("Preparing plan with all jobs")
filterPlan, err = planner.PlanAll() filterPlan, err = planner.PlanAll()
if err != nil { if err != nil {
@@ -348,18 +349,19 @@ func runExec(ctx context.Context, execArgs *executeArgs) func(cmd *cobra.Command
// collect all events from loaded workflows // collect all events from loaded workflows
events := planner.GetEvents() events := planner.GetEvents()
if len(execArgs.event) > 0 { switch {
case len(execArgs.event) > 0:
log.Infof("Using chosed event for filtering: %s", execArgs.event) log.Infof("Using chosed event for filtering: %s", execArgs.event)
eventName = 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]) log.Infof("Using the only detected workflow event: %s", events[0])
eventName = 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 // set default event type to first event from many available
// this way user dont have to specify the event. // this way user dont have to specify the event.
log.Infof("Using first detected workflow event: %s", events[0]) log.Infof("Using first detected workflow event: %s", events[0])
eventName = events[0] eventName = events[0]
} else { default:
log.Infof("Using default workflow event: push") log.Infof("Using default workflow event: push")
eventName = "push" eventName = "push"
} }
+6 -5
View File
@@ -276,7 +276,7 @@ func registerInteractive(ctx context.Context, configFile string, regArgs *regist
if stage == StageWaitingForRegistration { if stage == StageWaitingForRegistration {
log.Infof("Registering runner, name=%s, instance=%s, labels=%v.", inputs.RunnerName, inputs.InstanceAddr, inputs.Labels) log.Infof("Registering runner, name=%s, instance=%s, labels=%v.", inputs.RunnerName, inputs.InstanceAddr, inputs.Labels)
if err := doRegister(ctx, cfg, inputs); err != nil { 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.") log.Infof("Runner registered successfully.")
return nil return nil
@@ -340,7 +340,7 @@ func registerNoInteractive(ctx context.Context, configFile string, regArgs *regi
return err return err
} }
if err := doRegister(ctx, cfg, inputs); err != nil { 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.") log.Infof("Runner registered successfully.")
return nil 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 { func doRegister(ctx context.Context, cfg *config.Config, inputs *registerInputs) error {
// Refuse to rewrite the runner file while another process is using it. // Refuse to rewrite the runner file while another process is using it.
releaseLock, err := lock.TryLock(cfg.Runner.File) 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) 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 // Best-effort guard: if the lock file can't be created, warn and
// register anyway; writing the runner file will surface any real // register anyway; writing the runner file will surface any real
// permission problem with a clearer error. // 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) log.Warnf("could not lock runner file %q, continuing without the single-process guard: %v", cfg.Runner.File, err)
} else { default:
defer func() { _ = releaseLock() }() defer func() { _ = releaseLock() }()
} }
+1 -2
View File
@@ -87,8 +87,7 @@ func executeHealthCheck(ctx context.Context, script string, timeout time.Duratio
if err == nil { if err == nil {
return nil return nil
} }
var exitErr *exec.ExitError if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
if errors.As(err, &exitErr) {
return fmt.Errorf("exited with code %d", exitErr.ExitCode()) return fmt.Errorf("exited with code %d", exitErr.ExitCode())
} }
return err return err
+1 -2
View File
@@ -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) log.Warnf("post-task script %q for task %d: %v", script, task.Id, err)
return return
} }
var exitErr *exec.ExitError if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
if errors.As(err, &exitErr) {
log.Warnf("post-task script %q for task %d exited with code %d", script, task.Id, exitErr.ExitCode()) log.Warnf("post-task script %q for task %d exited with code %d", script, task.Id, exitErr.ExitCode())
return return
} }
+2 -2
View File
@@ -6,7 +6,7 @@ package run
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json/v2"
"errors" "errors"
"fmt" "fmt"
"maps" "maps"
@@ -676,7 +676,7 @@ func postInternalCache(url, secret string, body map[string]any) (map[string]any,
} }
answer := 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. // 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 return answer, nil
} }
+2 -2
View File
@@ -5,7 +5,7 @@ package run
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json/v2"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@@ -152,7 +152,7 @@ func TestRunner_CacheFullFlow_MatchesToolkit(t *testing.T) {
func decodeJSON(resp *http.Response, v any) error { func decodeJSON(resp *http.Response, v any) error {
defer resp.Body.Close() 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 → // End-to-end against a remote cache-server: token unknown → 401, register →
+8 -5
View File
@@ -4,7 +4,8 @@
package config package config
import ( import (
"encoding/json" "encoding/json/jsontext"
"encoding/json/v2"
"os" "os"
) )
@@ -31,7 +32,7 @@ func LoadRegistration(file string) (*Registration, error) {
defer f.Close() defer f.Close()
var reg Registration var reg Registration
if err := json.NewDecoder(f).Decode(&reg); err != nil { if err := json.UnmarshalRead(f, &reg); err != nil {
return nil, err return nil, err
} }
@@ -49,7 +50,9 @@ func SaveRegistration(file string, reg *Registration) error {
reg.Warning = registrationWarning reg.Warning = registrationWarning
enc := json.NewEncoder(f) if err := json.MarshalWrite(f, reg, jsontext.WithIndent(" ")); err != nil {
enc.SetIndent("", " ") return err
return enc.Encode(reg) }
_, err = f.WriteString("\n")
return err
} }