Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openQA for openSUSE:Factory checked 
in at 2025-12-18 18:31:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openQA (Old)
 and      /work/SRC/openSUSE:Factory/.openQA.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openQA"

Thu Dec 18 18:31:53 2025 rev:787 rq:1323427 version:5.1766014013.377e64fe

Changes:
--------
--- /work/SRC/openSUSE:Factory/openQA/openQA.changes    2025-12-17 
17:38:40.345458661 +0100
+++ /work/SRC/openSUSE:Factory/.openQA.new.1928/openQA.changes  2025-12-18 
18:32:41.828751405 +0100
@@ -1,0 +2,7 @@
+Thu Dec 18 03:54:10 UTC 2025 - [email protected]
+
+- Update to version 5.1766014013.377e64fe:
+  * feat(Needle::Save): Adapt to new error handling
+  * feat(OpenQA::Git): Make error handling more flexible with exceptions
+
+-------------------------------------------------------------------

Old:
----
  openQA-5.1765887110.8fc02990.obscpio

New:
----
  openQA-5.1766014013.377e64fe.obscpio

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

Other differences:
------------------
++++++ openQA-client-test.spec ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:32:43.024801650 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:32:43.024801650 +0100
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-client
 Name:           %{short_name}-test
-Version:        5.1765887110.8fc02990
+Version:        5.1766014013.377e64fe
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-devel-test.spec ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:32:43.064803330 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:32:43.068803498 +0100
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-devel
 Name:           %{short_name}-test
-Version:        5.1765887110.8fc02990
+Version:        5.1766014013.377e64fe
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-test.spec ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:32:43.096804675 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:32:43.100804842 +0100
@@ -18,7 +18,7 @@
 
 %define         short_name openQA
 Name:           %{short_name}-test
-Version:        5.1765887110.8fc02990
+Version:        5.1766014013.377e64fe
 Release:        0
 Summary:        Test package for openQA
 License:        GPL-2.0-or-later

++++++ openQA-worker-test.spec ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:32:43.136806355 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:32:43.140806523 +0100
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-worker
 Name:           %{short_name}-test
-Version:        5.1765887110.8fc02990
+Version:        5.1766014013.377e64fe
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA.spec ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:32:43.176808035 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:32:43.176808035 +0100
@@ -99,7 +99,7 @@
 %define devel_requires %devel_no_selenium_requires chromedriver
 
 Name:           openQA
-Version:        5.1765887110.8fc02990
+Version:        5.1766014013.377e64fe
 Release:        0
 Summary:        The openQA web-frontend, scheduler and tools
 License:        GPL-2.0-or-later

++++++ openQA-5.1765887110.8fc02990.obscpio -> 
openQA-5.1766014013.377e64fe.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1765887110.8fc02990/lib/OpenQA/Error/Cmd.pm 
new/openQA-5.1766014013.377e64fe/lib/OpenQA/Error/Cmd.pm
--- old/openQA-5.1765887110.8fc02990/lib/OpenQA/Error/Cmd.pm    1970-01-01 
01:00:00.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/lib/OpenQA/Error/Cmd.pm    2025-12-18 
00:26:53.000000000 +0100
@@ -0,0 +1,16 @@
+# Copyright SUSE LLC
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+package OpenQA::Error::Cmd;
+
+use Mojo::Base -base, -signatures;
+
+has [qw(status return_code stdout stderr signal msg)];
+
+# Perl::Critic::Policy::Community::OverloadOptions
+# Automatically render error message in string context
+use overload '""' => \&to_string, bool => sub { 1 }, fallback => 1;
+
+sub to_string ($self, @) { (ref $self) . ': ' . $self->msg }
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1765887110.8fc02990/lib/OpenQA/Git.pm 
new/openQA-5.1766014013.377e64fe/lib/OpenQA/Git.pm
--- old/openQA-5.1765887110.8fc02990/lib/OpenQA/Git.pm  2025-12-16 
13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/lib/OpenQA/Git.pm  2025-12-18 
00:26:53.000000000 +0100
@@ -10,6 +10,8 @@
 use OpenQA::Utils qw(run_cmd_with_log_return_error run_cmd_with_log 
config_autocommit_enabled);
 use OpenQA::App;
 use Feature::Compat::Try;
+use OpenQA::Error::Cmd;
+use Carp qw(croak);
 
 has 'app';
 has 'dir';
@@ -45,9 +47,14 @@
         expected_return_codes => $options->{expected_return_codes},
         output_file => $options->{output_file});
     $self->app->log->error("Git command failed: @cmd - Error: 
$result->{stderr}") unless $result->{status};
+    $self->error($result, $options->{croak}) if $options->{croak} && 
!$result->{status};
     return $result;
 }
 
+sub error ($self, $result, $msg) {
+    croak(OpenQA::Error::Cmd->new(%$result, msg => 
$self->_format_git_error($result, $msg)));
+}
+
 sub _prepare_git_command ($self, $include_git_path) {
     return 'git' unless $include_git_path;
     my $dir = $self->dir;
@@ -93,29 +100,31 @@
     for my $cmd (qw(add rm)) {
         next unless $args->{$cmd};
         push(@files, @{$args->{$cmd}});
-        my $res = $self->_run_cmd([$cmd, @{$args->{$cmd}}]);
-        return $self->_format_git_error($res, "Unable to $cmd via Git") unless 
$res->{status};
+        $self->_run_cmd([$cmd, @{$args->{$cmd}}], {croak => "Unable to $cmd 
via Git"});
     }
 
     # commit changes
     my $message = $args->{message};
     my $author = sprintf('--author=%s <%s>', $self->user->fullname, 
$self->user->email);
-    my $res = $self->_run_cmd(['commit', '-q', '-m', $message, $author, 
@files]);
-    return $self->_format_git_error($res, 'Unable to commit via Git') unless 
$res->{status};
+    $self->_run_cmd(['commit', '-q', '-m', $message, $author, @files], {croak 
=> 'Unable to commit via Git'});
 
     # push changes
     if (($self->config->{do_push} || '') eq 'yes') {
-        $res = $self->_run_cmd(['push'], {batchmode => 1});
-        return undef if $res->{status};
-
         my $msg = 'Unable to push Git commit';
-        if ($res->{return_code} == 128 and $res->{stderr} =~ m/Authentication 
failed for .http/) {
-            $msg
-              .= '. See https://open.qa/docs/#_setting_up_git_support on how 
to setup git support and possibly push via ssh.';
+        try {
+            $self->_run_cmd(['push'], {batchmode => 1, croak => $msg});
+            return undef;
+        }
+        catch ($e) {
+            if ($e->return_code == 128 and $e->stderr =~ m/Authentication 
failed for .http/) {
+                $msg
+                  .= '. See https://open.qa/docs/#_setting_up_git_support on 
how to setup git support and possibly push via ssh.';
+                $e->msg($msg);
+            }
+            croak $e;
         }
-        return $self->_format_git_error($res, $msg);
-    }
 
+    }
     return undef;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1765887110.8fc02990/lib/OpenQA/Schema/Result/Needles.pm 
new/openQA-5.1766014013.377e64fe/lib/OpenQA/Schema/Result/Needles.pm
--- old/openQA-5.1765887110.8fc02990/lib/OpenQA/Schema/Result/Needles.pm        
2025-12-16 13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/lib/OpenQA/Schema/Result/Needles.pm        
2025-12-18 00:26:53.000000000 +0100
@@ -17,6 +17,8 @@
 use OpenQA::Jobs::Constants;
 use OpenQA::Schema::Result::Jobs;
 use OpenQA::Needles qw(locate_needle);
+use Feature::Compat::Try;
+use Carp qw(croak);
 
 __PACKAGE__->table('needles');
 __PACKAGE__->load_components(qw(InflateColumn::DateTime Timestamps));
@@ -178,12 +180,11 @@
     my $git = OpenQA::Git->new({app => $app, dir => $self->directory->path, 
user => $user});
     if ($git->autocommit_enabled) {
         my $directory = $self->directory;
-        my $error = $git->commit(
+        $git->commit(
             {
                 rm => [$fname, $screenshot],
                 message => sprintf('Remove %s/%s', $directory->name, 
$self->filename),
             });
-        return $error if $error;
     }
     else {
         my @error_files;
@@ -192,7 +193,7 @@
         if (@error_files) {
             my $error = 'Unable to delete ' . join(' and ', @error_files);
             $app->log->debug($error);
-            return $error;
+            croak $error;
         }
     }
     $self->check_file;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1765887110.8fc02990/lib/OpenQA/Task/Needle/Delete.pm 
new/openQA-5.1766014013.377e64fe/lib/OpenQA/Task/Needle/Delete.pm
--- old/openQA-5.1765887110.8fc02990/lib/OpenQA/Task/Needle/Delete.pm   
2025-12-16 13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/lib/OpenQA/Task/Needle/Delete.pm   
2025-12-18 00:26:53.000000000 +0100
@@ -8,6 +8,7 @@
 use Scalar::Util 'looks_like_number';
 use Time::Seconds 'ONE_HOUR';
 use OpenQA::Task::SignalGuard;
+use Feature::Compat::Try;
 
 sub register {
     my ($self, $app) = @_;
@@ -57,12 +58,15 @@
         }
         for my $needle (@$needles) {
             my $needle_id = $needle->id;
-            if (my $error = $needle->remove($user)) {
+            try {
+                $needle->remove($user);
+            }
+            catch ($e) {
                 push @errors,
                   {
                     id => $needle_id,
                     display_name => $needle->filename,
-                    message => $error,
+                    message => ref $e ? $e->msg : $e,
                   };
                 next;
             }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1765887110.8fc02990/lib/OpenQA/Task/Needle/Save.pm 
new/openQA-5.1766014013.377e64fe/lib/OpenQA/Task/Needle/Save.pm
--- old/openQA-5.1765887110.8fc02990/lib/OpenQA/Task/Needle/Save.pm     
2025-12-16 13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/lib/OpenQA/Task/Needle/Save.pm     
2025-12-18 00:26:53.000000000 +0100
@@ -140,17 +140,12 @@
     }
     return $minion_job->fail({error => "<strong>Error creating/updating 
needle:</strong><br>$!."}) unless $success;
 
-    # commit needle in Git repository
-    if ($git->autocommit_enabled) {
-        my $error = $git->commit(
-            {
-                add => ["$needlename.json", "$needlename.png"],
-                message => ($commit_message || sprintf('%s for %s', 
$needlename, $openqa_job->name)),
-            });
-        if ($error) {
-            $app->log->error($error);
-            return $minion_job->fail({error => _format_git_error($needlename, 
$error)});
-        }
+    try {
+        _commit_needle_in_git_repo($app, $git, $needlename, $openqa_job, 
$commit_message);
+    }
+    catch ($e) {
+        $app->log->error("$e");
+        return $minion_job->fail({error => _format_git_error($needlename, 
"$e")});
     }
 
     # create/update needle in database
@@ -170,4 +165,12 @@
     return $minion_job->finish($info);
 }
 
+sub _commit_needle_in_git_repo ($app, $git, $needlename, $openqa_job, 
$commit_message) {
+    $git->commit(
+        {
+            add => ["$needlename.json", "$needlename.png"],
+            message => ($commit_message || sprintf('%s for %s', $needlename, 
$openqa_job->name)),
+        }) if $git->autocommit_enabled;
+}
+
 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1765887110.8fc02990/t/14-grutasks-git.t 
new/openQA-5.1766014013.377e64fe/t/14-grutasks-git.t
--- old/openQA-5.1765887110.8fc02990/t/14-grutasks-git.t        2025-12-16 
13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/t/14-grutasks-git.t        2025-12-18 
00:26:53.000000000 +0100
@@ -464,7 +464,9 @@
     $openqa_git->redefine(
         run_cmd_with_log_return_error => sub ($cmd, %args) {
             push @cmds, "@$cmd";
-            return {status => 0, stderr => 'lala', stdout => ''};
+            my $res = {status => 0, stderr => 'lala', stdout => ''};
+            OpenQA::Git->error($res, $args{croak}) if !$res->{status} && 
$args{croak};
+            return $res;
         });
     $args{needle_ids} = [5];
     stderr_like { $res = run_gru_job(@gru_args) } qr{Git command 
failed.*git.*rm}, 'expected stderr';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1765887110.8fc02990/t/16-utils-runcmd.t 
new/openQA-5.1766014013.377e64fe/t/16-utils-runcmd.t
--- old/openQA-5.1765887110.8fc02990/t/16-utils-runcmd.t        2025-12-16 
13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/t/16-utils-runcmd.t        2025-12-18 
00:26:53.000000000 +0100
@@ -75,9 +75,10 @@
     my $res;
 
     subtest 'invoking Git command outside of a Git repo' => sub {
-        stdout_like { $res = $git->commit({cmd => 'status', message => 
'test'}) }
-        qr/.*\[warn\].*fatal: Not a git repository/i, 'Git error logged';
-        like $res, qr"^Unable to commit via Git \($empty_tmp_dir\): fatal: Not 
a git repository"i, 'Git error returned';
+        throws_ok {
+            stdout_like { $res = $git->commit({cmd => 'status', message => 
'test'}) }
+            qr/.*\[warn\].*fatal: Not a git repository/i, 'Git error logged'
+        } qr/OpenQA::Error::Cmd: Unable to commit via 
Git.*\Q$empty_tmp_dir\E.*fatal: Not a git repository/i;
         combined_like {
             throws_ok { $git->check_sha('this-sha-does-not-exist') } 
qr/internal Git error/i,
             'check throws an exception'
@@ -259,10 +260,14 @@
             }
             return \%mock_return_value;
         });
-    combined_like {
-        like $git->commit({message => 'failed push test'}), qr/Unable to push 
Git commit/, 'error handled during push';
-    }
-    qr/Error: mocked push error/, 'push error logged';
+    throws_ok {
+        combined_like {
+            like $git->commit({message => 'failed push test'}), qr/Unable to 
push Git commit/,
+              'error handled during push';
+        }
+        qr/Error: mocked push error/,
+        'push error logged'
+    } qr{OpenQA::Error::Cmd: Unable to push Git commit.*mocked push error};
     $git->config->{do_push} = '';
 };
 
@@ -335,16 +340,16 @@
         sub fail ($self, $args) { $self->{fail_message} = $args }
     }    # uncoverable statement
 
-    sub _run_save_needle_test ($git_mock) {
+    sub _run_save_needle_test ($git_mock, $log_error = undef, $fail_message = 
undef) {
         my @log_errors;
         my $log_mock = Test::MockModule->new(ref $t->app->log);
         $log_mock->redefine(error => sub ($self, $message) { push @log_errors, 
$message; });
         my $job = bless({} => 'Test::FailingMinionJob');
         OpenQA::Task::Needle::Save::_save_needle($t->app, $job, $fake_needle);
 
-        like $log_errors[0], qr/Unable to fetch.*mocked/, 'error logged on 
fail';
+        like $log_errors[0], $log_error // qr/Unable to fetch.*mocked/, 'error 
logged on fail';
         like $job->{fail_message}->{error},
-          qr{<strong>Failed to save.*</strong>.*<pre>Unable to 
fetch.*mocked.*</pre>},
+          $fail_message // qr{<strong>Failed to save.*</strong>.*<pre>Unable 
to fetch.*mocked.*</pre>},
           'error message in fail';
     }
 
@@ -361,6 +366,13 @@
         $t->app->config->{'scm git'}->{do_cleanup} = 'no';
         _run_save_needle_test($git_mock);
     };
+
+    subtest 'fails when commit fails ' => sub {
+        $git_mock->redefine(set_to_latest_master => '');
+        $git_mock->redefine(commit => sub ($self, @) { $self->error({status => 
0}, 'Commit error') });
+        local $fake_needle->{overwrite} = 1;
+        _run_save_needle_test($git_mock, (qr/OpenQA::Error::Cmd: Commit 
error/) x 2);
+    };
 };
 
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1765887110.8fc02990/t/ui/21-admin-needles.t 
new/openQA-5.1766014013.377e64fe/t/ui/21-admin-needles.t
--- old/openQA-5.1765887110.8fc02990/t/ui/21-admin-needles.t    2025-12-16 
13:11:50.000000000 +0100
+++ new/openQA-5.1766014013.377e64fe/t/ui/21-admin-needles.t    2025-12-18 
00:26:53.000000000 +0100
@@ -118,9 +118,9 @@
         wait_for_ajax(with_minion => $minion);
         is(scalar @{$driver->find_elements('#outstanding-needles li', 'css')}, 
0, 'no outstanding needles');
         is(scalar @{$driver->find_elements('#failed-needles li', 'css')}, 1, 
'but failed needle');
-        is(
+        like(
             $driver->find_element('#failed-needles li')->get_text(),
-"inst-timezone-text.json\nUnable to delete 
t/data/openqa/share/tests/opensuse/needles/inst-timezone-text.json and 
t/data/openqa/share/tests/opensuse/needles/inst-timezone-text.png",
+qr{inst-timezone-text.json\nUnable to delete 
t/data/openqa/share/tests/opensuse/needles/inst-timezone-text.json and 
t/data/openqa/share/tests/opensuse/needles/inst-timezone-text.png},
             'right needle name and error message displayed'
         );
         $driver->find_element_by_id('close_delete')->click();

++++++ openQA.obsinfo ++++++
--- /var/tmp/diff_new_pack.ZKLqPw/_old  2025-12-18 18:33:09.469912566 +0100
+++ /var/tmp/diff_new_pack.ZKLqPw/_new  2025-12-18 18:33:09.485913238 +0100
@@ -1,5 +1,5 @@
 name: openQA
-version: 5.1765887110.8fc02990
-mtime: 1765887110
-commit: 8fc02990d191051d7fd201ea553ee3112c911efd
+version: 5.1766014013.377e64fe
+mtime: 1766014013
+commit: 377e64fe96888612ae1cc9a2b39306d811eae7c3
 

Reply via email to