decidim-maintainers_toolbox 0.2.0 → 0.3.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 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: []