decidim-maintainers_toolbox 0.1.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: 98bbc7bc7f2fe89db2430fe013218ed8f73139241148f81e2b836001341a9edb
4
- data.tar.gz: b2fcf684927d644818e40a3b47542bc9e71159ff8a220de40f45f7c02d479d90
3
+ metadata.gz: 28f518a4728ae94af5041c325e6c3814af3e48740d9c3e6cb28c2f3c83a358f2
4
+ data.tar.gz: 8700cc97ce988b8500e30961bd1d157f435971b5ea726769bd7df25a8d14e09c
5
5
  SHA512:
6
- metadata.gz: e9fcb49b88f506a3d8522ed38afe5253bb6cbdff6f66287ce9e5d9b24800f37d10756784999b9ef3944c7a338ffb088d0216da9232d2b77f604a36dbb40cb7d9
7
- data.tar.gz: 919e40cba79bb9d64c4cdaf6a7ec485423ffb64017f063ea696be0a5249e9d9eafd4bbf68c7cc85ee7aaf2059c3e083a637273e7f8b132953294f1fdc07c6c7b
6
+ metadata.gz: 953bb3fd9f7d34dc69797e0d40b874c6c6192a3250ec8533d65da67c32767ddff79b3776ba73d96cc29f595073f0234c4766a64205c28826998bb008441c3ae2
7
+ data.tar.gz: 1da57e99537368d5af2065745b5808888ef7738ebf2faee5d4d282f5217f726fde64fa492b74ceb784c94109cb0bb3135de0460ec8ec6a1d5c65dcb41c84867a
data/README.md CHANGED
@@ -55,11 +55,10 @@ To release this gem, follow these steps:
55
55
 
56
56
  1. Bump the version number in `lib/decidim/maintainers_toolbox/version.rb` following [Semantic Versioning](https://semver.org/).
57
57
  1. Update the `CHANGELOG.md` with the new version and the changes.
58
- 1. Commit the changes.
59
- 1. Create a new tag with the version number.
60
- 1. Push the changes and the tag to the repository.
61
- 1. Run `rake build` to build the gem.
62
- 1. Run `rake release` to publish the gem to [rubygems.org](https://rubygems.org).
58
+ 1. Commit the changes: `git commit -m "Prepare release v0.1.0"`
59
+ 1. Create the new tag, push the changs, build and publish with `bundle exec rake release[origin]`
60
+
61
+ Mind that you will need to have the right permissions to push to the repository and publish the gem.
63
62
 
64
63
  ## Contributing
65
64
 
@@ -37,11 +37,11 @@ Gem::Specification.new do |spec|
37
37
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
38
38
  spec.require_paths = ["lib"]
39
39
 
40
+ spec.add_dependency "activesupport", "~> 6.1.7"
40
41
  spec.add_dependency "faraday", "~> 1.10"
41
42
  spec.add_dependency "ruby-progressbar", "~> 1.7"
42
43
  spec.add_dependency "thor", "~> 1.0"
43
44
 
44
- spec.add_development_dependency "activesupport", "~> 6.1.7"
45
45
  spec.add_development_dependency "rspec", "~> 3.12"
46
46
  spec.add_development_dependency "webmock", "~> 3.18"
47
47
  end
@@ -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.1.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-maintainers_toolbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.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-03-15 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
- name: faraday
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.10'
19
+ version: 6.1.7
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.10'
26
+ version: 6.1.7
27
27
  - !ruby/object:Gem::Dependency
28
- name: ruby-progressbar
28
+ name: faraday
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.7'
33
+ version: '1.10'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.7'
40
+ version: '1.10'
41
41
  - !ruby/object:Gem::Dependency
42
- name: thor
42
+ name: ruby-progressbar
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.0'
47
+ version: '1.7'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.0'
54
+ version: '1.7'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activesupport
56
+ name: thor
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 6.1.7
62
- type: :development
61
+ version: '1.0'
62
+ type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 6.1.7
68
+ version: '1.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -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: []