decidim-maintainers_toolbox 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/decidim-action-backporter +40 -0
- data/exe/decidim-backporter +5 -1
- data/lib/decidim/maintainers_toolbox/action_backporter.rb +98 -0
- data/lib/decidim/maintainers_toolbox/backporter.rb +5 -3
- data/lib/decidim/maintainers_toolbox/git_backport_manager.rb +11 -4
- data/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id.rb +3 -0
- data/lib/decidim/maintainers_toolbox/github_manager/querier/{by_title.rb → by_query.rb} +6 -10
- data/lib/decidim/maintainers_toolbox/github_manager/querier.rb +1 -1
- data/lib/decidim/maintainers_toolbox/releaser.rb +7 -3
- data/lib/decidim/maintainers_toolbox/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28f518a4728ae94af5041c325e6c3814af3e48740d9c3e6cb28c2f3c83a358f2
|
4
|
+
data.tar.gz: 8700cc97ce988b8500e30961bd1d157f435971b5ea726769bd7df25a8d14e09c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 953bb3fd9f7d34dc69797e0d40b874c6c6192a3250ec8533d65da67c32767ddff79b3776ba73d96cc29f595073f0234c4766a64205c28826998bb008441c3ae2
|
7
|
+
data.tar.gz: 1da57e99537368d5af2065745b5808888ef7738ebf2faee5d4d282f5217f726fde64fa492b74ceb784c94109cb0bb3135de0460ec8ec6a1d5c65dcb41c84867a
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "thor"
|
5
|
+
|
6
|
+
require_relative "../lib/decidim/maintainers_toolbox/github_manager/querier"
|
7
|
+
require_relative "../lib/decidim/maintainers_toolbox/action_backporter"
|
8
|
+
|
9
|
+
class ActionBackporterCLI < Thor
|
10
|
+
desc "", "Backport a pull request to another branch. This is intended to be run in the GitHub Action environment, for automating the backport processes."
|
11
|
+
option :github_token, required: true, desc: <<~HELP
|
12
|
+
Required. Github Personal Access Token (PAT). It can be obtained from https://github.com/settings/tokens/new. You will need to create one with `public_repo` access.
|
13
|
+
Alternatively, you can use the `gh` CLI tool to authenticate with `gh auth token` (i.e. --github-token=$(gh auth token))
|
14
|
+
HELP
|
15
|
+
option :pull_request_id, required: true, desc: "Required. The ID of the pull request that you want to make the backport from. It should have the \"type: fix\" label."
|
16
|
+
option :exit_with_unstaged_changes, type: :boolean, default: true, desc: <<~HELP
|
17
|
+
Optional. Whether the script should exit with an error if there are unstaged changes in the current project.
|
18
|
+
HELP
|
19
|
+
default_task :backport
|
20
|
+
|
21
|
+
def backport
|
22
|
+
Decidim::MaintainersToolbox::ActionBackporter.new(
|
23
|
+
token: options[:github_token],
|
24
|
+
pull_request_id: options[:pull_request_id],
|
25
|
+
exit_with_unstaged_changes: options[:exit_with_unstaged_changes]
|
26
|
+
).call
|
27
|
+
rescue Decidim::MaintainersToolbox::GithubManager::Querier::Base::InvalidMetadataError
|
28
|
+
puts "Metadata was not returned from the server. Please check that the provided pull request ID and GitHub token are correct."
|
29
|
+
end
|
30
|
+
|
31
|
+
def help
|
32
|
+
super("backport")
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.exit_on_failure?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
ActionBackporterCLI.start(ARGV)
|
data/exe/decidim-backporter
CHANGED
@@ -19,6 +19,9 @@ class BackporterCLI < Thor
|
|
19
19
|
option :exit_with_unstaged_changes, type: :boolean, default: true, desc: <<~HELP
|
20
20
|
Optional. Whether the script should exit with an error if there are unstaged changes in the current project.
|
21
21
|
HELP
|
22
|
+
option :with_console, required: false, type: :boolean, default: true, desc: <<~HELP
|
23
|
+
Optional. Disables the shell dropout
|
24
|
+
HELP
|
22
25
|
default_task :backport
|
23
26
|
|
24
27
|
def backport
|
@@ -26,7 +29,8 @@ class BackporterCLI < Thor
|
|
26
29
|
token: options[:github_token],
|
27
30
|
pull_request_id: options[:pull_request_id],
|
28
31
|
version_number: options[:version_number],
|
29
|
-
exit_with_unstaged_changes: options[:exit_with_unstaged_changes]
|
32
|
+
exit_with_unstaged_changes: options[:exit_with_unstaged_changes],
|
33
|
+
with_console: options[:with_console]
|
30
34
|
).call
|
31
35
|
rescue Decidim::MaintainersToolbox::GithubManager::Querier::Base::InvalidMetadataError
|
32
36
|
puts "Metadata was not returned from the server. Please check that the provided pull request ID and GitHub token are correct."
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "github_manager/querier"
|
4
|
+
require_relative "github_manager/poster"
|
5
|
+
require_relative "git_backport_manager"
|
6
|
+
|
7
|
+
module Decidim
|
8
|
+
module MaintainersToolbox
|
9
|
+
class ActionBackporter
|
10
|
+
class InvalidMetadataError < StandardError; end
|
11
|
+
|
12
|
+
DECIDIM_MAINTAINERS = ["alecslupu", "andreslucena"]
|
13
|
+
|
14
|
+
# @param token [String] token for GitHub authentication
|
15
|
+
# @param pull_request_id [String] the ID of the pull request that we want to backport
|
16
|
+
# @param exit_with_unstaged_changes [Boolean] wheter we should exit cowardly if there is any unstaged change
|
17
|
+
def initialize(token: , pull_request_id: ,exit_with_unstaged_changes: )
|
18
|
+
@token = token
|
19
|
+
@pull_request_id = pull_request_id
|
20
|
+
@exit_with_unstaged_changes = exit_with_unstaged_changes
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
exit_with_errors("The requested PR #{pull_request_id} does not contain `type: fix`") unless pull_request_metadata[:labels].include?("type: fix")
|
25
|
+
exit_with_errors("The requested PR #{pull_request_id} is not merged") unless pull_request_metadata[:is_merged]
|
26
|
+
exit_with_errors("The requested PR #{pull_request_id} cannot be backported") if pull_request_metadata[:labels].include?("no-backport")
|
27
|
+
|
28
|
+
extract_versions.each do |version|
|
29
|
+
next if extract_backport_pull_request_for_version(related_issues, version)
|
30
|
+
system("decidim-backporter --github_token=#{token} --pull_request_id=#{pull_request_id} --version_number=#{version} --exit_with_unstaged_changes=#{exit_with_unstaged_changes} --with-console=false", exception: true)
|
31
|
+
rescue RuntimeError => e
|
32
|
+
puts e.message
|
33
|
+
create_backport_issue(version)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :token, :pull_request_id, :exit_with_unstaged_changes
|
40
|
+
|
41
|
+
def create_backport_issue(version)
|
42
|
+
some_params = {
|
43
|
+
title: "Fail: automatic backport of \"#{pull_request_metadata[:title]}\"",
|
44
|
+
body: "Automatic backport of ##{pull_request_id} has failed for version #{version}. Please do this action manually.",
|
45
|
+
assignee: DECIDIM_MAINTAINERS,
|
46
|
+
labels: pull_request_metadata[:labels]
|
47
|
+
}
|
48
|
+
|
49
|
+
uri = "https://api.github.com/repos/decidim/decidim/issues"
|
50
|
+
Faraday.post(uri, some_params.to_json, { Authorization: "token #{token}" })
|
51
|
+
end
|
52
|
+
|
53
|
+
# same method exists in lib/decidim/maintainers_toolbox/backports_reporter/report.rb
|
54
|
+
def extract_backport_pull_request_for_version(related_issues, version)
|
55
|
+
related_issues = related_issues.select do |pull_request|
|
56
|
+
pull_request[:title].start_with?("Backport") && pull_request[:title].include?(version)
|
57
|
+
end
|
58
|
+
return if related_issues.empty?
|
59
|
+
|
60
|
+
related_issues.first
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_versions
|
64
|
+
return [] unless pull_request_metadata[:labels]
|
65
|
+
|
66
|
+
pull_request_metadata[:labels].map do |item|
|
67
|
+
item.match(/release: v(\d+\.\d+)/) { |m| m[1] }
|
68
|
+
end.compact
|
69
|
+
end
|
70
|
+
|
71
|
+
# Asks the metadata for a given issue or pull request on GitHub API
|
72
|
+
#
|
73
|
+
# @return [Faraday::Response] An instance that represents an HTTP response from making an HTTP request
|
74
|
+
# Same method exists in lib/decidim/maintainers_toolbox/backporter.rb
|
75
|
+
def pull_request_metadata
|
76
|
+
@pull_request_metadata ||= Decidim::MaintainersToolbox::GithubManager::Querier::ByIssueId.new(
|
77
|
+
token: token,
|
78
|
+
issue_id: pull_request_id
|
79
|
+
).call
|
80
|
+
end
|
81
|
+
|
82
|
+
def related_issues
|
83
|
+
@related_issues ||= Decidim::MaintainersToolbox::GithubManager::Querier::RelatedIssues.new(
|
84
|
+
token: token,
|
85
|
+
issue_id: pull_request_id
|
86
|
+
).call
|
87
|
+
end
|
88
|
+
|
89
|
+
# Exit the script execution with a message
|
90
|
+
#
|
91
|
+
# @return [void]
|
92
|
+
def exit_with_errors(message)
|
93
|
+
puts message
|
94
|
+
exit 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -9,11 +9,12 @@ module Decidim
|
|
9
9
|
# @param pull_request_id [String] the ID of the pull request that we want to backport
|
10
10
|
# @param version_number [String] the version number of the release that we want to make the backport to
|
11
11
|
# @param exit_with_unstaged_changes [Boolean] wheter we should exit cowardly if there is any unstaged change
|
12
|
-
def initialize(token:, pull_request_id:, version_number:, exit_with_unstaged_changes:)
|
12
|
+
def initialize(token:, pull_request_id:, version_number:, exit_with_unstaged_changes:, with_console:)
|
13
13
|
@token = token
|
14
14
|
@pull_request_id = pull_request_id
|
15
15
|
@version_number = version_number
|
16
16
|
@exit_with_unstaged_changes = exit_with_unstaged_changes
|
17
|
+
@with_console = with_console
|
17
18
|
end
|
18
19
|
|
19
20
|
# Handles the different tasks to create a backport:
|
@@ -32,7 +33,7 @@ module Decidim
|
|
32
33
|
|
33
34
|
private
|
34
35
|
|
35
|
-
attr_reader :token, :pull_request_id, :version_number, :exit_with_unstaged_changes
|
36
|
+
attr_reader :token, :pull_request_id, :version_number, :exit_with_unstaged_changes, :with_console
|
36
37
|
|
37
38
|
# Asks the metadata for a given issue or pull request on GitHub API
|
38
39
|
#
|
@@ -52,7 +53,8 @@ module Decidim
|
|
52
53
|
pull_request_id: pull_request_id,
|
53
54
|
release_branch: release_branch,
|
54
55
|
backport_branch: backport_branch(metadata[:title]),
|
55
|
-
exit_with_unstaged_changes: exit_with_unstaged_changes
|
56
|
+
exit_with_unstaged_changes: exit_with_unstaged_changes,
|
57
|
+
with_console: with_console
|
56
58
|
).call
|
57
59
|
end
|
58
60
|
|
@@ -14,12 +14,13 @@ module Decidim
|
|
14
14
|
# @param backport_branch [String] the name of the branch that we want to create
|
15
15
|
# @param working_dir [String] current working directory. Useful for testing purposes
|
16
16
|
# @param exit_with_unstaged_changes [Boolean] wheter we should exit cowardly if there is any unstaged change
|
17
|
-
def initialize(pull_request_id:, release_branch:, backport_branch:, working_dir: Dir.pwd, exit_with_unstaged_changes: false)
|
17
|
+
def initialize(pull_request_id:, release_branch:, backport_branch:, working_dir: Dir.pwd, exit_with_unstaged_changes: false, with_console: true)
|
18
18
|
@pull_request_id = pull_request_id
|
19
19
|
@release_branch = release_branch
|
20
20
|
@backport_branch = sanitize_branch(backport_branch)
|
21
21
|
@working_dir = working_dir
|
22
22
|
@exit_with_unstaged_changes = exit_with_unstaged_changes
|
23
|
+
@with_console = with_console
|
23
24
|
end
|
24
25
|
|
25
26
|
# Handles all the different tasks involved on a backport with the git command line utility
|
@@ -64,7 +65,7 @@ module Decidim
|
|
64
65
|
|
65
66
|
private
|
66
67
|
|
67
|
-
attr_reader :pull_request_id, :release_branch, :backport_branch, :working_dir
|
68
|
+
attr_reader :pull_request_id, :release_branch, :backport_branch, :working_dir, :with_console
|
68
69
|
|
69
70
|
# Create the backport branch based on a release branch
|
70
71
|
# Checks that this branch does not exist already, if it does then exits
|
@@ -96,8 +97,14 @@ module Decidim
|
|
96
97
|
`git cherry-pick #{sha_commit}`
|
97
98
|
|
98
99
|
unless $CHILD_STATUS.exitstatus.zero?
|
99
|
-
|
100
|
-
|
100
|
+
error_message = "Resolve the cherrypick conflict manually and exit your shell to keep with the process."
|
101
|
+
|
102
|
+
if with_console
|
103
|
+
puts error_message
|
104
|
+
system ENV.fetch("SHELL")
|
105
|
+
else
|
106
|
+
exit_with_errors(error_message)
|
107
|
+
end
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
@@ -35,6 +35,9 @@ module Decidim
|
|
35
35
|
|
36
36
|
{
|
37
37
|
id: metadata["number"],
|
38
|
+
state: metadata["state"],
|
39
|
+
is_pull_request: metadata["pull_request"].present?,
|
40
|
+
is_merged: (metadata["pull_request"]["merged_at"].present? rescue false),
|
38
41
|
title: metadata["title"],
|
39
42
|
labels: labels,
|
40
43
|
type: labels.select { |l| l.match(/^type: /) || l == "target: developer-experience" },
|
@@ -9,15 +9,13 @@ module Decidim
|
|
9
9
|
# Makes a GET request for the list of Issues or Pull Requests in GitHub.
|
10
10
|
#
|
11
11
|
# @param token [String] token for GitHub authentication
|
12
|
-
# @param
|
13
|
-
# @param state [String] the state of the issue. By default is "open"
|
12
|
+
# @param query [Hash] the query to search
|
14
13
|
#
|
15
14
|
# @see https://docs.github.com/en/rest/issues/issues#list-repository-issues GitHub API documentation
|
16
|
-
class
|
17
|
-
def initialize(
|
18
|
-
@title = title
|
15
|
+
class ByQuery < Decidim::MaintainersToolbox::GithubManager::Querier::Base
|
16
|
+
def initialize(token:, query: {})
|
19
17
|
@token = token
|
20
|
-
@
|
18
|
+
@query = query
|
21
19
|
end
|
22
20
|
|
23
21
|
# Makes the GET request and parses the response of an Issue or Pull Request in GitHub
|
@@ -31,14 +29,12 @@ module Decidim
|
|
31
29
|
|
32
30
|
private
|
33
31
|
|
34
|
-
attr_reader :
|
32
|
+
attr_reader :query
|
35
33
|
|
36
34
|
def headers
|
37
35
|
{
|
38
|
-
title: title,
|
39
|
-
state: state,
|
40
36
|
per_page: 100
|
41
|
-
}
|
37
|
+
}.merge(query)
|
42
38
|
end
|
43
39
|
|
44
40
|
# Parses the response of an Issue or Pull Request in GitHub
|
@@ -15,7 +15,7 @@ module Decidim
|
|
15
15
|
module Querier
|
16
16
|
autoload :ByIssueId, "decidim/maintainers_toolbox/github_manager/querier/by_issue_id"
|
17
17
|
autoload :ByLabel, "decidim/maintainers_toolbox/github_manager/querier/by_label"
|
18
|
-
autoload :
|
18
|
+
autoload :ByQuery, "decidim/maintainers_toolbox/github_manager/querier/by_query"
|
19
19
|
autoload :RelatedIssues, "decidim/maintainers_toolbox/github_manager/querier/related_issues"
|
20
20
|
end
|
21
21
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "open3"
|
4
4
|
require_relative "github_manager/poster"
|
5
|
-
require_relative "github_manager/querier/
|
5
|
+
require_relative "github_manager/querier/by_query"
|
6
6
|
require_relative "changelog_generator"
|
7
7
|
|
8
8
|
module Decidim
|
@@ -37,11 +37,15 @@ module Decidim
|
|
37
37
|
|
38
38
|
run("git checkout #{release_branch}")
|
39
39
|
run("git pull origin #{release_branch}")
|
40
|
+
|
40
41
|
bump_decidim_version
|
41
42
|
run("bin/rake update_versions")
|
43
|
+
|
42
44
|
run("bin/rake patch_generators")
|
45
|
+
|
43
46
|
run("bin/rake bundle")
|
44
47
|
run("npm install")
|
48
|
+
run("bin/rake webpack") if Dir.exists?("decidim_app-design")
|
45
49
|
|
46
50
|
check_tests
|
47
51
|
|
@@ -176,7 +180,7 @@ module Decidim
|
|
176
180
|
# @return [void]
|
177
181
|
def check_tests
|
178
182
|
puts "Running specs"
|
179
|
-
output, status = capture("bin/rspec")
|
183
|
+
output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" })
|
180
184
|
|
181
185
|
unless status.success?
|
182
186
|
run("git restore .")
|
@@ -244,7 +248,7 @@ You will see errors such as `No matching version found for @decidim/browserslist
|
|
244
248
|
#
|
245
249
|
# @return [Boolean] - true if there is any open PR
|
246
250
|
def pending_crowdin_pull_requests?
|
247
|
-
pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::
|
251
|
+
pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery.new(token: @token, query: { title: "New Crowdin updates", creator: "decidim-bot" }).call
|
248
252
|
pull_requests.any?
|
249
253
|
end
|
250
254
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decidim-maintainers_toolbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrés Pereira de Lucena
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -99,6 +99,7 @@ description: Tools for releasing, backporting, changelog generating, and working
|
|
99
99
|
email:
|
100
100
|
- andreslucena@gmail.com
|
101
101
|
executables:
|
102
|
+
- decidim-action-backporter
|
102
103
|
- decidim-backporter
|
103
104
|
- decidim-backports-checker
|
104
105
|
- decidim-changelog-generator
|
@@ -108,11 +109,13 @@ extra_rdoc_files: []
|
|
108
109
|
files:
|
109
110
|
- README.md
|
110
111
|
- decidim-maintainers_toolbox.gemspec
|
112
|
+
- exe/decidim-action-backporter
|
111
113
|
- exe/decidim-backporter
|
112
114
|
- exe/decidim-backports-checker
|
113
115
|
- exe/decidim-changelog-generator
|
114
116
|
- exe/decidim-releaser
|
115
117
|
- lib/decidim/maintainers_toolbox.rb
|
118
|
+
- lib/decidim/maintainers_toolbox/action_backporter.rb
|
116
119
|
- lib/decidim/maintainers_toolbox/backporter.rb
|
117
120
|
- lib/decidim/maintainers_toolbox/backports_reporter/cli_report.rb
|
118
121
|
- lib/decidim/maintainers_toolbox/backports_reporter/csv_report.rb
|
@@ -125,7 +128,7 @@ files:
|
|
125
128
|
- lib/decidim/maintainers_toolbox/github_manager/querier/base.rb
|
126
129
|
- lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id.rb
|
127
130
|
- lib/decidim/maintainers_toolbox/github_manager/querier/by_label.rb
|
128
|
-
- lib/decidim/maintainers_toolbox/github_manager/querier/
|
131
|
+
- lib/decidim/maintainers_toolbox/github_manager/querier/by_query.rb
|
129
132
|
- lib/decidim/maintainers_toolbox/github_manager/querier/related_issues.rb
|
130
133
|
- lib/decidim/maintainers_toolbox/releaser.rb
|
131
134
|
- lib/decidim/maintainers_toolbox/version.rb
|
@@ -138,7 +141,7 @@ metadata:
|
|
138
141
|
funding_uri: https://opencollective.com/decidim
|
139
142
|
homepage_uri: https://decidim.org
|
140
143
|
source_code_uri: https://github.com/decidim/decidim
|
141
|
-
post_install_message:
|
144
|
+
post_install_message:
|
142
145
|
rdoc_options: []
|
143
146
|
require_paths:
|
144
147
|
- lib
|
@@ -154,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
157
|
version: '0'
|
155
158
|
requirements: []
|
156
159
|
rubygems_version: 3.1.6
|
157
|
-
signing_key:
|
160
|
+
signing_key:
|
158
161
|
specification_version: 4
|
159
162
|
summary: Release related tools for the Decidim project
|
160
163
|
test_files: []
|