gh_draft_issues_conerter 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5d5bc58f8fe58746a0118f9ba194049141d6bec1627c093434349183d9633064
4
+ data.tar.gz: d2a288fbd37cdca69e17b0f4f9244b53c7f6e5bc220d7a92d139587dbc60d7b4
5
+ SHA512:
6
+ metadata.gz: f48081331c0d159a3a4a39962a786fe343c51f821465001ae2778f463d7d51a5a28e0254f48846e6496d42e8b629119edfd3a792be9756cba83b5755126be187
7
+ data.tar.gz: 3f48a9ab22191c40ee8eca092be41aee23aeae23fd93dd9ec5cae8ce61935c17dc4326e8a32059cf79f3af9a3e51ffceb4c4cd187beaaa6b2ece0974493dec95
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "graphlient"
6
+ gem "rake", "~> 13.0"
7
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (7.2.1)
5
+ base64
6
+ bigdecimal
7
+ concurrent-ruby (~> 1.0, >= 1.3.1)
8
+ connection_pool (>= 2.2.5)
9
+ drb
10
+ i18n (>= 1.6, < 2)
11
+ logger (>= 1.4.2)
12
+ minitest (>= 5.1)
13
+ securerandom (>= 0.3)
14
+ tzinfo (~> 2.0, >= 2.0.5)
15
+ base64 (0.2.0)
16
+ bigdecimal (3.1.8)
17
+ concurrent-ruby (1.3.4)
18
+ connection_pool (2.4.1)
19
+ diff-lcs (1.5.1)
20
+ drb (2.2.1)
21
+ faraday (2.11.0)
22
+ faraday-net_http (>= 2.0, < 3.4)
23
+ logger
24
+ faraday-net_http (3.3.0)
25
+ net-http
26
+ fiber-storage (1.0.0)
27
+ graphlient (0.8.0)
28
+ faraday (~> 2.0)
29
+ graphql-client
30
+ graphql (2.3.14)
31
+ base64
32
+ fiber-storage
33
+ graphql-client (0.23.0)
34
+ activesupport (>= 3.0)
35
+ graphql (>= 1.13.0)
36
+ i18n (1.14.5)
37
+ concurrent-ruby (~> 1.0)
38
+ logger (1.6.0)
39
+ minitest (5.25.1)
40
+ net-http (0.4.1)
41
+ uri
42
+ rake (13.2.1)
43
+ rspec (3.13.0)
44
+ rspec-core (~> 3.13.0)
45
+ rspec-expectations (~> 3.13.0)
46
+ rspec-mocks (~> 3.13.0)
47
+ rspec-core (3.13.1)
48
+ rspec-support (~> 3.13.0)
49
+ rspec-expectations (3.13.2)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.13.0)
52
+ rspec-mocks (3.13.1)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.13.0)
55
+ rspec-support (3.13.1)
56
+ securerandom (0.3.1)
57
+ tzinfo (2.0.6)
58
+ concurrent-ruby (~> 1.0)
59
+ uri (0.13.1)
60
+
61
+ PLATFORMS
62
+ x86_64-linux
63
+
64
+ DEPENDENCIES
65
+ graphlient
66
+ rake (~> 13.0)
67
+ rspec (~> 3.0)
68
+
69
+ BUNDLED WITH
70
+ 2.4.10
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Akira kure
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Overview
2
+ A tool to batch convert Draft Issues to Issues in GitHub Projects.
3
+
4
+ # Installation
5
+
6
+ ```sh
7
+ % gem install gh_draft_issues_converter
8
+ ```
9
+
10
+ # Usage
11
+
12
+ Prerequisites:
13
+
14
+ - Project number (specify with `-p`)
15
+ - ex) "In the URL `https://github.com/users/kuredev/projects/1`, the `1` corresponds to the project number."
16
+ - Repository name (owner/repository, specify with `-r`)
17
+ - GitHub Personal Token (register it as `GITHUB_KEY`)
18
+
19
+ ## Example
20
+
21
+ ```sh
22
+ % gh_draft_issues_converter -p 1 -r kuredev/gh-draft-issues-converter
23
+ ```
24
+
25
+ # Limitations
26
+ - Only single-select custom fields will be migrated.
27
+ - Among standard fields, only the assignee will be migrated.
28
+
29
+ # Notes
30
+ To avoid rate limits with the CreateIssue API, a default interval of 25 seconds is set. This interval can be adjusted using the `-i` option.
31
+
32
+ https://github.com/cli/cli/issues/4801#issuecomment-1431812916
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "gh_draft_issues_conerter"
5
+
6
+ GhDraftIssuesConerter::CLI.start(ARGV)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/gh_draft_issues_conerter/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "gh_draft_issues_conerter"
7
+ spec.version = GhDraftIssuesConerter::VERSION
8
+ spec.authors = ["Akira Kure"]
9
+ spec.email = ["kuredev@users.noreply.github.com"]
10
+
11
+ spec.summary = "Convert GitHub's DraftIssues to Issues"
12
+ spec.description = "Convert GitHub's DraftIssues to Issues"
13
+ spec.homepage = "https://github.com/kuredev/gh_draft_issues_conerter"
14
+ spec.required_ruby_version = ">= 3.2.0"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/kuredev/gh_draft_issues_conerter"
18
+ spec.metadata["changelog_uri"] = "https://github.com/kuredev/gh_draft_issues_conerter"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(__dir__) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
25
+ end
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
32
+
33
+ # Uncomment to register a new dependency of your gem
34
+ spec.add_dependency "graphlient"
35
+
36
+ # For more information and examples about making a new gem, check out our
37
+ # guide at: https://bundler.io/guides/creating_gem.html
38
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ # Example
6
+ # bundle exec ruby gh_draft_issues_conerter --projects_number N --repository_name "XXX"
7
+
8
+ module GhDraftIssuesConerter
9
+ class CLI
10
+ def self.start(argv)
11
+ options = {}
12
+ options[:interval] = 25 # Default
13
+
14
+ OptionParser.new do |opts|
15
+ opts.banner = "Usage: bundle exec ruby gh-draft-issues-conerter --projects_number N --repository_name xxxxx"
16
+
17
+ opts.on("-p N", "--projects_number N", "project number") do |projects_number|
18
+ options[:projects_number] = projects_number.to_i
19
+ end
20
+
21
+ opts.on("-r NAME", "--repository_name NAME", "full repository name. ex: [owner]/[repository]") do |repository_name|
22
+ options[:repository_name] = repository_name
23
+ end
24
+
25
+ opts.on("-i SECONDS", "--interval SECONDS", "(option)interval seconds for create issue.default: 25s") do |interval|
26
+ options[:interval] = interval.to_i
27
+ end
28
+ end.parse!(argv)
29
+
30
+ # Check must option
31
+ if options[:projects_number].nil?
32
+ puts "Error: --projects_number option is required."
33
+ exit 1
34
+ end
35
+
36
+ # Check must option
37
+ if options[:repository_name].nil?
38
+ puts "Error: --repository_name option is required. ex: sample_user/sample_repository"
39
+ exit 1
40
+ end
41
+
42
+ if ENV["GITHUB_KEY"].nil?
43
+ puts "Environment value `GITHUB_KEY` is required."
44
+ exit 1
45
+ end
46
+
47
+ converter = GhDraftIssueConverter::Converter.new(ENV["GITHUB_KEY"])
48
+ repository = GhDraftIssueConverter::Repository.new(options[:repository_name])
49
+ converter.run(
50
+ options[:projects_number],
51
+ repository,
52
+ options[:interval],
53
+ )
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,362 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphlient"
4
+
5
+ module GhDraftIssueConverter
6
+ class DraftIssue
7
+ attr_reader :id, :title, :body, :field_values, :assign_user_ids
8
+
9
+ # @param assign_user_ids [Array<String>]
10
+ # @field_values [Hash]
11
+ # [
12
+ # FieldValue, FieldValue
13
+ # ]
14
+ def initialize(id, title, body, assign_user_ids, field_values)
15
+ @id = id
16
+ @title = title
17
+ @body = body
18
+ @field_values = field_values
19
+ @assign_user_ids = assign_user_ids
20
+ end
21
+
22
+ def unnecessary_for_convert_issue?
23
+ false
24
+
25
+ #field_values.any? do |field_value|
26
+ # field_value.field_name == "Status" && field_value.field_value_name == "🚫unnecessary"
27
+ #end
28
+ end
29
+
30
+ def user_ids_github_format
31
+ assign_user_ids.map { |id| "\"#{id}\""}.join(", ")
32
+ end
33
+ end
34
+
35
+ class FieldValue
36
+ attr_reader :field_value_id,
37
+ :field_value_name,
38
+ :field_value_option_id,
39
+ :field_id,
40
+ :field_name
41
+
42
+ def initialize(field_value_id, field_value_name, field_value_option_id, field_id, field_name)
43
+ @field_value_id = field_value_id
44
+ @field_value_name = field_value_name
45
+ @field_value_option_id = field_value_option_id
46
+ @field_id = field_id
47
+ @field_name = field_name
48
+ end
49
+ end
50
+
51
+ class Repository
52
+ attr_reader :full_repository_name
53
+ def initialize(full_repository_name)
54
+ parts = full_repository_name.split('/')
55
+
56
+ if full_repository_name.include?('/')
57
+ parts = full_repository_name.split('/')
58
+
59
+ if parts.length != 2
60
+ puts "repository_name is invalid"
61
+ exit 1
62
+ elsif parts[0].empty? || parts[1].empty?
63
+ puts "repository_name is invalid"
64
+ exit 1
65
+ else
66
+ # OK
67
+ end
68
+ else
69
+ puts "repository_name is invalid"
70
+ exit 1
71
+ end
72
+
73
+ @full_repository_name = full_repository_name
74
+ end
75
+
76
+ def name
77
+ full_repository_name.split("/")[1]
78
+ end
79
+
80
+ def owner
81
+ full_repository_name.split("/")[0]
82
+ end
83
+ end
84
+
85
+ class GhResoucesManager
86
+ attr_reader :client
87
+
88
+ def initialize(client)
89
+ @client = client
90
+ end
91
+
92
+ # @return [String] Issue ID
93
+ def add_issue_projectv2(project_id, issue_id)
94
+ response = client.query <<~GRAPHQL
95
+ mutation {
96
+ addProjectV2ItemById(input: {projectId: "#{project_id}", contentId: "#{issue_id}"}) {
97
+ item {
98
+ id
99
+ }
100
+ }
101
+ }
102
+ GRAPHQL
103
+
104
+ response.to_h["data"]["addProjectV2ItemById"]["item"]["id"]
105
+ end
106
+
107
+ def fetch_draft_issues(project_id)
108
+ # https://docs.github.com/ja/graphql/reference/objects#user
109
+ response = client.query <<~GRAPHQL
110
+ query {
111
+ node(id: "#{project_id}") {
112
+ ... on ProjectV2 {
113
+ items {
114
+ nodes {
115
+ id,
116
+ content {
117
+ ... on DraftIssue {
118
+ title
119
+ body
120
+ assignees(first: 10) {
121
+ nodes {
122
+ id
123
+ }
124
+ }
125
+ }
126
+ }
127
+ fieldValues(first: 10) {
128
+ nodes {
129
+ ... on ProjectV2ItemFieldSingleSelectValue {
130
+ id
131
+ optionId
132
+ name
133
+ field {
134
+ ... on ProjectV2SingleSelectField {
135
+ id
136
+ name
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ GRAPHQL
148
+
149
+ nodes = response.to_h["data"]["node"]["items"]["nodes"]
150
+ nodes.map do |node|
151
+ next if node["content"]["__typename"] == "Issue"
152
+
153
+ assign_user_ids = node["content"]["assignees"]["nodes"]
154
+ assign_user_ids = assign_user_ids.map { |item| item["id"] }
155
+
156
+ DraftIssue.new(
157
+ node["id"],
158
+ node["content"]["title"],
159
+ node["content"]["body"],
160
+ assign_user_ids,
161
+ convert_field_nodes_to_objs(node["fieldValues"]["nodes"])
162
+ )
163
+ end.compact
164
+ end
165
+
166
+ # @return [Array<FieldValue>]
167
+ def convert_field_nodes_to_objs(nodes)
168
+ nodes.map do |node|
169
+ next if node.empty?
170
+ next if node["__typename"] != "ProjectV2ItemFieldSingleSelectValue"
171
+
172
+ FieldValue.new(
173
+ node["id"],
174
+ node["name"],
175
+ node["optionId"],
176
+ node["field"]["id"],
177
+ node["field"]["name"]
178
+ )
179
+ end.compact
180
+ end
181
+
182
+ def fetch_project_id(project_number, repository)
183
+ owner_is_user = owner_is_user?(repository)
184
+ if owner_is_user
185
+ response = client.query <<~GRAPHQL
186
+ query {
187
+ user(login: "#{repository.owner}") {
188
+ projectV2(number: #{project_number}) {
189
+ id,
190
+ title
191
+ }
192
+ }
193
+ }
194
+ GRAPHQL
195
+ response.to_h["data"]["user"]["projectV2"]["id"]
196
+ else
197
+ response = client.query <<~GRAPHQL
198
+ query {
199
+ organization(login: "#{repository.owner}") {
200
+ projectV2(number: #{project_number}) {
201
+ id,
202
+ title
203
+ }
204
+ }
205
+ }
206
+ GRAPHQL
207
+ response.to_h["data"]["organization"]["projectV2"]["id"]
208
+ end
209
+ end
210
+
211
+ def fetch_repository_id(repository)
212
+ owner_is_user = owner_is_user?(repository)
213
+ if owner_is_user
214
+ response = client.query <<~GRAPHQL
215
+ query {
216
+ repository(owner: "#{repository.owner}", name: "#{repository.name}") {
217
+ id
218
+ }
219
+ }
220
+ GRAPHQL
221
+
222
+ response.to_h["data"]["repository"]["id"]
223
+ else
224
+ response = client.query <<~GRAPHQL
225
+ query {
226
+ organization(login: "#{repository.owner}") {
227
+ repository(name: "#{repository.name}") {
228
+ id
229
+ }
230
+ }
231
+ }
232
+ GRAPHQL
233
+
234
+ response.to_h["data"]["organization"]["repository"]["id"]
235
+ end
236
+ end
237
+
238
+ def update_item_field_values(project_id, draft_issue, item_id)
239
+ draft_issue.field_values.each do |field_value|
240
+ response = client.query <<~GRAPHQL
241
+ mutation {
242
+ updateProjectV2ItemFieldValue(input: {
243
+ projectId: "#{project_id}",
244
+ itemId: "#{item_id}",
245
+ fieldId: "#{field_value.field_id}",
246
+ value: {singleSelectOptionId: "#{field_value.field_value_option_id}"}}
247
+ ) {
248
+ projectV2Item {
249
+ id
250
+ }
251
+ }
252
+ }
253
+ GRAPHQL
254
+ end
255
+ end
256
+
257
+ # memo: https://docs.github.com/en/graphql/reference/input-objects#createissueinput
258
+ # @return [String] item_id
259
+ def create_issue_from_draft(draft_issue, repository_id, project_id)
260
+ response = client.query <<~GRAPHQL
261
+ mutation {
262
+ createIssue(input: {
263
+ repositoryId: "#{repository_id}",
264
+ assigneeIds: [#{draft_issue.user_ids_github_format}],
265
+ title: "#{draft_issue.title}",
266
+ body: "#{draft_issue.body.gsub("\n", "\\n").gsub('"', '\"')}"
267
+ }) {
268
+ issue {
269
+ id
270
+ }
271
+ }
272
+ }
273
+ GRAPHQL
274
+
275
+ response.original_hash["data"]["createIssue"]["issue"]["id"]
276
+ end
277
+
278
+ def delete_draft_issue(project_id, draft_issue)
279
+ response = client.query <<~GRAPHQL
280
+ mutation {
281
+ deleteProjectV2Item(input: {
282
+ projectId: "#{project_id}",
283
+ itemId: "#{draft_issue.id}"
284
+ }) {
285
+ clientMutationId
286
+ }
287
+ }
288
+ GRAPHQL
289
+ end
290
+
291
+ def owner_is_user?(repository)
292
+ response = client.query <<~GRAPHQL
293
+ query {
294
+ repositoryOwner(login: "#{repository.owner}") {
295
+ __typename
296
+ login
297
+ }
298
+ }
299
+ GRAPHQL
300
+
301
+ response.to_h["data"]["repositoryOwner"]["__typename"] == "User"
302
+ end
303
+ end
304
+
305
+ class Converter
306
+ def initialize(github_key)
307
+ client = Graphlient::Client.new(
308
+ 'https://api.github.com/graphql',
309
+ headers: {
310
+ 'Authorization' => "Bearer #{github_key}"
311
+ },
312
+ http_options: {
313
+ read_timeout: 20,
314
+ write_timeout: 30
315
+ }
316
+ )
317
+
318
+ @resource_manager = GhResoucesManager.new(client)
319
+ end
320
+
321
+ # @param [Number] project_number
322
+ # @param [Repository] repository
323
+ def run(project_number, repository, interval = 25)
324
+ repository_id = @resource_manager.fetch_repository_id(repository)
325
+ project_id = @resource_manager.fetch_project_id(project_number, repository)
326
+
327
+ draft_issues = @resource_manager.fetch_draft_issues(project_id)
328
+ draft_issues.select! do |draft_issue|
329
+ !draft_issue.unnecessary_for_convert_issue?
330
+ end
331
+
332
+ draft_issues.each_with_index do |draft_issue, index|
333
+ puts "Converting: #{draft_issue.title}"
334
+
335
+ issue_repository_id = @resource_manager.create_issue_from_draft(
336
+ draft_issue,
337
+ repository_id,
338
+ project_id
339
+ )
340
+
341
+ puts "Add ProjectV2..."
342
+ issue_projectv2_id = @resource_manager.add_issue_projectv2(project_id, issue_repository_id)
343
+
344
+ puts "Update Field Values..."
345
+ @resource_manager.update_item_field_values(project_id, draft_issue, issue_projectv2_id)
346
+
347
+ puts "Delete DraftIssue..."
348
+ @resource_manager.delete_draft_issue(project_id, draft_issue)
349
+
350
+ puts "Complete Convert."
351
+
352
+ if index == draft_issues.length - 1
353
+ puts "All DraftIssue Converted."
354
+ else
355
+ # https://github.com/cli/cli/issues/4801#issuecomment-1431812916
356
+ puts "Sleep(25s) for rate limit..."
357
+ sleep interval
358
+ end
359
+ end
360
+ end
361
+ end
362
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhDraftIssuesConerter
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gh_draft_issues_conerter/version"
4
+ require_relative "gh_draft_issues_conerter/cli"
5
+ require_relative "gh_draft_issues_conerter/gh_draft_issues_conerter"
6
+
7
+ module GhDraftIssuesConerter
8
+ class Error < StandardError; end
9
+ end
@@ -0,0 +1,4 @@
1
+ module GhDraftIssuesConerter
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gh_draft_issues_conerter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Akira Kure
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: graphlient
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Convert GitHub's DraftIssues to Issues
28
+ email:
29
+ - kuredev@users.noreply.github.com
30
+ executables:
31
+ - gh_draft_issues_conerter
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE
38
+ - README.md
39
+ - Rakefile
40
+ - exe/gh_draft_issues_conerter
41
+ - gh_draft_issues_conerter.gemspec
42
+ - lib/gh_draft_issues_conerter.rb
43
+ - lib/gh_draft_issues_conerter/cli.rb
44
+ - lib/gh_draft_issues_conerter/gh_draft_issues_conerter.rb
45
+ - lib/gh_draft_issues_conerter/version.rb
46
+ - sig/gh_draft_issues_conerter.rbs
47
+ homepage: https://github.com/kuredev/gh_draft_issues_conerter
48
+ licenses: []
49
+ metadata:
50
+ homepage_uri: https://github.com/kuredev/gh_draft_issues_conerter
51
+ source_code_uri: https://github.com/kuredev/gh_draft_issues_conerter
52
+ changelog_uri: https://github.com/kuredev/gh_draft_issues_conerter
53
+ allowed_push_host: https://rubygems.org
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 3.2.0
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubygems_version: 3.4.10
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Convert GitHub's DraftIssues to Issues
73
+ test_files: []