From 50bfec157b827091d0bbc12f023598000634ee4e Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 9 Jun 2025 15:48:30 +0800 Subject: [PATCH 1/7] Bump golangci/golangci-lint-action from 6 to 8 --- .github/workflows/build.yml | 2 +- .github/workflows/static.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c160c7a..c3ac286 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: cache: false - name: Lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v8 CodeQL: needs: Lint diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 2e5dca7..7e60836 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -25,7 +25,7 @@ jobs: cache: false - name: Lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v8 CodeQL: needs: Lint From bc40a422ad376c45dc292318878e102ef61a4dbb Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 9 Jun 2025 15:48:32 +0800 Subject: [PATCH 2/7] Ignore lint error check warning --- g/reflect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g/reflect.go b/g/reflect.go index 264f6e5..e02bf60 100644 --- a/g/reflect.go +++ b/g/reflect.go @@ -75,7 +75,7 @@ func typeByString(str string) reflect.Type { h := int(uint(i+j) >> 1) // avoid overflow when computing h // i ≤ h < j face.data = resolveTypeOff(section, offs[h]) - if !(typ.String() >= s) { + if !(typ.String() >= s) { //nolint:staticcheck i = h + 1 // preserves f(i-1) == false } else { j = h // preserves f(j) == true From 75d3d46e44511a0ed962eb23bec1cf9f402124a4 Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 9 Jun 2025 15:48:34 +0800 Subject: [PATCH 3/7] Refactor FileTracker to use os.File directly instead of pointer --- api_routine_test.go | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/api_routine_test.go b/api_routine_test.go index 8244cbc..d9453b0 100644 --- a/api_routine_test.go +++ b/api_routine_test.go @@ -137,7 +137,7 @@ func TestWrapTask_HasContext(t *testing.T) { } func TestWrapTask_Complete_ThenFail(t *testing.T) { - tracker := NewFileTracker(&os.Stdout) + tracker := NewFileTracker(os.Stdout) tracker.Begin() defer tracker.End() // @@ -343,7 +343,7 @@ func TestWrapWaitTask_HasContext_Cancel(t *testing.T) { } func TestWrapWaitTask_Complete_ThenFail(t *testing.T) { - tracker := NewFileTracker(&os.Stdout) + tracker := NewFileTracker(os.Stdout) tracker.Begin() defer tracker.End() // @@ -553,7 +553,7 @@ func TestWrapWaitResultTask_HasContext_Cancel(t *testing.T) { } func TestWrapWaitResultTask_Complete_ThenFail(t *testing.T) { - tracker := NewFileTracker(&os.Stdout) + tracker := NewFileTracker(os.Stdout) tracker.Begin() defer tracker.End() // @@ -587,7 +587,7 @@ func TestWrapWaitResultTask_Complete_ThenFail(t *testing.T) { } func TestGo_Error(t *testing.T) { - tracker := NewFileTracker(&os.Stdout) + tracker := NewFileTracker(os.Stdout) tracker.Begin() defer tracker.End() // @@ -927,12 +927,12 @@ func TestGoWaitResult_Cross(t *testing.T) { //=== type FileTracker struct { - target **os.File - oldValue *os.File - tempValue *os.File + target *os.File + oldValue os.File + tempValue os.File } -func NewFileTracker(target **os.File) *FileTracker { +func NewFileTracker(target *os.File) *FileTracker { return &FileTracker{target: target, oldValue: *target} } @@ -941,8 +941,8 @@ func (f *FileTracker) Begin() { if err != nil { panic(err) } - *f.target = file - f.tempValue = file + *f.target = *file + f.tempValue = *file } func (f *FileTracker) End() { @@ -959,7 +959,7 @@ func (f *FileTracker) Value() string { if _, err := f.tempValue.Seek(0, io.SeekStart); err != nil { panic(err) } - buff, err := io.ReadAll(f.tempValue) + buff, err := io.ReadAll(&f.tempValue) if err != nil { panic(err) } @@ -968,10 +968,22 @@ func (f *FileTracker) Value() string { func TestFileTracker(t *testing.T) { origin := os.Stdout - tracker := NewFileTracker(&os.Stdout) + tracker := NewFileTracker(os.Stdout) tracker.Begin() - fmt.Println("hello world") + _, _ = fmt.Fprintln(os.Stdout, "hello world") assert.Equal(t, "hello world\n", tracker.Value()) tracker.End() + assert.Equal(t, "/dev/stdout", origin.Name()) + assert.Same(t, origin, os.Stdout) +} + +func TestFileTrackerRef(t *testing.T) { + origin := os.Stdout + tracker := NewFileTracker(os.Stdout) + tracker.Begin() + _, _ = fmt.Fprintln(origin, "hello world") + assert.Equal(t, "hello world\n", tracker.Value()) + tracker.End() + assert.Equal(t, "/dev/stdout", origin.Name()) assert.Same(t, origin, os.Stdout) } From 162a7282fc3d525d6bd7710bea9ca3caa8d63abc Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 11 Aug 2025 15:15:17 +0800 Subject: [PATCH 4/7] Modify continuous integration script remove retired runner --- .github/workflows/build.yml | 11 ++++++++--- .github/workflows/static.yml | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c3ac286..f3f37ce 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -191,9 +191,6 @@ jobs: runs-on: ubuntu-latest - os: windows runs-on: windows-latest - - os: windows - go: 1.18 - runs-on: windows-2019 - os: freebsd runs-on: ubuntu-latest - os: js @@ -300,6 +297,14 @@ jobs: GOARCH: ${{ matrix.arch }} run: go test -v -coverprofile='coverage.txt' -covermode=atomic ./... + - name: 'Downgrade gcc for go1.18 on [windows] arch [amd64]' + if: ${{ matrix.os == 'windows' && contains(fromJson('["amd64"]'), matrix.arch) && matrix.go == '1.18' }} + run: | + Invoke-WebRequest -Uri 'https://jaist.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-win32/sjlj/x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.7z?viasf=1' -OutFile gcc8.7z + Remove-Item 'C:\mingw64' -Recurse -Force + 7z x gcc8.7z -oC:\ -y + gcc --version + - name: 'Test on [windows] arch [amd64]' if: ${{ matrix.os == 'windows' && contains(fromJson('["amd64"]'), matrix.arch) }} env: diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 7e60836..4125998 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -191,9 +191,6 @@ jobs: runs-on: ubuntu-latest - os: windows runs-on: windows-latest - - os: windows - go: 1.18 - runs-on: windows-2019 - os: freebsd runs-on: ubuntu-latest - os: js @@ -304,6 +301,14 @@ jobs: GOARCH: ${{ matrix.arch }} run: go test -v -coverprofile='coverage.txt' -covermode=atomic -a -toolexec='routinex -v' ./... + - name: 'Downgrade gcc for go1.18 on [windows] arch [amd64]' + if: ${{ matrix.os == 'windows' && contains(fromJson('["amd64"]'), matrix.arch) && matrix.go == '1.18' }} + run: | + Invoke-WebRequest -Uri 'https://jaist.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-win32/sjlj/x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.7z?viasf=1' -OutFile gcc8.7z + Remove-Item 'C:\mingw64' -Recurse -Force + 7z x gcc8.7z -oC:\ -y + gcc --version + - name: 'Test on [windows] arch [amd64]' if: ${{ matrix.os == 'windows' && contains(fromJson('["amd64"]'), matrix.arch) }} env: From 83229b5f7b8696b3bb1c6b5de516d6679cf18c5d Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 11 Aug 2025 15:15:19 +0800 Subject: [PATCH 5/7] Refactor inherited task handling and add restoreInheritedMap function --- api_routine_test.go | 22 +++--------- routine.go | 75 ++++++---------------------------------- thread_local_map.go | 31 +++++++++++++++++ thread_local_map_test.go | 74 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 81 deletions(-) diff --git a/api_routine_test.go b/api_routine_test.go index d9453b0..b9ebc1d 100644 --- a/api_routine_test.go +++ b/api_routine_test.go @@ -617,11 +617,7 @@ func TestGo_Error(t *testing.T) { // line = lines[2] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.inheritedTask.run()")) - if routinexEnabled { - assert.True(t, strings.HasSuffix(line, "routine.go:53")) - } else { - assert.True(t, strings.HasSuffix(line, "routine.go:45")) - } + assert.True(t, strings.HasSuffix(line, "routine.go:24")) // line = lines[3] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.(*futureTask[...]).Run()")) @@ -727,15 +723,11 @@ func TestGoWait_Error(t *testing.T) { // line = lines[1] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.TestGoWait_Error.")) - assert.True(t, strings.HasSuffix(line, "api_routine_test.go:710")) + assert.True(t, strings.HasSuffix(line, "api_routine_test.go:706")) // line = lines[2] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.inheritedWaitTask.run()")) - if routinexEnabled { - assert.True(t, strings.HasSuffix(line, "routine.go:85")) - } else { - assert.True(t, strings.HasSuffix(line, "routine.go:77")) - } + assert.True(t, strings.HasSuffix(line, "routine.go:44")) // line = lines[3] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.(*futureTask[...]).Run()")) @@ -833,15 +825,11 @@ func TestGoWaitResult_Error(t *testing.T) { // line = lines[1] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.TestGoWaitResult_Error.")) - assert.True(t, strings.HasSuffix(line, "api_routine_test.go:814")) + assert.True(t, strings.HasSuffix(line, "api_routine_test.go:806")) // line = lines[2] assert.True(t, strings.HasPrefix(line, " at github.com/timandy/routine.inheritedWaitResultTask[...].run()")) - if routinexEnabled { - assert.True(t, strings.HasSuffix(line, "routine.go:116")) - } else { - assert.True(t, strings.HasSuffix(line, "routine.go:109")) - } + assert.True(t, strings.HasSuffix(line, "routine.go:64")) // lineOffset := 0 if len(lines) == 7 { diff --git a/routine.go b/routine.go index c43c5eb..39e58f8 100644 --- a/routine.go +++ b/routine.go @@ -2,26 +2,7 @@ package routine import "fmt" -type inherited struct { -} - -//go:norace -func (inherited) reset() { - t := currentThread(false) - if t != nil { - t.threadLocals = nil - t.inheritableThreadLocals = nil - } -} - -//go:norace -func (inherited) restore(t *thread, threadLocalsBackup, inheritableThreadLocalsBackup *threadLocalMap) { - t.threadLocals = threadLocalsBackup - t.inheritableThreadLocals = inheritableThreadLocalsBackup -} - type inheritedTask struct { - inherited context *threadLocalMap function Runnable } @@ -38,25 +19,13 @@ func (it inheritedTask) run(task FutureTask[any]) any { } }() // restore - t := currentThread(it.context != nil) - if t == nil { - //copied is nil - defer it.reset() - it.function() - return nil - } else { - threadLocalsBackup := t.threadLocals - inheritableThreadLocalsBackup := t.inheritableThreadLocals - defer it.restore(t, threadLocalsBackup, inheritableThreadLocalsBackup) - t.threadLocals = nil - t.inheritableThreadLocals = it.context - it.function() - return nil - } + defer restoreInheritedMap(it.context)() + // exec + it.function() + return nil } type inheritedWaitTask struct { - inherited context *threadLocalMap function CancelRunnable } @@ -70,25 +39,13 @@ func (iwt inheritedWaitTask) run(task FutureTask[any]) any { } }() // restore - t := currentThread(iwt.context != nil) - if t == nil { - //copied is nil - defer iwt.reset() - iwt.function(task) - return nil - } else { - threadLocalsBackup := t.threadLocals - inheritableThreadLocalsBackup := t.inheritableThreadLocals - defer iwt.restore(t, threadLocalsBackup, inheritableThreadLocalsBackup) - t.threadLocals = nil - t.inheritableThreadLocals = iwt.context - iwt.function(task) - return nil - } + defer restoreInheritedMap(iwt.context)() + // exec + iwt.function(task) + return nil } type inheritedWaitResultTask[TResult any] struct { - inherited context *threadLocalMap function CancelCallable[TResult] } @@ -102,17 +59,7 @@ func (iwrt inheritedWaitResultTask[TResult]) run(task FutureTask[TResult]) TResu } }() // restore - t := currentThread(iwrt.context != nil) - if t == nil { - //copied is nil - defer iwrt.reset() - return iwrt.function(task) - } else { - threadLocalsBackup := t.threadLocals - inheritableThreadLocalsBackup := t.inheritableThreadLocals - defer iwrt.restore(t, threadLocalsBackup, inheritableThreadLocalsBackup) - t.threadLocals = nil - t.inheritableThreadLocals = iwrt.context - return iwrt.function(task) - } + defer restoreInheritedMap(iwrt.context)() + // exec + return iwrt.function(task) } diff --git a/thread_local_map.go b/thread_local_map.go index e61dbf0..0ecb97f 100644 --- a/thread_local_map.go +++ b/thread_local_map.go @@ -76,6 +76,37 @@ func createInheritedMap() *threadLocalMap { return &threadLocalMap{table: table} } +//go:norace +func restoreInheritedMap(mp *threadLocalMap) func() { + t := currentThread(mp != nil) + if t == nil { + // mp and t are nil + return clearThread + } + threadLocalsBackup := t.threadLocals + inheritableThreadLocalsBackup := t.inheritableThreadLocals + t.threadLocals = nil + t.inheritableThreadLocals = mp + return func() { + resetThread(t, threadLocalsBackup, inheritableThreadLocalsBackup) + } +} + +//go:norace +func clearThread() { + t := currentThread(false) + if t != nil { + t.threadLocals = nil + t.inheritableThreadLocals = nil + } +} + +//go:norace +func resetThread(t *thread, threadLocals, inheritableThreadLocals *threadLocalMap) { + t.threadLocals = threadLocals + t.inheritableThreadLocals = inheritableThreadLocals +} + func fill[T any](a []T, fromIndex int, toIndex int, val T) { for i := fromIndex; i < toIndex; i++ { a[i] = val diff --git a/thread_local_map_test.go b/thread_local_map_test.go index 7dc7197..30becdf 100644 --- a/thread_local_map_test.go +++ b/thread_local_map_test.go @@ -144,6 +144,80 @@ func TestCreateInheritedMap_Cloneable(t *testing.T) { assert.Equal(t, *value, *getValue2) } +func TestRestoreInheritedMap(t *testing.T) { + tls := NewInheritableThreadLocal[*personCloneable]() + value := &personCloneable{Id: 1, Name: "Hello"} + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + mp := createInheritedMap() + assert.Nil(t, mp) + // + go func() { + defer func() { + if routinexEnabled { + assert.NotNil(t, currentThread(false)) + } else { + assert.Nil(t, currentThread(false)) + } + assert.Nil(t, tls.Get()) + wg.Done() + }() + defer restoreInheritedMap(mp)() + }() + wg.Done() + }() + wg.Wait() + // + wg2 := sync.WaitGroup{} + wg2.Add(2) + go func() { + mp := createInheritedMap() + assert.Nil(t, mp) + // + go func() { + defer func() { + assert.NotNil(t, currentThread(false)) + assert.Nil(t, tls.Get()) + wg2.Done() + }() + defer restoreInheritedMap(mp)() + tls.Set(value) + assert.Same(t, value, tls.Get()) + }() + wg2.Done() + }() + wg2.Wait() + // + value2 := &personCloneable{Id: 2, Name: "World"} + wg3 := sync.WaitGroup{} + wg3.Add(2) + go func() { + tls.Set(value) + assert.Same(t, value, tls.Get()) + mp := createInheritedMap() + assert.NotNil(t, mp) + // + go func() { + defer func() { + assert.NotNil(t, currentThread(false)) + assert.Same(t, value2, tls.Get()) + wg3.Done() + }() + tls.Set(value2) + assert.Same(t, value2, tls.Get()) + defer restoreInheritedMap(mp)() + result := tls.Get() + assert.NotNil(t, result) + assert.NotSame(t, value, result) + assert.NotSame(t, value2, result) + assert.Equal(t, *value, *result) + }() + wg3.Done() + }() + wg3.Wait() +} + func TestFill(t *testing.T) { a := make([]entry, 6) fill(a, 4, 5, unset) From 44f4d17359a02c1c7ca6c03e641ef46a9ff2aa9d Mon Sep 17 00:00:00 2001 From: TimAndy Date: Mon, 11 Aug 2025 16:44:37 +0800 Subject: [PATCH 6/7] Add linkname directives for createInheritedMap and restoreInheritedMap functions --- thread_local_map.go | 4 ++ thread_local_map_test.go | 81 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/thread_local_map.go b/thread_local_map.go index 0ecb97f..0d4078c 100644 --- a/thread_local_map.go +++ b/thread_local_map.go @@ -1,5 +1,7 @@ package routine +import _ "unsafe" + var unset entry = &object{} type object struct { @@ -53,6 +55,7 @@ func (mp *threadLocalMap) expandAndSet(index int, value entry) { } //go:norace +//go:linkname createInheritedMap routine.createInheritedMap func createInheritedMap() *threadLocalMap { parent := currentThread(false) if parent == nil { @@ -77,6 +80,7 @@ func createInheritedMap() *threadLocalMap { } //go:norace +//go:linkname restoreInheritedMap routine.restoreInheritedMap func restoreInheritedMap(mp *threadLocalMap) func() { t := currentThread(mp != nil) if t == nil { diff --git a/thread_local_map_test.go b/thread_local_map_test.go index 30becdf..775f29c 100644 --- a/thread_local_map_test.go +++ b/thread_local_map_test.go @@ -4,10 +4,17 @@ import ( "math/rand" "sync" "testing" + "unsafe" "github.com/stretchr/testify/assert" ) +//go:linkname createInheritedMapExport routine.createInheritedMap +func createInheritedMapExport() unsafe.Pointer + +//go:linkname restoreInheritedMapExport routine.restoreInheritedMap +func restoreInheritedMapExport(mp unsafe.Pointer) func() + func TestObject(t *testing.T) { var value entry = &object{} assert.NotSame(t, unset, value) @@ -218,6 +225,80 @@ func TestRestoreInheritedMap(t *testing.T) { wg3.Wait() } +func TestRestoreInheritedMap_Export(t *testing.T) { + tls := NewInheritableThreadLocal[*personCloneable]() + value := &personCloneable{Id: 1, Name: "Hello"} + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + mp := createInheritedMapExport() + assert.Nil(t, mp) + // + go func() { + defer func() { + if routinexEnabled { + assert.NotNil(t, currentThread(false)) + } else { + assert.Nil(t, currentThread(false)) + } + assert.Nil(t, tls.Get()) + wg.Done() + }() + defer restoreInheritedMapExport(mp)() + }() + wg.Done() + }() + wg.Wait() + // + wg2 := sync.WaitGroup{} + wg2.Add(2) + go func() { + mp := createInheritedMapExport() + assert.Nil(t, mp) + // + go func() { + defer func() { + assert.NotNil(t, currentThread(false)) + assert.Nil(t, tls.Get()) + wg2.Done() + }() + defer restoreInheritedMapExport(mp)() + tls.Set(value) + assert.Same(t, value, tls.Get()) + }() + wg2.Done() + }() + wg2.Wait() + // + value2 := &personCloneable{Id: 2, Name: "World"} + wg3 := sync.WaitGroup{} + wg3.Add(2) + go func() { + tls.Set(value) + assert.Same(t, value, tls.Get()) + mp := createInheritedMapExport() + assert.NotNil(t, mp) + // + go func() { + defer func() { + assert.NotNil(t, currentThread(false)) + assert.Same(t, value2, tls.Get()) + wg3.Done() + }() + tls.Set(value2) + assert.Same(t, value2, tls.Get()) + defer restoreInheritedMapExport(mp)() + result := tls.Get() + assert.NotNil(t, result) + assert.NotSame(t, value, result) + assert.NotSame(t, value2, result) + assert.Equal(t, *value, *result) + }() + wg3.Done() + }() + wg3.Wait() +} + func TestFill(t *testing.T) { a := make([]entry, 6) fill(a, 4, 5, unset) From dc631602f1d0e62b8b7c7d2fdd81812cb35a2991 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 08:34:10 +0000 Subject: [PATCH 7/7] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 6 +++--- .github/workflows/static.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3f37ce..e9440f6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 @@ -198,7 +198,7 @@ jobs: steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 4125998..757646c 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5 @@ -198,7 +198,7 @@ jobs: steps: - name: Checkout scm - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Go uses: actions/setup-go@v5