yast-rake 0.2.36 → 0.2.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ module GithubActions
22
+ # Github Actions job
23
+ # @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
24
+ class Job
25
+ attr_reader :name, :steps, :runs_on, :container, :workflow
26
+
27
+ # @param name [String] name of the job
28
+ # @param data [Hash] data from the workflow YAML file
29
+ # @param workflow [GithubActions::Workflow] the parent workflow
30
+ def initialize(name, data, workflow)
31
+ @name = name
32
+ @runs_on = data["runs-on"]
33
+ @container = data["container"]
34
+ @workflow = workflow
35
+
36
+ @steps = data["steps"].map do |step|
37
+ Step.new(self, step)
38
+ end
39
+ end
40
+
41
+ # check if the defined steps can be used locally
42
+ # @return [Array<String>] the list of unsupported steps, returns empty
43
+ # list if all actions are supported
44
+ def unsupported_steps
45
+ steps.each_with_object([]) do |step, array|
46
+ array << step.name unless step.supported?
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ module GithubActions
22
+ # Runs GitHub Actions job in a container locally
23
+ class JobRunner
24
+ include Colorizer
25
+
26
+ attr_reader :job, :image
27
+
28
+ # constructor
29
+ # @param job [GithubActions::Job] the job to run
30
+ # @param image [String,nil] override the Docker image to use,
31
+ # if `nil` it by default uses the image specified in the job
32
+ def initialize(job, image = nil)
33
+ @job = job
34
+ @image = image
35
+ end
36
+
37
+ # run the job in a container
38
+ # @return [Boolean] `true` if all steps were successfully executed,
39
+ # `false` otherwise
40
+ def run
41
+ stage("Running \"#{job.name}\" job from file #{job.workflow.file}")
42
+ start_container
43
+
44
+ result = true
45
+ job.steps.each do |step|
46
+ result &= run_step(step)
47
+ end
48
+
49
+ print_result(result)
50
+ container.stop
51
+ result
52
+ end
53
+
54
+ private
55
+
56
+ # GithubActions::Container
57
+ attr_reader :container
58
+
59
+ # pull the Docker image and start the container
60
+ def start_container
61
+ # prefer the custom image if requested
62
+ @container = Container.new(image || job.container)
63
+ container.pull
64
+ container.start
65
+ end
66
+
67
+ # run a job step
68
+ # @param step [GithubActions::Step] the step to run
69
+ # @return [Boolean] `true` if the step succeeded, `false` otherwise
70
+ def run_step(step)
71
+ info("Step \"#{step.name}\"")
72
+
73
+ # run "uses" step if present
74
+ run_uses_step(step.uses) if step.uses
75
+
76
+ # run "run" step if present
77
+ return true unless step.run
78
+
79
+ container.run(step.run)
80
+ end
81
+
82
+ # print the job result
83
+ # @param success [Boolean] status of the job
84
+ def print_result(success)
85
+ if success
86
+ success("Job result: SUCCESS")
87
+ else
88
+ error("Job result: FAILURE!")
89
+ end
90
+ end
91
+
92
+ # workarounds for some special Javascript actions which are otherwise
93
+ # not supported in general
94
+ # @param uses [String] name of the "uses" action
95
+ def run_uses_step(uses)
96
+ case uses
97
+ when CHECKOUT_ACTION
98
+ # emulate the Git checkout action, just copy the current checkout
99
+ # into the current directory in the running container
100
+ container.copy_current_dir
101
+ when COVERALLS_ACTION
102
+ # skip the coveralls action, do not send the code coverage report
103
+ # when running locally
104
+ info("Skipping the Coveralls step")
105
+ else
106
+ # this should actually never happen, we already checked for
107
+ # the unsupported steps before starting the job
108
+ raise "Unsupported action \"#{uses}\""
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ module GithubActions
22
+ # Github Actions step
23
+ # @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
24
+ class Step
25
+ attr_reader :job, :name, :uses, :run, :env
26
+
27
+ # constructor
28
+ # @param job [GithubActions::Job] the parent job
29
+ # @param step [Hash] the step definition from the YAML file
30
+ def initialize(job, step)
31
+ @job = job
32
+ @name = step["name"]
33
+ @uses = step["uses"]
34
+ @run = step["run"]
35
+ @env = step["env"]
36
+ end
37
+
38
+ # we can run the step if it is just a plain command (not a Javascript or
39
+ # Docker container action) and the environment variables do not contain any
40
+ # expansions (usually used for Github secrets)
41
+ # @return [Boolean] `true` if the step is supported, `false` otherwise
42
+ def supported?
43
+ known_uses? && !expansion?
44
+ end
45
+
46
+ private
47
+
48
+ # Javascript or Docker actions are not supported
49
+ # @return [Boolean] `true` if there is a workaround defined for the step
50
+ def known_uses?
51
+ uses.nil? || uses.match?(CHECKOUT_ACTION) || uses.match?(COVERALLS_ACTION)
52
+ end
53
+
54
+ # we cannot expand the Github secrets
55
+ # @return [Boolean] `true` if an expansion is found, `false` otherwise
56
+ def expansion?
57
+ env&.any? { |_k, v| v.to_s.include?("${{") }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require "yaml"
22
+
23
+ module GithubActions
24
+ # Github Actions workflow
25
+ # @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
26
+ class Workflow
27
+ attr_reader :file, :name, :on, :jobs
28
+
29
+ # load all defined workflows from all YAML files
30
+ # @return [Array<GithubActions::Workflow>]
31
+ def self.read
32
+ Dir[".github/workflows/*.{yml,yaml}"].map do |file|
33
+ new(file)
34
+ end
35
+ end
36
+
37
+ # load the workflow from an YAML file
38
+ # @param file [String] path to the YAML file
39
+ def initialize(file)
40
+ @file = file
41
+ yml = YAML.load_file(file)
42
+ @name = yml["name"]
43
+ # "on" is autoconverted to Boolean "true" for this line
44
+ # on: [push, pull_request]
45
+ # see https://medium.com/@lefloh/lessons-learned-about-yaml-and-norway-13ba26df680
46
+ @on = yml[true]
47
+
48
+ @jobs = yml["jobs"].map do |name, job|
49
+ Job.new(name, job, self)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require_relative "tasks/details"
22
+ require_relative "tasks/list"
23
+ require_relative "tasks/run"
24
+ require_relative "tasks/run_all"
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require_relative "../github_actions"
22
+
23
+ module GithubActions
24
+ module Tasks
25
+ # print the defined Github Actions jobs with details
26
+ class Details
27
+ include Colorizer
28
+
29
+ def run
30
+ Workflow.read.each_with_index do |workflow, index|
31
+ workflow.jobs.each do |job|
32
+ # empty line separator if multiple jobs are found
33
+ puts if index > 0
34
+
35
+ # print the job details
36
+ success(job.name)
37
+ puts " run: \"rake actions:run[#{job.name}]\""
38
+ puts " container: #{job.container}"
39
+ puts " steps:"
40
+ job.steps.each do |step|
41
+ puts " #{step.name}"
42
+ puts " #{step.run}" if step.run
43
+ puts " #{step.uses}" if step.uses
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require_relative "../github_actions"
22
+
23
+ module GithubActions
24
+ module Tasks
25
+ # print the defined Github Actions jobs
26
+ class List
27
+ def run
28
+ Workflow.read.each do |workflow|
29
+ workflow.jobs.each do |job|
30
+ # print rake commands so users can easily copy&paste into terminal
31
+ puts "rake actions:run[#{job.name}]"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # Yast rake
5
+ #
6
+ # Copyright (C) 2021 SUSE LLC
7
+ # This library is free software; you can redistribute it and/or modify
8
+ # it only under the terms of version 2.1 of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation.
10
+ #
11
+ # This library is distributed in the hope that it will be useful, but WITHOUT
12
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
+ # details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ #++
20
+
21
+ require_relative "../github_actions"
22
+
23
+ module GithubActions
24
+ module Tasks
25
+ # run the requested Github Actions job locally
26
+ class Run
27
+ include Colorizer
28
+
29
+ # the requested job name
30
+ attr_reader :name
31
+
32
+ # constructor
33
+ # @param name [String] name of the job to run
34
+ def initialize(name)
35
+ @name = name
36
+ end
37
+
38
+ # run the GitHub Action locally
39
+ def run
40
+ runner = GithubActions::JobRunner.new(find_job, ENV["DOCKER_IMAGE"])
41
+ abort unless runner.run
42
+ end
43
+
44
+ private
45
+
46
+ # read the job definition from YAML file
47
+ def find_job
48
+ job = nil
49
+ Workflow.read.each do |workflow|
50
+ # Note: in theory the same job name might be used in different files,
51
+ # but in YaST we use single YAML files and we can avoid duplicates,
52
+ # simply use the first found and avoid unnecessary complexity
53
+ job = workflow.jobs.find { |j| j.name == name }
54
+ end
55
+
56
+ check_job(job)
57
+
58
+ job
59
+ end
60
+
61
+ # check if the job is valid and can be run locally,
62
+ # it aborts when the job cannot be used
63
+ def check_job(job)
64
+ if job.nil?
65
+ error("ERROR: Job \"#{name}\" not found")
66
+ abort
67
+ end
68
+
69
+ unsupported = job.unsupported_steps
70
+ if !unsupported.empty?
71
+ error("ERROR: These steps are not supported: #{unsupported.inspect}")
72
+ abort
73
+ end
74
+
75
+ return if job.container && !job.container.empty?
76
+
77
+ error("ERROR: Docker image name is missing in the job definition")
78
+ abort
79
+ end
80
+ end
81
+ end
82
+ end