Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package forgejo-runner for openSUSE:Factory 
checked in at 2026-04-10 17:52:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/forgejo-runner (Old)
 and      /work/SRC/openSUSE:Factory/.forgejo-runner.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "forgejo-runner"

Fri Apr 10 17:52:52 2026 rev:44 rq:1345680 version:12.8.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/forgejo-runner/forgejo-runner.changes    
2026-04-08 17:15:13.678681485 +0200
+++ /work/SRC/openSUSE:Factory/.forgejo-runner.new.21863/forgejo-runner.changes 
2026-04-10 18:02:04.036270795 +0200
@@ -1,0 +2,6 @@
+Thu Apr  9 19:05:39 UTC 2026 - Richard Rahl <[email protected]>
+
+- Update to version 12.8.2:
+  * fix: return error when one-job receives no task
+
+-------------------------------------------------------------------

Old:
----
  forgejo-runner-12.8.1.obscpio

New:
----
  forgejo-runner-12.8.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ forgejo-runner.spec ++++++
--- /var/tmp/diff_new_pack.0sIe14/_old  2026-04-10 18:02:05.228319876 +0200
+++ /var/tmp/diff_new_pack.0sIe14/_new  2026-04-10 18:02:05.232320042 +0200
@@ -18,7 +18,7 @@
 
 %define services %{name}.service
 Name:           forgejo-runner
-Version:        12.8.1
+Version:        12.8.2
 Release:        0
 Summary:        Daemon that connects to a Forgejo instance and runs CI jobs
 License:        GPL-3.0-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.0sIe14/_old  2026-04-10 18:02:05.284322183 +0200
+++ /var/tmp/diff_new_pack.0sIe14/_new  2026-04-10 18:02:05.292322512 +0200
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://code.forgejo.org/forgejo/runner</param>
     <param name="scm">git</param>
-    <param name="revision">refs/tags/v12.8.1</param>
+    <param name="revision">refs/tags/v12.8.2</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">disable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ forgejo-runner-12.8.1.obscpio -> forgejo-runner-12.8.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forgejo-runner-12.8.1/internal/app/cmd/cmd.go 
new/forgejo-runner-12.8.2/internal/app/cmd/cmd.go
--- old/forgejo-runner-12.8.1/internal/app/cmd/cmd.go   2026-04-06 
19:20:18.000000000 +0200
+++ new/forgejo-runner-12.8.2/internal/app/cmd/cmd.go   2026-04-07 
17:51:41.000000000 +0200
@@ -5,9 +5,11 @@
 
 import (
        "context"
+       "errors"
        "fmt"
        "os"
 
+       "code.forgejo.org/forgejo/runner/v12/internal/app/poll"
        "github.com/spf13/cobra"
 
        "code.forgejo.org/forgejo/runner/v12/internal/pkg/config"
@@ -106,6 +108,10 @@
        rootCmd.CompletionOptions.HiddenDefaultCmd = true
 
        if err := rootCmd.Execute(); err != nil {
+               if errors.Is(err, poll.ErrNoTaskReceived) {
+                       os.Exit(2)
+               }
+
                os.Exit(1)
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forgejo-runner-12.8.1/internal/app/cmd/job.go 
new/forgejo-runner-12.8.2/internal/app/cmd/job.go
--- old/forgejo-runner-12.8.1/internal/app/cmd/job.go   2026-04-06 
19:20:18.000000000 +0200
+++ new/forgejo-runner-12.8.2/internal/app/cmd/job.go   2026-04-07 
17:51:41.000000000 +0200
@@ -89,6 +89,11 @@
        }
 
        poller := newSingleTaskPoller(ctx, cfg, client, runner, args.wait, 
args.GetHandle())
-       poller.Poll()
-       return poller.Shutdown(ctx)
+       err = poller.Poll()
+       if shutdownErr := poller.Shutdown(ctx); shutdownErr != nil {
+               // If the shutdown error was returned, then context 
cancellation or a timeout would result in an exit code that
+               // indicates an error.
+               log.Warnf("error during poller shutdown: %s", shutdownErr)
+       }
+       return err
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forgejo-runner-12.8.1/internal/app/cmd/job_test.go 
new/forgejo-runner-12.8.2/internal/app/cmd/job_test.go
--- old/forgejo-runner-12.8.1/internal/app/cmd/job_test.go      2026-04-06 
19:20:18.000000000 +0200
+++ new/forgejo-runner-12.8.2/internal/app/cmd/job_test.go      2026-04-07 
17:51:41.000000000 +0200
@@ -12,6 +12,7 @@
 
        runnerv1 "code.forgejo.org/forgejo/actions-proto/runner/v1"
        "code.forgejo.org/forgejo/runner/v12/act/cacheproxy"
+       "code.forgejo.org/forgejo/runner/v12/internal/app/poll"
        "code.forgejo.org/forgejo/runner/v12/internal/app/run"
        mock_runner "code.forgejo.org/forgejo/runner/v12/internal/app/run/mocks"
        "code.forgejo.org/forgejo/runner/v12/internal/pkg/client"
@@ -82,7 +83,62 @@
                close(runJobCompleted)
        }()
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
+       // Wait for the goroutine that executes runJob() to stop.
+       <-runJobCompleted
+}
+
+func TestRunJob_ErrorWhenNoTaskReceived(t *testing.T) {
+       rawConfig := `
+cache:
+  enabled: false
+server:
+  connections:
+    example:
+      url: https://example.com/forgejo
+      uuid: 41414141-4141-4141-4141-414141414141
+      token: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+`
+
+       tempDir := t.TempDir()
+       configPath := filepath.Join(tempDir, "config.yaml")
+
+       err := os.WriteFile(configPath, []byte(rawConfig), 0o644)
+       require.NoError(t, err)
+
+       mockClient := mock_client.NewMockClient(t)
+       mockClient.
+               On("Address").Return("https://example.com/forgejo";).
+               On("SetRequestKey", mock.Anything).Return(func() {}).
+               On("FetchInterval").Return(time.Millisecond).
+               On("FetchTask", mock.Anything, 
connect.NewRequest(&runnerv1.FetchTaskRequest{})).
+               Return(connect.NewResponse(&runnerv1.FetchTaskResponse{Task: 
nil, TasksVersion: int64(1)}), nil)
+
+       mockRunner := mock_runner.NewMockRunner(t)
+
+       defer testutils.MockVariable(&initLogging, func(cfg *config.Config) 
{})()
+       defer testutils.MockVariable(&createClient, func(cfg *config.Config, 
conn *config.Connection) client.Client {
+               assert.Equal(t, "https://example.com/forgejo";, 
conn.URL.String())
+               assert.Equal(t, "41414141-4141-4141-4141-414141414141", 
conn.UUID.String())
+               assert.Equal(t, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 
conn.Token)
+
+               return mockClient
+       })()
+       defer testutils.MockVariable(&createRunner, func(ctx context.Context, 
name string, cfg *config.Config, cli client.Client, ls labels.Labels, 
cacheProxy *cacheproxy.Handler) (run.RunnerInterface, string, bool, error) {
+               if name == "example" {
+                       return mockRunner, "example", false, nil
+               }
+               t.Fatalf("unexpected connection name: %q", name)
+               return nil, "", false, nil
+       })()
+
+       runJobCompleted := make(chan any)
+       go func() {
+               err := runJob(t.Context(), &configPath, &runJobArgs{})
+               require.ErrorIs(t, err, poll.ErrNoTaskReceived)
+
+               // Signal that runJob() has completed.
+               close(runJobCompleted)
+       }()
 
        // Wait for the goroutine that executes runJob() to stop.
        <-runJobCompleted
@@ -152,8 +208,6 @@
                close(runJobCompleted)
        }()
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
-
        // Wait for the goroutine that executes runJob() to stop.
        <-runJobCompleted
 }
@@ -216,8 +270,6 @@
                close(runJobCompleted)
        }()
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
-
        // Wait for the goroutine that executes runJob() to stop.
        <-runJobCompleted
 }
@@ -280,8 +332,6 @@
                close(runJobCompleted)
        }()
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
-
        // Wait for the goroutine that executes runJob() to stop.
        <-runJobCompleted
 }
@@ -346,8 +396,6 @@
                close(runJobCompleted)
        }()
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
-
        // Wait for the goroutine that executes runJob() to stop.
        <-runJobCompleted
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/forgejo-runner-12.8.1/internal/app/poll/mocks/single.go 
new/forgejo-runner-12.8.2/internal/app/poll/mocks/single.go
--- old/forgejo-runner-12.8.1/internal/app/poll/mocks/single.go 1970-01-01 
01:00:00.000000000 +0100
+++ new/forgejo-runner-12.8.2/internal/app/poll/mocks/single.go 2026-04-07 
17:51:41.000000000 +0200
@@ -0,0 +1,134 @@
+// Code generated by mockery; DO NOT EDIT.
+// github.com/vektra/mockery
+// template: testify
+
+package mocks
+
+import (
+       "context"
+
+       mock "github.com/stretchr/testify/mock"
+)
+
+// NewMockSingleTaskPoller creates a new instance of MockSingleTaskPoller. It 
also registers a testing interface on the mock and a cleanup function to assert 
the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewMockSingleTaskPoller(t interface {
+       mock.TestingT
+       Cleanup(func())
+},
+) *MockSingleTaskPoller {
+       mock := &MockSingleTaskPoller{}
+       mock.Mock.Test(t)
+
+       t.Cleanup(func() { mock.AssertExpectations(t) })
+
+       return mock
+}
+
+// MockSingleTaskPoller is an autogenerated mock type for the SingleTaskPoller 
type
+type MockSingleTaskPoller struct {
+       mock.Mock
+}
+
+type MockSingleTaskPoller_Expecter struct {
+       mock *mock.Mock
+}
+
+func (_m *MockSingleTaskPoller) EXPECT() *MockSingleTaskPoller_Expecter {
+       return &MockSingleTaskPoller_Expecter{mock: &_m.Mock}
+}
+
+// Poll provides a mock function for the type MockSingleTaskPoller
+func (_mock *MockSingleTaskPoller) Poll() error {
+       ret := _mock.Called()
+
+       if len(ret) == 0 {
+               panic("no return value specified for Poll")
+       }
+
+       var r0 error
+       if returnFunc, ok := ret.Get(0).(func() error); ok {
+               r0 = returnFunc()
+       } else {
+               r0 = ret.Error(0)
+       }
+       return r0
+}
+
+// MockSingleTaskPoller_Poll_Call is a *mock.Call that shadows Run/Return 
methods with type explicit version for method 'Poll'
+type MockSingleTaskPoller_Poll_Call struct {
+       *mock.Call
+}
+
+// Poll is a helper method to define mock.On call
+func (_e *MockSingleTaskPoller_Expecter) Poll() 
*MockSingleTaskPoller_Poll_Call {
+       return &MockSingleTaskPoller_Poll_Call{Call: _e.mock.On("Poll")}
+}
+
+func (_c *MockSingleTaskPoller_Poll_Call) Run(run func()) 
*MockSingleTaskPoller_Poll_Call {
+       _c.Call.Run(func(args mock.Arguments) {
+               run()
+       })
+       return _c
+}
+
+func (_c *MockSingleTaskPoller_Poll_Call) Return(err error) 
*MockSingleTaskPoller_Poll_Call {
+       _c.Call.Return(err)
+       return _c
+}
+
+func (_c *MockSingleTaskPoller_Poll_Call) RunAndReturn(run func() error) 
*MockSingleTaskPoller_Poll_Call {
+       _c.Call.Return(run)
+       return _c
+}
+
+// Shutdown provides a mock function for the type MockSingleTaskPoller
+func (_mock *MockSingleTaskPoller) Shutdown(ctx context.Context) error {
+       ret := _mock.Called(ctx)
+
+       if len(ret) == 0 {
+               panic("no return value specified for Shutdown")
+       }
+
+       var r0 error
+       if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok {
+               r0 = returnFunc(ctx)
+       } else {
+               r0 = ret.Error(0)
+       }
+       return r0
+}
+
+// MockSingleTaskPoller_Shutdown_Call is a *mock.Call that shadows Run/Return 
methods with type explicit version for method 'Shutdown'
+type MockSingleTaskPoller_Shutdown_Call struct {
+       *mock.Call
+}
+
+// Shutdown is a helper method to define mock.On call
+//   - ctx context.Context
+func (_e *MockSingleTaskPoller_Expecter) Shutdown(ctx interface{}) 
*MockSingleTaskPoller_Shutdown_Call {
+       return &MockSingleTaskPoller_Shutdown_Call{Call: _e.mock.On("Shutdown", 
ctx)}
+}
+
+func (_c *MockSingleTaskPoller_Shutdown_Call) Run(run func(ctx 
context.Context)) *MockSingleTaskPoller_Shutdown_Call {
+       _c.Call.Run(func(args mock.Arguments) {
+               var arg0 context.Context
+               if args[0] != nil {
+                       arg0 = args[0].(context.Context)
+               }
+               run(
+                       arg0,
+               )
+       })
+       return _c
+}
+
+func (_c *MockSingleTaskPoller_Shutdown_Call) Return(err error) 
*MockSingleTaskPoller_Shutdown_Call {
+       _c.Call.Return(err)
+       return _c
+}
+
+func (_c *MockSingleTaskPoller_Shutdown_Call) RunAndReturn(run func(ctx 
context.Context) error) *MockSingleTaskPoller_Shutdown_Call {
+       _c.Call.Return(run)
+       return _c
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forgejo-runner-12.8.1/internal/app/poll/single.go 
new/forgejo-runner-12.8.2/internal/app/poll/single.go
--- old/forgejo-runner-12.8.1/internal/app/poll/single.go       2026-04-06 
19:20:18.000000000 +0200
+++ new/forgejo-runner-12.8.2/internal/app/poll/single.go       2026-04-07 
17:51:41.000000000 +0200
@@ -17,6 +17,17 @@
        "golang.org/x/time/rate"
 )
 
+// ErrNoTaskReceived signals that no task was received from the server.
+var ErrNoTaskReceived = errors.New("no task received")
+
+//mockery:generate: true
+//mockery:filename: mocks/single.go
+//mockery:pkgname: mocks
+type SingleTaskPoller interface {
+       Poll() error
+       Shutdown(ctx context.Context) error
+}
+
 type singleTaskPoller struct {
        client client.Client
        runner run.RunnerInterface
@@ -34,7 +45,7 @@
        handle *string
 }
 
-func NewSingleTaskPoller(ctx context.Context, cfg *config.Config, client 
client.Client, runner run.RunnerInterface, wait bool, handle *string) Poller {
+func NewSingleTaskPoller(ctx context.Context, cfg *config.Config, client 
client.Client, runner run.RunnerInterface, wait bool, handle *string) 
SingleTaskPoller {
        pollingCtx, cancelPolling := context.WithCancel(ctx)
        taskCtx, cancelTasks := context.WithCancel(ctx)
 
@@ -52,7 +63,7 @@
        }
 }
 
-func (s *singleTaskPoller) Poll() {
+func (s *singleTaskPoller) Poll() error {
        rateLimiter := rate.NewLimiter(rate.Every(s.client.FetchInterval()), 1)
 
        log.Info("single task poller launched")
@@ -77,7 +88,7 @@
                if err := rateLimiter.Wait(s.pollingCtx); err != nil {
                        log.Infof("single task poller is shutting down")
                        close(s.done)
-                       return
+                       return nil
                }
 
                log.Tracef("single task poller asking client %s for a task", 
s.client.Address())
@@ -100,11 +111,13 @@
                        continue
                }
 
+               var err error
                if task != nil {
                        log.Infof("single task poller successfully fetched one 
task from %s", s.client.Address())
                        s.runner.Run(s.taskCtx, task)
                } else {
-                       log.Infof("single task poller received no task from 
%s", s.client.Address())
+                       log.Debugf("single task poller received no task from 
%s", s.client.Address())
+                       err = ErrNoTaskReceived
                }
 
                log.Info("single task poller is shutting down")
@@ -113,7 +126,7 @@
                // Signal that the poller is done.
                close(s.done)
 
-               return
+               return err
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/forgejo-runner-12.8.1/internal/app/poll/single_test.go 
new/forgejo-runner-12.8.2/internal/app/poll/single_test.go
--- old/forgejo-runner-12.8.1/internal/app/poll/single_test.go  2026-04-06 
19:20:18.000000000 +0200
+++ new/forgejo-runner-12.8.2/internal/app/poll/single_test.go  2026-04-07 
17:51:41.000000000 +0200
@@ -13,6 +13,7 @@
        "code.forgejo.org/forgejo/runner/v12/internal/pkg/config"
        "connectrpc.com/connect"
        "github.com/stretchr/testify/mock"
+       "github.com/stretchr/testify/require"
 )
 
 func TestSingleTaskPoller_FetchesAvailableTask(t *testing.T) {
@@ -32,9 +33,26 @@
                Run(func(args mock.Arguments) {})
 
        taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, false, nil)
-       taskPoller.Poll()
+       err := taskPoller.Poll()
+       require.NoError(t, err)
+}
+
+func TestSingleTaskPoller_ReturnsErrorWhenNoTaskReceived(t *testing.T) {
+       cfg := &config.Config{}
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
+       mockClient := mock_client.NewMockClient(t)
+       mockClient.
+               On("Address").Return("https://example.com/forgejo";).
+               On("SetRequestKey", mock.Anything).Return(func() {}).
+               On("FetchInterval").Return(time.Millisecond).
+               On("FetchTask", mock.Anything, 
connect.NewRequest(&runnerv1.FetchTaskRequest{})).
+               Return(connect.NewResponse(&runnerv1.FetchTaskResponse{Task: 
nil, TasksVersion: int64(1)}), nil)
+
+       mockRunner := mock_runner.NewMockRunner(t)
+
+       taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, false, nil)
+       err := taskPoller.Poll()
+       require.ErrorIs(t, err, ErrNoTaskReceived)
 }
 
 func TestSingleTaskPoller_WaitsForAvailableTask(t *testing.T) {
@@ -56,9 +74,8 @@
                Run(func(args mock.Arguments) {})
 
        taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, true, nil)
-       taskPoller.Poll()
-
-       mockRunner.On("Run", mock.Anything, mock.Anything)
+       err := taskPoller.Poll()
+       require.NoError(t, err)
 }
 
 func TestSingleTaskPoller_FetchesRequestedTask(t *testing.T) {
@@ -80,9 +97,28 @@
                Run(func(args mock.Arguments) {})
 
        taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, false, &handle)
-       taskPoller.Poll()
+       err := taskPoller.Poll()
+       require.NoError(t, err)
+}
 
-       mockRunner.On("Run", mock.Anything, mock.Anything)
+func TestSingleTaskPoller_ReturnsErrorWhenRequestedTaskNotReceived(t 
*testing.T) {
+       cfg := &config.Config{}
+
+       handle := "fc0dbe3b-aca2-4ad7-9b7e-d8d7a15dfc42"
+
+       mockClient := mock_client.NewMockClient(t)
+       mockClient.
+               On("Address").Return("https://example.com/forgejo";).
+               On("SetRequestKey", mock.Anything).Return(func() {}).
+               On("FetchInterval").Return(time.Millisecond).
+               On("FetchSingleTask", mock.Anything, 
connect.NewRequest(&runnerv1.FetchSingleTaskRequest{Handle: &handle})).
+               
Return(connect.NewResponse(&runnerv1.FetchSingleTaskResponse{Task: nil, 
TasksVersion: int64(1)}), nil)
+
+       mockRunner := mock_runner.NewMockRunner(t)
+
+       taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, false, &handle)
+       err := taskPoller.Poll()
+       require.ErrorIs(t, err, ErrNoTaskReceived)
 }
 
 func TestSingleTaskPoller_WaitsForRequestedTask(t *testing.T) {
@@ -106,7 +142,6 @@
                Run(func(args mock.Arguments) {})
 
        taskPoller := NewSingleTaskPoller(t.Context(), cfg, mockClient, 
mockRunner, true, &handle)
-       taskPoller.Poll()
-
-       mockRunner.On("Run", mock.Anything, mock.Anything)
+       err := taskPoller.Poll()
+       require.NoError(t, err)
 }

++++++ forgejo-runner.obsinfo ++++++
--- /var/tmp/diff_new_pack.0sIe14/_old  2026-04-10 18:02:07.116397615 +0200
+++ /var/tmp/diff_new_pack.0sIe14/_new  2026-04-10 18:02:07.124397945 +0200
@@ -1,5 +1,5 @@
 name: forgejo-runner
-version: 12.8.1
-mtime: 1775496018
-commit: 9eb2ed865c2bef5f5c8a38191bde86b3645442dc
+version: 12.8.2
+mtime: 1775577101
+commit: 483dc418ecb029b3c0f05faefebac547847aa950
 

++++++ vendor.tar.gz ++++++

Reply via email to