yast-rake 0.2.34 → 0.2.40

Sign up to get free protection for your applications and to get access to all the features.
@@ -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