Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-yast-rake for 
openSUSE:Factory checked in at 2021-07-17 23:36:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-yast-rake (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-yast-rake.new.2632 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-yast-rake"

Sat Jul 17 23:36:26 2021 rev:34 rq:906424 version:0.2.41

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-yast-rake/rubygem-yast-rake.changes      
2020-06-27 23:22:02.177714972 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-yast-rake.new.2632/rubygem-yast-rake.changes
    2021-07-17 23:36:47.501898973 +0200
@@ -1,0 +2,19 @@
+Thu Jun 24 11:44:52 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz>
+
+- Move the "sle_latest" build target to SLE15-SP4 (bsc#1187677)
+- Added "sle15sp4" and future "sle15sp5" build targets
+- 0.2.41
+
+-------------------------------------------------------------------
+Fri Mar 26 12:38:22 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz>
+
+- Added new rake tasks for running the GitHub Actions locally
+  (bsc#1184033)
+- 0.2.40
+
+-------------------------------------------------------------------
+Tue Oct 20 11:59:11 UTC 2020 - Bernhard Wiedemann <bwiedem...@suse.com>
+
+- Fix URL in .spec file
+
+-------------------------------------------------------------------

Old:
----
  yast-rake-0.2.39.gem

New:
----
  yast-rake-0.2.41.gem

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

Other differences:
------------------
++++++ rubygem-yast-rake.spec ++++++
--- /var/tmp/diff_new_pack.2sH1VK/_old  2021-07-17 23:36:47.949895519 +0200
+++ /var/tmp/diff_new_pack.2sH1VK/_new  2021-07-17 23:36:47.953895488 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-yast-rake
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
 %define rb_build_ruby_abis    %{rb_default_ruby_abi}
 
 Name:           rubygem-yast-rake
-Version:        0.2.39
+Version:        0.2.41
 Release:        0
 %define mod_name yast-rake
 %define mod_full_name %{mod_name}-%{version}
@@ -29,8 +29,8 @@
 BuildRequires:  %{ruby}
 BuildRequires:  ruby-macros >= 5
 BuildRequires:  rubygem(%{rb_default_ruby_abi}:gem2rpm)
-URL:            http://github.org/openSUSE/yast-rake
-Source:         http://rubygems.org/gems/%{mod_full_name}.gem
+URL:            https://github.com/yast/yast-rake
+Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Summary:        Rake tasks providing basic work-flow for Yast development
 License:        LGPL-2.1-only
 Group:          Development/Languages/Ruby

++++++ yast-rake-0.2.39.gem -> yast-rake-0.2.41.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/VERSION new/VERSION
--- old/VERSION 2020-06-23 14:20:45.000000000 +0200
+++ new/VERSION 2021-01-22 12:31:49.000000000 +0100
@@ -1 +1 @@
-0.2.39
+0.2.41
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/data/targets.yml new/data/targets.yml
--- old/data/targets.yml        2020-06-23 14:20:45.000000000 +0200
+++ new/data/targets.yml        2021-01-22 12:31:49.000000000 +0100
@@ -85,11 +85,21 @@
   obs_project: "Devel:YaST:SLE-15-SP3"
   obs_sr_project: "SUSE:SLE-15-SP3:Update"
   obs_target: "SUSE_SLE-15-SP3_Update"
+:sle15sp4:
+  obs_api: "https://api.suse.de/";
+  obs_project: "Devel:YaST:SLE-15-SP4"
+  obs_sr_project: "SUSE:SLE-15-SP4:Update"
+  obs_target: "SUSE_SLE-15-SP4_Update"
+:sle15sp5:
+  obs_api: "https://api.suse.de/";
+  obs_project: "Devel:YaST:SLE-15-SP5"
+  obs_sr_project: "SUSE:SLE-15-SP5:Update"
+  obs_target: "SUSE_SLE-15-SP5_Update"
 :sle_latest:
   obs_api: "https://api.suse.de/";
   obs_project: "Devel:YaST:Head"
-  obs_sr_project: "SUSE:SLE-15-SP3:GA"
-  obs_target: "SUSE_SLE-15-SP3_GA"
+  obs_sr_project: "SUSE:SLE-15-SP4:GA"
+  obs_target: "SUSE_SLE-15-SP4_GA"
 :factory:
   obs_project: "YaST:Head"
   obs_sr_project: "openSUSE:Factory"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/actions.rake new/lib/tasks/actions.rake
--- old/lib/tasks/actions.rake  1970-01-01 01:00:00.000000000 +0100
+++ new/lib/tasks/actions.rake  2021-01-22 12:31:49.000000000 +0100
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "github_actions/tasks"
+
+# tasks related to GitHub Actions (https://docs.github.com/en/actions)
+namespace :actions do
+  desc "List the GitHub Action jobs"
+  task :list do
+    GithubActions::Tasks::List.new.run
+  end
+
+  desc "Display GitHub Action job details"
+  task :details do
+    GithubActions::Tasks::Details.new.run
+  end
+
+  desc "Run locally the specified GitHub Action job (all jobs if \"job\" is 
empty)"
+  task :run, [:job] do |_task, args|
+    name = args[:job]
+    if name.nil? || name.empty?
+      GithubActions::Tasks::RunAll.new.run
+    else
+      GithubActions::Tasks::Run.new(name).run
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/container_runner.rb 
new/lib/tasks/container_runner.rb
--- old/lib/tasks/container_runner.rb   1970-01-01 01:00:00.000000000 +0100
+++ new/lib/tasks/container_runner.rb   2021-01-22 12:31:49.000000000 +0100
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "github_actions/github_actions"
+
+# Run a client in Docker container
+class ContainerRunner
+  include GithubActions::Colorizer
+
+  # start a container, copy the sources there and run "rake run"
+  # @param client [String,nil] the client name, nil or empty string = find
+  #   the client automatically
+  def run(client)
+    image = find_image
+    container = GithubActions::Container.new(image)
+    container.pull
+    container.start
+    container.copy_current_dir
+
+    cmd = client ? "rake run[#{client}]" : "rake run"
+    container.run(cmd)
+
+    container.stop
+  end
+
+private
+
+  # find the Docker image to use in the container
+  # @return [String] the image name
+  def find_image
+    # explicitly requested image
+    image = ENV["DOCKER_IMAGE"]
+    return image if image && !image.empty?
+
+    # scan the Docker images used in the GitHub Actions
+    images = workflow_images
+    return images.first if images.size == 1
+
+    if images.empty?
+      error("No Docker image was found in the GitHub Actions")
+      puts "Use DOCKER_IMAGE=<name> option for specifying the image name"
+      abort
+    end
+
+    # multiple images found
+    error("Found multiple Docker images in the GitHub Actions:")
+    error(images.inspect)
+    puts "Use DOCKER_IMAGE=<name> option for specifying the image name"
+    abort
+  end
+
+  # extract the Docker images from the GitHub Actions,
+  # the duplicates are removed
+  # @return [Array<String>] image names
+  def workflow_images
+    GithubActions::Workflow.read.each_with_object([]) do |workflow, images|
+      workflow.jobs.each do |job|
+        container = job.container
+        images << container if container && !images.include?(container)
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions/colorizer.rb 
new/lib/tasks/github_actions/github_actions/colorizer.rb
--- old/lib/tasks/github_actions/github_actions/colorizer.rb    1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/colorizer.rb    2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+module GithubActions
+  # helper methods for colorizing output, if the "rainbow" colorizing gem
+  # is not installed then it prints the original messages without any 
colorizing
+  module Colorizer
+    # print an error
+    # @param msg [Object] the text to print
+    def error(msg)
+      print_colored(msg, :red)
+    end
+
+    # print a success message
+    # @param msg [Object] the text to print
+    def success(msg)
+      print_colored(msg, :green)
+    end
+
+    # print a warning
+    # @param msg [Object] the text to print
+    def warning(msg)
+      print_colored(msg, :magenta)
+    end
+
+    # print a message
+    # @param msg [Object] the text to print
+    def info(msg)
+      print_colored(msg, :cyan)
+    end
+
+    # print the progress status
+    # @param msg [Object] the text to print
+    def stage(msg)
+      print_colored(msg, :yellow)
+    end
+
+  private
+
+    # helper for printing the text
+    # @param msg [Object] the text to print
+    # @param color [Symbol] the text color
+    def print_colored(msg, color)
+      puts rainbow? ? Rainbow(msg).color(color) : msg
+    end
+
+    # load the Rainbow colorizing library if present
+    # see https://github.com/sickill/rainbow
+    # @return Boolean `true` if Rainbow was successfully loaded, `false` 
otherwise
+    def rainbow?
+      return @rainbow_present unless @rainbow_present.nil?
+
+      begin
+        require "rainbow"
+        @rainbow_present = true
+      rescue LoadError
+        @rainbow_present = false
+      end
+
+      @rainbow_present
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions/container.rb 
new/lib/tasks/github_actions/github_actions/container.rb
--- old/lib/tasks/github_actions/github_actions/container.rb    1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/container.rb    2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,162 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require "English"
+require "shellwords"
+
+module GithubActions
+  # Manage a Docker container
+  class Container
+    include Colorizer
+
+    attr_reader :image, :container
+
+    # the default timeout in seconds, maximum time for the running container,
+    # after the time runs out the container is automatically stopped and 
removed
+    # unless `KEEP_CONTAINER` option is set
+    TIMEOUT = 3600
+
+    # the default environment variables in the container
+    ENV_VARIABLES = {
+      # this is a CI environment
+      "CI"             => "true",
+      # skip the modified check in the "rake osc:build" task
+      "CHECK_MODIFIED" => "0"
+    }.freeze
+
+    # constructor
+    # @param image [String] name of the Docker image to use
+    def initialize(image)
+      @image = image
+    end
+
+    # pull the Docker image, ensure that the latest version is used
+    def pull
+      stage("Pulling the #{image} image...")
+      # if the latest image is already present it does nothing
+      system("docker pull #{image.shellescape}")
+    end
+
+    # start the container, runs "docker create" and "docker start"
+    def start
+      stage("Starting the container...")
+
+      # define the initial command for the container to start
+      if keep_container?
+        # running "tail -f /dev/null" does nothing and gets stuck forever,
+        # this ensures the container keeps running and we can execute
+        # the other commands there via "docker exec"
+        run = "tail"
+        args = "-f /dev/null"
+      else
+        # the "sleep" command ensures the container shuts down automatically 
after
+        # the timeout (to abort frozen jobs or avoid hanging containers after 
a crash)
+        run = "sleep"
+        args = TIMEOUT
+      end
+
+      cmd = "docker create #{env_options(ENV_VARIABLES)} --rm --entrypoint " \
+        "#{run} #{image.shellescape} #{args}"
+
+      # contains the container ID
+      @container = `#{cmd}`.chomp
+      system("docker start #{container.shellescape} > /dev/null")
+    end
+
+    # stop and remove the container from the system, runs "docker rm"
+    def stop
+      if keep_container?
+        print_container_usage
+      else
+        stage("Stopping the container...")
+        system("docker rm --force #{container.shellescape} > /dev/null")
+      end
+    end
+
+    # run a command in the container, runs "docker exec"
+    # the command is executed in a shell, so shell metacharacters like "&&"
+    # can be used to join several commands
+    # @param cmd [String] the command to run, it is passed to a shell to it 
might
+    #   contain multiple commands or shell meta characters
+    # @param env [Hash] optional environment variables (with mapping "name" => 
"value")
+    # @return [Boolean] `true` if the command succeeded (exit status 0),
+    #  `false` otherwise
+    def run(cmd, env = {})
+      stage("Running command: #{cmd}")
+      system("docker exec -it #{env_options(env)} #{container.shellescape} " \
+        "sh -c #{cmd.shellescape}")
+      $CHILD_STATUS.success?
+    end
+
+    # get the current working directory in the container
+    # @return [String] the path
+    def cwd
+      `docker exec #{container.shellescape} pwd`.chomp
+    end
+
+    # copy the files from host into the container
+    # @param from [String] the source path, if it is a directory all content
+    #   is copied (including subdirectories)
+    # @param to [String] the target location in the container
+    def copy_files(from, to)
+      stage("Copying #{from} to #{to} in the container...")
+
+      if File.directory?(from)
+        # Dir.children is similar to Dir.entries but it omits the "." and ".." 
values
+        Dir.children(from).each do |f|
+          system("docker cp #{f.shellescape} 
#{container.shellescape}:#{to.shellescape}")
+        end
+      else
+        system("docker cp #{from.shellescape} 
#{container.shellescape}:#{to.shellescape}")
+      end
+    end
+
+    # copy the current directory to the current directory in the container
+    def copy_current_dir
+      copy_files(Dir.pwd, cwd)
+    end
+
+  private
+
+    # should we keep the container at the end or remove it?
+    def keep_container?
+      ENV["KEEP_CONTAINER"] == "1" || ENV["KEEP_CONTAINER"] == "true"
+    end
+
+    # when we keep the container running print some hints how to use it
+    def print_container_usage
+      warning("The Docker container is still running!")
+      puts "Use this command to connect to it:"
+      # docker accepts shortened IDs, make the commands shorter
+      info("  docker exec -it #{container[0..16]} bash")
+      puts "To stop and remove the container run:"
+      info("  docker rm -f #{container[0..16]}")
+    end
+
+    # build the docker environment command line options
+    # @param mapping [Hash] environment variables
+    # @return [String] the built Docker options
+    def env_options(mapping)
+      mapping.map do |name, value|
+        "-e #{name.shellescape}=#{value.shellescape}"
+      end.join(" ")
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions/job.rb 
new/lib/tasks/github_actions/github_actions/job.rb
--- old/lib/tasks/github_actions/github_actions/job.rb  1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/job.rb  2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+module GithubActions
+  # Github Actions job
+  # @see 
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+  class Job
+    attr_reader :name, :steps, :runs_on, :container, :workflow
+
+    # @param name [String] name of the job
+    # @param data [Hash] data from the workflow YAML file
+    # @param workflow [GithubActions::Workflow] the parent workflow
+    def initialize(name, data, workflow)
+      @name = name
+      @runs_on = data["runs-on"]
+      @container = data["container"]
+      @workflow = workflow
+
+      @steps = data["steps"].map do |step|
+        Step.new(self, step)
+      end
+    end
+
+    # check if the defined steps can be used locally
+    # @return [Array<String>] the list of unsupported steps, returns empty
+    #  list if all actions are supported
+    def unsupported_steps
+      steps.each_with_object([]) do |step, array|
+        array << step.name unless step.supported?
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/lib/tasks/github_actions/github_actions/job_runner.rb 
new/lib/tasks/github_actions/github_actions/job_runner.rb
--- old/lib/tasks/github_actions/github_actions/job_runner.rb   1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/job_runner.rb   2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+module GithubActions
+  # Runs GitHub Actions job in a container locally
+  class JobRunner
+    include Colorizer
+
+    attr_reader :job, :image
+
+    # constructor
+    # @param job [GithubActions::Job] the job to run
+    # @param image [String,nil] override the Docker image to use,
+    #   if `nil` it by default uses the image specified in the job
+    def initialize(job, image = nil)
+      @job = job
+      @image = image
+    end
+
+    # run the job in a container
+    # @return [Boolean] `true` if all steps were successfully executed,
+    #  `false` otherwise
+    def run
+      stage("Running \"#{job.name}\" job from file #{job.workflow.file}")
+      start_container
+
+      result = true
+      job.steps.each do |step|
+        result &= run_step(step)
+      end
+
+      print_result(result)
+      container.stop
+      result
+    end
+
+  private
+
+    # GithubActions::Container
+    attr_reader :container
+
+    # pull the Docker image and start the container
+    def start_container
+      # prefer the custom image if requested
+      @container = Container.new(image || job.container)
+      container.pull
+      container.start
+    end
+
+    # run a job step
+    # @param step [GithubActions::Step] the step to run
+    # @return [Boolean] `true` if the step succeeded, `false` otherwise
+    def run_step(step)
+      info("Step \"#{step.name}\"")
+
+      # run "uses" step if present
+      run_uses_step(step.uses) if step.uses
+
+      # run "run" step if present
+      return true unless step.run
+
+      container.run(step.run)
+    end
+
+    # print the job result
+    # @param success [Boolean] status of the job
+    def print_result(success)
+      if success
+        success("Job result: SUCCESS")
+      else
+        error("Job result: FAILURE!")
+      end
+    end
+
+    # workarounds for some special Javascript actions which are otherwise
+    # not supported in general
+    # @param uses [String] name of the "uses" action
+    def run_uses_step(uses)
+      case uses
+      when CHECKOUT_ACTION
+        # emulate the Git checkout action, just copy the current checkout
+        # into the current directory in the running container
+        container.copy_current_dir
+      when COVERALLS_ACTION
+        # skip the coveralls action, do not send the code coverage report
+        # when running locally
+        info("Skipping the Coveralls step")
+      else
+        # this should actually never happen, we already checked for
+        # the unsupported steps before starting the job
+        raise "Unsupported action \"#{uses}\""
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions/step.rb 
new/lib/tasks/github_actions/github_actions/step.rb
--- old/lib/tasks/github_actions/github_actions/step.rb 1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/step.rb 2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+module GithubActions
+  # Github Actions step
+  # @see 
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+  class Step
+    attr_reader :job, :name, :uses, :run, :env
+
+    # constructor
+    # @param job [GithubActions::Job] the parent job
+    # @param step [Hash] the step definition from the YAML file
+    def initialize(job, step)
+      @job = job
+      @name = step["name"]
+      @uses = step["uses"]
+      @run = step["run"]
+      @env = step["env"]
+    end
+
+    # we can run the step if it is just a plain command (not a Javascript or
+    # Docker container action) and the environment variables do not contain any
+    # expansions (usually used for Github secrets)
+    # @return [Boolean] `true` if the step is supported, `false` otherwise
+    def supported?
+      known_uses? && !expansion?
+    end
+
+  private
+
+    # Javascript or Docker actions are not supported
+    # @return [Boolean] `true` if there is a workaround defined for the step
+    def known_uses?
+      uses.nil? || uses.match?(CHECKOUT_ACTION) || 
uses.match?(COVERALLS_ACTION)
+    end
+
+    # we cannot expand the Github secrets
+    # @return [Boolean] `true` if an expansion is found, `false` otherwise
+    def expansion?
+      env&.any? { |_k, v| v.to_s.include?("${{") }
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions/workflow.rb 
new/lib/tasks/github_actions/github_actions/workflow.rb
--- old/lib/tasks/github_actions/github_actions/workflow.rb     1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions/workflow.rb     2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require "yaml"
+
+module GithubActions
+  # Github Actions workflow
+  # @see 
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+  class Workflow
+    attr_reader :file, :name, :on, :jobs
+
+    # load all defined workflows from all YAML files
+    # @return [Array<GithubActions::Workflow>]
+    def self.read
+      Dir[".github/workflows/*.{yml,yaml}"].map do |file|
+        new(file)
+      end
+    end
+
+    # load the workflow from an YAML file
+    # @param file [String] path to the YAML file
+    def initialize(file)
+      @file = file
+      yml = YAML.load_file(file)
+      @name = yml["name"]
+      # "on" is autoconverted to Boolean "true" for this line
+      #   on: [push, pull_request]
+      # see 
https://medium.com/@lefloh/lessons-learned-about-yaml-and-norway-13ba26df680
+      @on = yml[true]
+
+      @jobs = yml["jobs"].map do |name, job|
+        Job.new(name, job, self)
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/github_actions.rb 
new/lib/tasks/github_actions/github_actions.rb
--- old/lib/tasks/github_actions/github_actions.rb      1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/github_actions.rb      2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "github_actions/colorizer"
+require_relative "github_actions/container"
+require_relative "github_actions/job"
+require_relative "github_actions/job_runner"
+require_relative "github_actions/step"
+require_relative "github_actions/workflow"
+
+# classes for running the Github Actions locally
+module GithubActions
+  # regexps for some special actions which need to be handled differently
+  CHECKOUT_ACTION = /\Aactions\/checkout(|@.*)\z/.freeze
+  COVERALLS_ACTION = /\Acoverallsapp\/github-action(|@.*)\z/.freeze
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/tasks/details.rb 
new/lib/tasks/github_actions/tasks/details.rb
--- old/lib/tasks/github_actions/tasks/details.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/tasks/details.rb       2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "../github_actions"
+
+module GithubActions
+  module Tasks
+    # print the defined Github Actions jobs with details
+    class Details
+      include Colorizer
+
+      def run
+        Workflow.read.each_with_index do |workflow, index|
+          workflow.jobs.each do |job|
+            # empty line separator if multiple jobs are found
+            puts if index > 0
+
+            # print the job details
+            success(job.name)
+            puts "  run: \"rake actions:run[#{job.name}]\""
+            puts "  container: #{job.container}"
+            puts "  steps:"
+            job.steps.each do |step|
+              puts "    #{step.name}"
+              puts "      #{step.run}" if step.run
+              puts "      #{step.uses}" if step.uses
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/tasks/list.rb 
new/lib/tasks/github_actions/tasks/list.rb
--- old/lib/tasks/github_actions/tasks/list.rb  1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/tasks/github_actions/tasks/list.rb  2021-01-22 12:31:49.000000000 
+0100
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "../github_actions"
+
+module GithubActions
+  module Tasks
+    # print the defined Github Actions jobs
+    class List
+      def run
+        Workflow.read.each do |workflow|
+          workflow.jobs.each do |job|
+            # print rake commands so users can easily copy&paste into terminal
+            puts "rake actions:run[#{job.name}]"
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/tasks/run.rb 
new/lib/tasks/github_actions/tasks/run.rb
--- old/lib/tasks/github_actions/tasks/run.rb   1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/tasks/github_actions/tasks/run.rb   2021-01-22 12:31:49.000000000 
+0100
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "../github_actions"
+
+module GithubActions
+  module Tasks
+    # run the requested Github Actions job locally
+    class Run
+      include Colorizer
+
+      # the requested job name
+      attr_reader :name
+
+      # constructor
+      # @param name [String] name of the job to run
+      def initialize(name)
+        @name = name
+      end
+
+      # run the GitHub Action locally
+      def run
+        runner = GithubActions::JobRunner.new(find_job, ENV["DOCKER_IMAGE"])
+        abort unless runner.run
+      end
+
+    private
+
+      # read the job definition from YAML file
+      def find_job
+        job = nil
+        Workflow.read.each do |workflow|
+          # Note: in theory the same job name might be used in different files,
+          # but in YaST we use single YAML files and we can avoid duplicates,
+          # simply use the first found and avoid unnecessary complexity
+          job = workflow.jobs.find { |j| j.name == name }
+        end
+
+        check_job(job)
+
+        job
+      end
+
+      # check if the job is valid and can be run locally,
+      # it aborts when the job cannot be used
+      def check_job(job)
+        if job.nil?
+          error("ERROR: Job \"#{name}\" not found")
+          abort
+        end
+
+        unsupported = job.unsupported_steps
+        if !unsupported.empty?
+          error("ERROR: These steps are not supported: #{unsupported.inspect}")
+          abort
+        end
+
+        return if job.container && !job.container.empty?
+
+        error("ERROR: Docker image name is missing in the job definition")
+        abort
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/tasks/run_all.rb 
new/lib/tasks/github_actions/tasks/run_all.rb
--- old/lib/tasks/github_actions/tasks/run_all.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/tasks/github_actions/tasks/run_all.rb       2021-01-22 
12:31:49.000000000 +0100
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "../github_actions"
+
+module GithubActions
+  module Tasks
+    # run all supported Github Action jobs locally
+    class RunAll
+      include Colorizer
+
+      # run all jobs one by one, continue even if a job fails,
+      # print the summary in the end
+      def run
+        # collect failed jobs
+        failed_jobs = []
+        workflows = Workflow.read
+        # custom Docker image requested?
+        image = custom_image(workflows)
+
+        workflows.each do |workflow|
+          workflow.jobs.each do |job|
+            # skip unsupported jobs
+            next unless valid_job?(job)
+
+            runner = JobRunner.new(job, image)
+            failed_jobs << job.name if !runner.run
+          end
+        end
+
+        print_result(failed_jobs)
+      end
+
+    private
+
+      # check if a custom image can be used for all jobs,
+      # if more than one Docker image is used than it's unlikely that
+      # a same custom image will work for all jobs, rather abort in that case
+      # to avoid some strange errors when using incorrect image
+      # @param workflows [GithubActions::Workflow] all defined workflows
+      # @return [String,nil] the custom Docker image name or `nil` if not 
specified
+      def custom_image(workflows)
+        return nil unless ENV["DOCKER_IMAGE"]
+
+        images = workflows.each_with_object([]) do |workflow, arr|
+          workflow.jobs.each do |job|
+            arr << job.container if job.container && 
!arr.include?(job.container)
+          end
+        end
+
+        if images.size > 1
+          error("More than one Docker image is used in the workflows,")
+          error("DOCKER_IMAGE option cannot be used.")
+          puts "Use DOCKER_IMAGE option for each job separately."
+          abort
+        end
+
+        ENV["DOCKER_IMAGE"]
+      end
+
+      # print the final result
+      # @param failed_jobs [Array<String>] list of failed jobs
+      def print_result(failed_jobs)
+        if failed_jobs.empty?
+          success("Overall result: SUCCESS")
+        else
+          error("Failed jobs: #{failed_jobs.inspect}")
+          error("Overall result: FAILURE!")
+          abort
+        end
+      end
+
+      # check if the job is valid and can be run locally,
+      # if the job cannot be used it prints a warning
+      # @return [Boolean] `true` if the job is valid, `false` otherwise
+      def valid_job?(job)
+        unsupported = job.unsupported_steps
+        if !unsupported.empty?
+          warning("WARNING: Skipping job \"#{job.name}\", found " \
+            "unsupported steps: #{unsupported.inspect}")
+          return false
+        end
+
+        if job.container.nil? || job.container.empty?
+          warning("WARNING: Skipping job \"#{job.name}\", " \
+            "the Docker container in not specified")
+          return false
+        end
+
+        true
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/github_actions/tasks.rb 
new/lib/tasks/github_actions/tasks.rb
--- old/lib/tasks/github_actions/tasks.rb       1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/tasks/github_actions/tasks.rb       2021-01-22 12:31:49.000000000 
+0100
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+#--
+# Yast rake
+#
+# Copyright (C) 2021 SUSE LLC
+#   This library is free software; you can redistribute it and/or modify
+# it only under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#++
+
+require_relative "tasks/details"
+require_relative "tasks/list"
+require_relative "tasks/run"
+require_relative "tasks/run_all"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/tasks/run.rake new/lib/tasks/run.rake
--- old/lib/tasks/run.rake      2020-06-23 14:20:45.000000000 +0200
+++ new/lib/tasks/run.rake      2021-01-22 12:31:49.000000000 +0100
@@ -18,6 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 #++
 
+require_relative "container_runner"
+
 def set_y2dir
   dirs = Dir["**/src"]
   dirs << ENV["Y2DIR"] if ENV["Y2DIR"] && !ENV["Y2DIR"].empty?
@@ -46,6 +48,15 @@
   sh "/sbin/yast2 #{client}"
 end
 
+desc "Run given client in a Docker container"
+task :"run:container", :client do |_t, args|
+  args.with_defaults = { client: nil }
+  client = args[:client]
+
+  runner = ContainerRunner.new
+  runner.run(client)
+end
+
 desc "Runs console with preloaded module directories"
 task :console do
   set_y2dir
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2020-06-23 14:20:45.000000000 +0200
+++ new/metadata        2021-06-24 15:18:38.000000000 +0200
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: yast-rake
 version: !ruby/object:Gem::Version
-  version: 0.2.39
+  version: 0.2.41
 platform: ruby
 authors:
 - Josef Reidinger
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2020-06-23 00:00:00.000000000 Z
+date: 2021-06-24 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: packaging_rake_tasks
@@ -51,6 +51,20 @@
 - VERSION
 - data/index.html
 - data/targets.yml
+- lib/tasks/actions.rake
+- lib/tasks/container_runner.rb
+- lib/tasks/github_actions/github_actions.rb
+- lib/tasks/github_actions/github_actions/colorizer.rb
+- lib/tasks/github_actions/github_actions/container.rb
+- lib/tasks/github_actions/github_actions/job.rb
+- lib/tasks/github_actions/github_actions/job_runner.rb
+- lib/tasks/github_actions/github_actions/step.rb
+- lib/tasks/github_actions/github_actions/workflow.rb
+- lib/tasks/github_actions/tasks.rb
+- lib/tasks/github_actions/tasks/details.rb
+- lib/tasks/github_actions/tasks/list.rb
+- lib/tasks/github_actions/tasks/run.rb
+- lib/tasks/github_actions/tasks/run_all.rb
 - lib/tasks/install.rake
 - lib/tasks/pot.rake
 - lib/tasks/rubocop.rake
@@ -86,7 +100,8 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.1.2
+rubyforge_project: 
+rubygems_version: 2.7.6.3
 signing_key: 
 specification_version: 4
 summary: Rake tasks providing basic work-flow for Yast development

Reply via email to