decidim-maintainers_toolbox 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|