decidim-maintainers_toolbox 0.1.0
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.
- checksums.yaml +7 -0
- data/README.md +66 -0
- data/decidim-maintainers_toolbox.gemspec +47 -0
- data/exe/decidim-backporter +44 -0
- data/exe/decidim-backports-checker +48 -0
- data/exe/decidim-changelog-generator +46 -0
- data/exe/decidim-releaser +41 -0
- data/lib/decidim/maintainers_toolbox/backporter.rb +100 -0
- data/lib/decidim/maintainers_toolbox/backports_reporter/cli_report.rb +46 -0
- data/lib/decidim/maintainers_toolbox/backports_reporter/csv_report.rb +34 -0
- data/lib/decidim/maintainers_toolbox/backports_reporter/report.rb +67 -0
- data/lib/decidim/maintainers_toolbox/changelog_generator.rb +166 -0
- data/lib/decidim/maintainers_toolbox/git_backport_checker.rb +81 -0
- data/lib/decidim/maintainers_toolbox/git_backport_manager.rb +184 -0
- data/lib/decidim/maintainers_toolbox/github_manager/poster.rb +75 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/base.rb +80 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id.rb +48 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/by_label.rb +97 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/by_title.rb +59 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/related_issues.rb +53 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier.rb +23 -0
- data/lib/decidim/maintainers_toolbox/releaser.rb +287 -0
- data/lib/decidim/maintainers_toolbox/version.rb +7 -0
- data/lib/decidim/maintainers_toolbox.rb +10 -0
- metadata +160 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/time/zones"
|
4
|
+
require_relative "base"
|
5
|
+
|
6
|
+
module Decidim
|
7
|
+
module MaintainersToolbox
|
8
|
+
module GithubManager
|
9
|
+
module Querier
|
10
|
+
# Makes a GET request for the list of Issues or Pull Requests in GitHub.
|
11
|
+
# They must comply the following conditions:
|
12
|
+
# * To be merged in the period between the days to check from and today. (90 days by default)
|
13
|
+
# * To have the label that we are querying ("type: fix" by default)
|
14
|
+
# * To not have any of the excluded labels (["backport", "no-backport"] by default)
|
15
|
+
# * To have been merged
|
16
|
+
#
|
17
|
+
# @param token [String] token for GitHub authentication
|
18
|
+
# @param days_to_check_from [Integer] the number of days since the pull requests were merged from when we will start the check
|
19
|
+
# @param label [String] the label that we want to search by
|
20
|
+
# @param exclude_labels [Array] the labels that we want to exclude in the search
|
21
|
+
#
|
22
|
+
# @see https://docs.github.com/en/rest/issues/issues#list-repository-issues GitHub API documentation
|
23
|
+
class ByLabel < Decidim::MaintainersToolbox::GithubManager::Querier::Base
|
24
|
+
def initialize(token:, days_to_check_from: 90, label: "type: fix", exclude_labels: ["backport", "no-backport"])
|
25
|
+
@label = label
|
26
|
+
@exclude_labels = exclude_labels
|
27
|
+
@token = token
|
28
|
+
@days_to_check_from = days_to_check_from
|
29
|
+
end
|
30
|
+
|
31
|
+
# Makes the GET request and parses the response of an Issue or Pull Request in GitHub
|
32
|
+
#
|
33
|
+
# @return [Hash]
|
34
|
+
def call
|
35
|
+
parse json_response("https://api.github.com/repos/decidim/decidim/issues")
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :label, :exclude_labels, :days_to_check_from
|
41
|
+
|
42
|
+
def headers
|
43
|
+
Time.zone = "UTC"
|
44
|
+
|
45
|
+
{
|
46
|
+
labels: label,
|
47
|
+
state: "closed",
|
48
|
+
per_page: 100,
|
49
|
+
since: since.iso8601
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def since
|
54
|
+
Time.zone.today - days_to_check_from
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parses the response of an Issue or Pull Request in GitHub
|
58
|
+
#
|
59
|
+
# @return [Hash]
|
60
|
+
def parse(metadata)
|
61
|
+
metadata.map do |item|
|
62
|
+
next if has_any_of_excluded_labels?(item)
|
63
|
+
next unless merged?(item)
|
64
|
+
next unless merged_in_date_range?(item)
|
65
|
+
|
66
|
+
{
|
67
|
+
id: item["number"],
|
68
|
+
title: item["title"]
|
69
|
+
}
|
70
|
+
end.compact
|
71
|
+
end
|
72
|
+
|
73
|
+
def has_any_of_excluded_labels?(item)
|
74
|
+
item["labels"].map { |label| label.map { |_key, val| exclude_labels.include?(val) } }.flatten.any? true
|
75
|
+
end
|
76
|
+
|
77
|
+
def merged_at(item)
|
78
|
+
Date.parse(item["pull_request"]["merged_at"])
|
79
|
+
end
|
80
|
+
|
81
|
+
def merged?(item)
|
82
|
+
return false if item["pull_request"].nil?
|
83
|
+
return false if item["pull_request"]["merged_at"].nil?
|
84
|
+
|
85
|
+
merged_at(item).present?
|
86
|
+
rescue TypeError, Date::Error
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
90
|
+
def merged_in_date_range?(item)
|
91
|
+
merged_at(item) > since
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module MaintainersToolbox
|
7
|
+
module GithubManager
|
8
|
+
module Querier
|
9
|
+
# Makes a GET request for the list of Issues or Pull Requests in GitHub.
|
10
|
+
#
|
11
|
+
# @param token [String] token for GitHub authentication
|
12
|
+
# @param title [String] the title that we want to search by
|
13
|
+
# @param state [String] the state of the issue. By default is "open"
|
14
|
+
#
|
15
|
+
# @see https://docs.github.com/en/rest/issues/issues#list-repository-issues GitHub API documentation
|
16
|
+
class ByTitle < Decidim::MaintainersToolbox::GithubManager::Querier::Base
|
17
|
+
def initialize(title:, token:, state: "open")
|
18
|
+
@title = title
|
19
|
+
@token = token
|
20
|
+
@state = state
|
21
|
+
end
|
22
|
+
|
23
|
+
# Makes the GET request and parses the response of an Issue or Pull Request in GitHub
|
24
|
+
#
|
25
|
+
# @return [Hash]
|
26
|
+
def call
|
27
|
+
data = json_response("https://api.github.com/repos/decidim/decidim/issues")
|
28
|
+
|
29
|
+
parse(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :title, :state
|
35
|
+
|
36
|
+
def headers
|
37
|
+
{
|
38
|
+
title: title,
|
39
|
+
state: state,
|
40
|
+
per_page: 100
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Parses the response of an Issue or Pull Request in GitHub
|
45
|
+
#
|
46
|
+
# @return [Hash]
|
47
|
+
def parse(metadata)
|
48
|
+
metadata.map do |item|
|
49
|
+
{
|
50
|
+
id: item["number"],
|
51
|
+
title: item["title"]
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module MaintainersToolbox
|
7
|
+
module GithubManager
|
8
|
+
module Querier
|
9
|
+
# Makes a GET request for the related issues of an Issue or Pull Request in GitHub
|
10
|
+
# Uses the Timeline events API endpoint
|
11
|
+
#
|
12
|
+
# @see https://docs.github.com/en/rest/issues/timeline?apiVersion=2022-11-28 GitHub API documentation
|
13
|
+
class RelatedIssues < Decidim::MaintainersToolbox::GithubManager::Querier::Base
|
14
|
+
def initialize(issue_id:, token:)
|
15
|
+
@issue_id = issue_id
|
16
|
+
@token = token
|
17
|
+
end
|
18
|
+
|
19
|
+
# Makes the GET request and parses the response of an Issue or Pull Request in GitHub
|
20
|
+
#
|
21
|
+
# @return [Hash]
|
22
|
+
def call
|
23
|
+
parse(json_response("https://api.github.com/repos/decidim/decidim/issues/#{@issue_id}/timeline"))
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def headers
|
29
|
+
{ per_page: 100 }
|
30
|
+
end
|
31
|
+
|
32
|
+
# Parses the response of an Issue or Pull Request in GitHub
|
33
|
+
#
|
34
|
+
# @return [Hash]
|
35
|
+
def parse(metadata)
|
36
|
+
references = metadata.select do |item|
|
37
|
+
item["event"] == "cross-referenced" && item["source"]["issue"]["repository"]["full_name"] == "decidim/decidim"
|
38
|
+
end
|
39
|
+
references.map do |item|
|
40
|
+
issue = item["source"]["issue"]
|
41
|
+
|
42
|
+
{
|
43
|
+
id: issue["number"],
|
44
|
+
title: issue["title"].strip,
|
45
|
+
state: issue.dig("pull_request", "merged_at").nil? ? issue["state"] : "merged"
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
require_relative "querier/by_issue_id"
|
7
|
+
require_relative "querier/by_label"
|
8
|
+
require_relative "querier/related_issues"
|
9
|
+
|
10
|
+
module Decidim
|
11
|
+
module MaintainersToolbox
|
12
|
+
module GithubManager
|
13
|
+
# Allows to make GET requests to GitHub Rest API about Issues and Pull Requests
|
14
|
+
# @see https://docs.github.com/en/rest
|
15
|
+
module Querier
|
16
|
+
autoload :ByIssueId, "decidim/maintainers_toolbox/github_manager/querier/by_issue_id"
|
17
|
+
autoload :ByLabel, "decidim/maintainers_toolbox/github_manager/querier/by_label"
|
18
|
+
autoload :ByTitle, "decidim/maintainers_toolbox/github_manager/querier/by_title"
|
19
|
+
autoload :RelatedIssues, "decidim/maintainers_toolbox/github_manager/querier/related_issues"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,287 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open3"
|
4
|
+
require_relative "github_manager/poster"
|
5
|
+
require_relative "github_manager/querier/by_title"
|
6
|
+
require_relative "changelog_generator"
|
7
|
+
|
8
|
+
module Decidim
|
9
|
+
module MaintainersToolbox
|
10
|
+
class Releaser
|
11
|
+
class InvalidMetadataError < StandardError; end
|
12
|
+
|
13
|
+
class InvalidBranchError < StandardError; end
|
14
|
+
|
15
|
+
class InvalidVersionTypeError < StandardError; end
|
16
|
+
|
17
|
+
DECIDIM_VERSION_FILE = ".decidim-version"
|
18
|
+
|
19
|
+
# @param token [String] token for GitHub authentication
|
20
|
+
# @param version_type [String] The kind of release that you want to prepare. Supported values: rc, minor, patch
|
21
|
+
# @param working_dir [String] current working directory. Useful for testing purposes
|
22
|
+
# @param exit_with_unstaged_changes [Boolean] wheter we should exit cowardly if there is any unstaged change
|
23
|
+
def initialize(token:, version_type:, working_dir: Dir.pwd, exit_with_unstaged_changes: false)
|
24
|
+
@token = token
|
25
|
+
@version_type = version_type
|
26
|
+
@working_dir = working_dir
|
27
|
+
@exit_with_unstaged_changes = exit_with_unstaged_changes
|
28
|
+
end
|
29
|
+
|
30
|
+
def call
|
31
|
+
Dir.chdir(@working_dir) do
|
32
|
+
exit_if_unstaged_changes if @exit_with_unstaged_changes
|
33
|
+
exit_if_pending_crowdin_pull_request
|
34
|
+
|
35
|
+
puts "Starting the release process for #{version_number} in 10 seconds"
|
36
|
+
sleep 10
|
37
|
+
|
38
|
+
run("git checkout #{release_branch}")
|
39
|
+
run("git pull origin #{release_branch}")
|
40
|
+
bump_decidim_version
|
41
|
+
run("bin/rake update_versions")
|
42
|
+
run("bin/rake patch_generators")
|
43
|
+
run("bin/rake bundle")
|
44
|
+
run("npm install")
|
45
|
+
|
46
|
+
check_tests
|
47
|
+
|
48
|
+
generate_changelog
|
49
|
+
|
50
|
+
run("git checkout -b chore/prepare/#{version_number}")
|
51
|
+
run("git commit -a -m 'Prepare #{version_number} release'")
|
52
|
+
run("git push origin chore/prepare/#{version_number}")
|
53
|
+
|
54
|
+
create_pull_request
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# The git branch
|
61
|
+
#
|
62
|
+
# @return [String]
|
63
|
+
def branch
|
64
|
+
@branch ||= capture("git rev-parse --abbrev-ref HEAD")[0].strip
|
65
|
+
end
|
66
|
+
|
67
|
+
# Raise an error if the branch does not start with the preffix "release/"
|
68
|
+
# or returns the branch name
|
69
|
+
#
|
70
|
+
# @raise [InvalidBranchError]
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def release_branch
|
74
|
+
raise InvalidBranchError, "This is not a release branch, aborting" unless branch.start_with?("release/")
|
75
|
+
|
76
|
+
branch
|
77
|
+
end
|
78
|
+
|
79
|
+
# Changes the decidim version in the file
|
80
|
+
#
|
81
|
+
# @return [void]
|
82
|
+
def bump_decidim_version
|
83
|
+
File.write(DECIDIM_VERSION_FILE, version_number)
|
84
|
+
end
|
85
|
+
|
86
|
+
# The version number for the release that we are preparing
|
87
|
+
#
|
88
|
+
# @todo support the "minor" type version
|
89
|
+
#
|
90
|
+
# @return [String] the version number
|
91
|
+
def version_number
|
92
|
+
@version_number ||= case @version_type
|
93
|
+
when "rc"
|
94
|
+
next_version_number_for_release_candidate(old_version_number)
|
95
|
+
when "patch"
|
96
|
+
next_version_number_for_patch_release(old_version_number)
|
97
|
+
else
|
98
|
+
raise InvalidVersionTypeError, "This is not a supported version type"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def parsed_version_number(version_number)
|
103
|
+
/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/ =~ version_number
|
104
|
+
|
105
|
+
[major.to_i, minor.to_i, patch.to_i]
|
106
|
+
end
|
107
|
+
|
108
|
+
# Given a version number, returns the next release candidate
|
109
|
+
#
|
110
|
+
# If the current version number is `dev`, then we return the `rc1` version
|
111
|
+
# If the current version number is `rc`, then we return the next `rc` version
|
112
|
+
# Else, it means is a `minor` or `patch` version. On those cases we raise an Exception, as releases candidates should
|
113
|
+
# be only done from a `dev` or a `rc` version.
|
114
|
+
#
|
115
|
+
# @raise [InvalidVersionTypeError]
|
116
|
+
#
|
117
|
+
# @param current_version_number [String] - The version number of the current version
|
118
|
+
#
|
119
|
+
# @return [String] - the new version number
|
120
|
+
def next_version_number_for_release_candidate(current_version_number)
|
121
|
+
if current_version_number.include? "dev"
|
122
|
+
major, minor, patch = parsed_version_number(current_version_number)
|
123
|
+
new_version_number = "#{major}.#{minor}.#{patch}.rc1"
|
124
|
+
elsif current_version_number.include? "rc"
|
125
|
+
new_rc_number = current_version_number.match(/rc(\d)/)[1].to_i + 1
|
126
|
+
new_version_number = current_version_number.gsub(/rc\d/, "rc#{new_rc_number}")
|
127
|
+
else
|
128
|
+
error_message = <<-EOMESSAGE
|
129
|
+
Trying to do a release candidate version from patch release. Bailing out.
|
130
|
+
You need to do a release candidate from a `dev` or from another `rc` version
|
131
|
+
EOMESSAGE
|
132
|
+
raise InvalidVersionTypeError, error_message
|
133
|
+
end
|
134
|
+
|
135
|
+
new_version_number
|
136
|
+
end
|
137
|
+
|
138
|
+
# Given a version number, returns the next patch release
|
139
|
+
#
|
140
|
+
# If the current version number is `dev`, then we raise an Exception, as you need to first do a release candidate.
|
141
|
+
# If the current version number is `rc`, then we return the `0` patch version
|
142
|
+
# Else, it means is a `patch` version, so we return the next patch version
|
143
|
+
#
|
144
|
+
# @raise [InvalidVersionTypeError]
|
145
|
+
#
|
146
|
+
# @param current_version_number [String] - The version number of the current version
|
147
|
+
#
|
148
|
+
# @return [String] - the new version number
|
149
|
+
def next_version_number_for_patch_release(current_version_number)
|
150
|
+
major, minor, patch = parsed_version_number(current_version_number)
|
151
|
+
|
152
|
+
if current_version_number.include? "dev"
|
153
|
+
error_message = <<-EOMESSAGE
|
154
|
+
Trying to do a patch version from dev release. Bailing out.
|
155
|
+
You need to do first a release candidate.
|
156
|
+
EOMESSAGE
|
157
|
+
raise InvalidVersionTypeError, error_message
|
158
|
+
elsif current_version_number.include? "rc"
|
159
|
+
new_version_number = "#{major}.#{minor}.0"
|
160
|
+
else
|
161
|
+
new_version_number = "#{major}.#{minor}.#{patch.to_i + 1}"
|
162
|
+
end
|
163
|
+
|
164
|
+
new_version_number
|
165
|
+
end
|
166
|
+
|
167
|
+
# The version number from the file
|
168
|
+
#
|
169
|
+
# @return [String] the version number
|
170
|
+
def old_version_number
|
171
|
+
File.read(DECIDIM_VERSION_FILE).strip
|
172
|
+
end
|
173
|
+
|
174
|
+
# Run the tests and if fails restore the changes using git and exit with an error
|
175
|
+
#
|
176
|
+
# @return [void]
|
177
|
+
def check_tests
|
178
|
+
puts "Running specs"
|
179
|
+
output, status = capture("bin/rspec")
|
180
|
+
|
181
|
+
unless status.success?
|
182
|
+
run("git restore .")
|
183
|
+
puts output
|
184
|
+
exit_with_errors("Tests execution failed. Fix the errors and run again.")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Generates the changelog taking into account the last time the version changed
|
189
|
+
#
|
190
|
+
# @return [void]
|
191
|
+
def generate_changelog
|
192
|
+
sha_version = capture("git log -n 1 --pretty=format:%h -- .decidim-version")[0]
|
193
|
+
ChangeLogGenerator.new(token: @token, since_sha: sha_version).call
|
194
|
+
temporary_changelog = File.read("./temporary_changelog.md")
|
195
|
+
legacy_changelog = File.read("./CHANGELOG.md")
|
196
|
+
version_changelog = "## [#{version_number}](https://github.com/decidim/decidim/tree/#{version_number})\n\n#{temporary_changelog}\n"
|
197
|
+
changelog = legacy_changelog.gsub("# Changelog\n\n", "# Changelog\n\n#{version_changelog}")
|
198
|
+
File.write("./CHANGELOG.md", changelog)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Creates the pull request for bumping the version
|
202
|
+
#
|
203
|
+
# @return [void]
|
204
|
+
def create_pull_request
|
205
|
+
base_branch = release_branch
|
206
|
+
head_branch = "chore/prepare/#{version_number}"
|
207
|
+
|
208
|
+
params = {
|
209
|
+
title: "Bump to v#{version_number} version",
|
210
|
+
body: "#### :tophat: What? Why?
|
211
|
+
|
212
|
+
This PR changes the version of the #{release_branch} branch, so we can publish the release once this is approved and merged.
|
213
|
+
|
214
|
+
#### Testing
|
215
|
+
|
216
|
+
All the tests should pass, except for some generators tests, that will fail because the gems and NPM packages have not
|
217
|
+
been actually published yet (as in sent to rubygems/npm).
|
218
|
+
You will see errors such as `No matching version found for @decidim/browserslist-config@~0.xx.y` in the CI logs.
|
219
|
+
|
220
|
+
:hearts: Thank you!
|
221
|
+
",
|
222
|
+
labels: ["type: internal"],
|
223
|
+
head: head_branch,
|
224
|
+
base: base_branch
|
225
|
+
}
|
226
|
+
Decidim::MaintainersToolbox::GithubManager::Poster.new(token: @token, params: params).call
|
227
|
+
end
|
228
|
+
|
229
|
+
# Captures to output of a command
|
230
|
+
#
|
231
|
+
# @return [Array<String, Process::Status>] The stdout and stderr of the command and its status (aka error code)
|
232
|
+
def capture(cmd, env: {})
|
233
|
+
Open3.capture2e(env, cmd)
|
234
|
+
end
|
235
|
+
|
236
|
+
# Runs a command
|
237
|
+
#
|
238
|
+
# @return [void]
|
239
|
+
def run(cmd, out: $stdout)
|
240
|
+
system(cmd, out: out)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Check if there is any open pull request from Crowdin in GitHub
|
244
|
+
#
|
245
|
+
# @return [Boolean] - true if there is any open PR
|
246
|
+
def pending_crowdin_pull_requests?
|
247
|
+
pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByTitle.new(token: @token, title: "New Crowdin updates").call
|
248
|
+
pull_requests.any?
|
249
|
+
end
|
250
|
+
|
251
|
+
# Exit the script execution if there are any pull request from Crowdin open
|
252
|
+
#
|
253
|
+
# @return [void]
|
254
|
+
def exit_if_pending_crowdin_pull_request
|
255
|
+
return unless pending_crowdin_pull_requests?
|
256
|
+
|
257
|
+
error_message = <<-EOERROR
|
258
|
+
There are open pull requests from Crowdin in GitHub
|
259
|
+
Merge them and run again this script.
|
260
|
+
EOERROR
|
261
|
+
exit_with_errors(error_message)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Exit the script execution with a message
|
265
|
+
# Exit the script execution if there are any unstaged changes
|
266
|
+
#
|
267
|
+
# @return [void]
|
268
|
+
def exit_if_unstaged_changes
|
269
|
+
return if `git diff`.empty?
|
270
|
+
|
271
|
+
error_message = <<-EOERROR
|
272
|
+
There are changes not staged in your project.
|
273
|
+
Please commit your changes or stash them.
|
274
|
+
EOERROR
|
275
|
+
exit_with_errors(error_message)
|
276
|
+
end
|
277
|
+
|
278
|
+
# Exit the script execution with a message
|
279
|
+
#
|
280
|
+
# @return [void]
|
281
|
+
def exit_with_errors(message)
|
282
|
+
puts message
|
283
|
+
exit 1
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: decidim-maintainers_toolbox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrés Pereira de Lucena
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-03-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ruby-progressbar
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 6.1.7
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 6.1.7
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.18'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.18'
|
97
|
+
description: Tools for releasing, backporting, changelog generating, and working with
|
98
|
+
GitHub
|
99
|
+
email:
|
100
|
+
- andreslucena@gmail.com
|
101
|
+
executables:
|
102
|
+
- decidim-backporter
|
103
|
+
- decidim-backports-checker
|
104
|
+
- decidim-changelog-generator
|
105
|
+
- decidim-releaser
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- README.md
|
110
|
+
- decidim-maintainers_toolbox.gemspec
|
111
|
+
- exe/decidim-backporter
|
112
|
+
- exe/decidim-backports-checker
|
113
|
+
- exe/decidim-changelog-generator
|
114
|
+
- exe/decidim-releaser
|
115
|
+
- lib/decidim/maintainers_toolbox.rb
|
116
|
+
- lib/decidim/maintainers_toolbox/backporter.rb
|
117
|
+
- lib/decidim/maintainers_toolbox/backports_reporter/cli_report.rb
|
118
|
+
- lib/decidim/maintainers_toolbox/backports_reporter/csv_report.rb
|
119
|
+
- lib/decidim/maintainers_toolbox/backports_reporter/report.rb
|
120
|
+
- lib/decidim/maintainers_toolbox/changelog_generator.rb
|
121
|
+
- lib/decidim/maintainers_toolbox/git_backport_checker.rb
|
122
|
+
- lib/decidim/maintainers_toolbox/git_backport_manager.rb
|
123
|
+
- lib/decidim/maintainers_toolbox/github_manager/poster.rb
|
124
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier.rb
|
125
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/base.rb
|
126
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id.rb
|
127
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/by_label.rb
|
128
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/by_title.rb
|
129
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/related_issues.rb
|
130
|
+
- lib/decidim/maintainers_toolbox/releaser.rb
|
131
|
+
- lib/decidim/maintainers_toolbox/version.rb
|
132
|
+
homepage: https://decidim.org
|
133
|
+
licenses:
|
134
|
+
- AGPL-3.0
|
135
|
+
metadata:
|
136
|
+
bug_tracker_uri: https://github.com/decidim/decidim/issues
|
137
|
+
documentation_uri: https://docs.decidim.org/
|
138
|
+
funding_uri: https://opencollective.com/decidim
|
139
|
+
homepage_uri: https://decidim.org
|
140
|
+
source_code_uri: https://github.com/decidim/decidim
|
141
|
+
post_install_message:
|
142
|
+
rdoc_options: []
|
143
|
+
require_paths:
|
144
|
+
- lib
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 2.7.5
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
requirements: []
|
156
|
+
rubygems_version: 3.1.6
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: Release related tools for the Decidim project
|
160
|
+
test_files: []
|