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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0b9ae7866429214e90e126591375eac79e09fdc47cf2fb49f6e8bdf69a20c3d
4
- data.tar.gz: 30e89f1df16e431b83201ca802e3b85a6de707cdd6c7a8d9d6f0efa0a2949676
3
+ metadata.gz: 28f518a4728ae94af5041c325e6c3814af3e48740d9c3e6cb28c2f3c83a358f2
4
+ data.tar.gz: 8700cc97ce988b8500e30961bd1d157f435971b5ea726769bd7df25a8d14e09c
5
5
  SHA512:
6
- metadata.gz: 571f60cad557dbd12773c93de4d8f2d14f42694338c134d9f0d7d83c9c3ade328df0e474c672208cf5211153b1e719cd8cc81c9841c4ba5cd70b43c5436db2f9
7
- data.tar.gz: 0b42c263e333d1c0bb8e18fb58db11bed8e1a491a3fab8f7291b15160b3ff7929c90ba69e4a911602e542a545c25fb93d45fdd070e95a23639ba88ba0d86eedf
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)
@@ -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
- puts "Resolve the cherrypick conflict manually and exit your shell to keep with the process."
100
- system ENV.fetch("SHELL")
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 title [String] the title that we want to search by
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 ByTitle < Decidim::MaintainersToolbox::GithubManager::Querier::Base
17
- def initialize(title:, token:, state: "open")
18
- @title = title
15
+ class ByQuery < Decidim::MaintainersToolbox::GithubManager::Querier::Base
16
+ def initialize(token:, query: {})
19
17
  @token = token
20
- @state = state
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 :title, :state
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 :ByTitle, "decidim/maintainers_toolbox/github_manager/querier/by_title"
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/by_title"
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::ByTitle.new(token: @token, title: "New Crowdin updates").call
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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Decidim
4
4
  module MaintainersToolbox
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
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.2.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-04-25 00:00:00.000000000 Z
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/by_title.rb
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: []