makit 0.0.169 → 0.0.170

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.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -41
  3. data/exe/makit +5 -5
  4. data/lib/makit/apache.rb +28 -28
  5. data/lib/makit/auto.rb +48 -48
  6. data/lib/makit/azure/blob_storage.rb +257 -257
  7. data/lib/makit/azure/cli.rb +284 -284
  8. data/lib/makit/azure-pipelines.rb +187 -187
  9. data/lib/makit/cli/base.rb +17 -17
  10. data/lib/makit/cli/build_commands.rb +500 -500
  11. data/lib/makit/cli/generators/base_generator.rb +74 -74
  12. data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
  13. data/lib/makit/cli/generators/generator_factory.rb +49 -49
  14. data/lib/makit/cli/generators/node_generator.rb +50 -50
  15. data/lib/makit/cli/generators/ruby_generator.rb +77 -77
  16. data/lib/makit/cli/generators/rust_generator.rb +50 -50
  17. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
  18. data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
  19. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
  20. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +41 -41
  21. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
  22. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
  23. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
  24. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
  25. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
  26. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
  27. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
  28. data/lib/makit/cli/main.rb +78 -78
  29. data/lib/makit/cli/pipeline_commands.rb +311 -311
  30. data/lib/makit/cli/project_commands.rb +868 -868
  31. data/lib/makit/cli/repository_commands.rb +661 -661
  32. data/lib/makit/cli/strategy_commands.rb +207 -207
  33. data/lib/makit/cli/utility_commands.rb +521 -521
  34. data/lib/makit/commands/factory.rb +359 -359
  35. data/lib/makit/commands/middleware/base.rb +73 -73
  36. data/lib/makit/commands/middleware/cache.rb +248 -248
  37. data/lib/makit/commands/middleware/command_logger.rb +312 -312
  38. data/lib/makit/commands/middleware/validator.rb +269 -269
  39. data/lib/makit/commands/request.rb +316 -316
  40. data/lib/makit/commands/result.rb +323 -323
  41. data/lib/makit/commands/runner.rb +386 -386
  42. data/lib/makit/commands/strategies/base.rb +171 -171
  43. data/lib/makit/commands/strategies/child_process.rb +162 -162
  44. data/lib/makit/commands/strategies/factory.rb +136 -136
  45. data/lib/makit/commands/strategies/synchronous.rb +139 -139
  46. data/lib/makit/commands.rb +50 -50
  47. data/lib/makit/configuration/dotnet_project.rb +48 -48
  48. data/lib/makit/configuration/gitlab_helper.rb +61 -61
  49. data/lib/makit/configuration/project.rb +292 -292
  50. data/lib/makit/configuration/rakefile_helper.rb +43 -43
  51. data/lib/makit/configuration/step.rb +34 -34
  52. data/lib/makit/configuration/timeout.rb +74 -74
  53. data/lib/makit/configuration.rb +21 -21
  54. data/lib/makit/content/default_gitignore.rb +7 -7
  55. data/lib/makit/content/default_gitignore.txt +225 -225
  56. data/lib/makit/content/default_rakefile.rb +13 -13
  57. data/lib/makit/content/gem_rakefile.rb +16 -16
  58. data/lib/makit/context.rb +1 -1
  59. data/lib/makit/data.rb +49 -49
  60. data/lib/makit/directories.rb +170 -170
  61. data/lib/makit/directory.rb +262 -262
  62. data/lib/makit/docs/files.rb +89 -89
  63. data/lib/makit/docs/rake.rb +102 -102
  64. data/lib/makit/dotnet/cli.rb +224 -224
  65. data/lib/makit/dotnet/project.rb +217 -217
  66. data/lib/makit/dotnet/solution.rb +38 -38
  67. data/lib/makit/dotnet/solution_classlib.rb +239 -239
  68. data/lib/makit/dotnet/solution_console.rb +264 -264
  69. data/lib/makit/dotnet/solution_maui.rb +354 -354
  70. data/lib/makit/dotnet/solution_wasm.rb +275 -275
  71. data/lib/makit/dotnet/solution_wpf.rb +304 -304
  72. data/lib/makit/dotnet.rb +110 -110
  73. data/lib/makit/email.rb +90 -90
  74. data/lib/makit/environment.rb +142 -142
  75. data/lib/makit/examples/runner.rb +370 -370
  76. data/lib/makit/exceptions.rb +45 -45
  77. data/lib/makit/fileinfo.rb +32 -32
  78. data/lib/makit/files.rb +43 -43
  79. data/lib/makit/gems.rb +49 -49
  80. data/lib/makit/git/cli.rb +103 -103
  81. data/lib/makit/git/repository.rb +100 -100
  82. data/lib/makit/git.rb +104 -104
  83. data/lib/makit/github_actions.rb +202 -202
  84. data/lib/makit/gitlab/pipeline.rb +857 -857
  85. data/lib/makit/gitlab/pipeline_service_impl.rb +1535 -1535
  86. data/lib/makit/gitlab_runner.rb +59 -59
  87. data/lib/makit/humanize.rb +218 -218
  88. data/lib/makit/indexer.rb +47 -47
  89. data/lib/makit/io/filesystem.rb +111 -111
  90. data/lib/makit/io/filesystem_service_impl.rb +337 -337
  91. data/lib/makit/lint.rb +212 -212
  92. data/lib/makit/logging/configuration.rb +309 -309
  93. data/lib/makit/logging/format_registry.rb +84 -84
  94. data/lib/makit/logging/formatters/base.rb +39 -39
  95. data/lib/makit/logging/formatters/console_formatter.rb +140 -140
  96. data/lib/makit/logging/formatters/json_formatter.rb +65 -65
  97. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
  98. data/lib/makit/logging/formatters/text_formatter.rb +64 -64
  99. data/lib/makit/logging/log_request.rb +119 -119
  100. data/lib/makit/logging/logger.rb +199 -199
  101. data/lib/makit/logging/sinks/base.rb +91 -91
  102. data/lib/makit/logging/sinks/console.rb +72 -72
  103. data/lib/makit/logging/sinks/file_sink.rb +92 -92
  104. data/lib/makit/logging/sinks/structured.rb +123 -123
  105. data/lib/makit/logging/sinks/unified_file_sink.rb +296 -296
  106. data/lib/makit/logging.rb +578 -578
  107. data/lib/makit/markdown.rb +75 -75
  108. data/lib/makit/mp/basic_object_mp.rb +17 -17
  109. data/lib/makit/mp/command_mp.rb +13 -13
  110. data/lib/makit/mp/command_request.mp.rb +17 -17
  111. data/lib/makit/mp/project_mp.rb +199 -199
  112. data/lib/makit/mp/string_mp.rb +205 -205
  113. data/lib/makit/nuget.rb +460 -460
  114. data/lib/makit/podman/podman.rb +458 -458
  115. data/lib/makit/podman/podman_service_impl.rb +1081 -1081
  116. data/lib/makit/port.rb +32 -32
  117. data/lib/makit/process.rb +377 -377
  118. data/lib/makit/protoc.rb +112 -112
  119. data/lib/makit/rake/cli.rb +196 -196
  120. data/lib/makit/rake/trace_controller.rb +174 -174
  121. data/lib/makit/rake.rb +81 -81
  122. data/lib/makit/ruby/cli.rb +185 -185
  123. data/lib/makit/ruby.rb +25 -25
  124. data/lib/makit/rubygems.rb +137 -137
  125. data/lib/makit/secrets/azure_key_vault.rb +322 -322
  126. data/lib/makit/secrets/azure_secrets.rb +221 -221
  127. data/lib/makit/secrets/local_secrets.rb +72 -72
  128. data/lib/makit/secrets/secrets_manager.rb +105 -105
  129. data/lib/makit/secrets.rb +96 -96
  130. data/lib/makit/serializer.rb +130 -130
  131. data/lib/makit/services/builder.rb +186 -186
  132. data/lib/makit/services/error_handler.rb +226 -226
  133. data/lib/makit/services/repository_manager.rb +367 -367
  134. data/lib/makit/services/validator.rb +112 -112
  135. data/lib/makit/setup/classlib.rb +101 -101
  136. data/lib/makit/setup/gem.rb +268 -268
  137. data/lib/makit/setup/pages.rb +11 -11
  138. data/lib/makit/setup/razorclasslib.rb +101 -101
  139. data/lib/makit/setup/runner.rb +54 -54
  140. data/lib/makit/setup.rb +5 -5
  141. data/lib/makit/show.rb +110 -110
  142. data/lib/makit/storage.rb +126 -126
  143. data/lib/makit/symbols.rb +175 -175
  144. data/lib/makit/task_info.rb +130 -130
  145. data/lib/makit/tasks/at_exit.rb +15 -15
  146. data/lib/makit/tasks/build.rb +22 -22
  147. data/lib/makit/tasks/bump.rb +7 -7
  148. data/lib/makit/tasks/clean.rb +13 -13
  149. data/lib/makit/tasks/configure.rb +10 -10
  150. data/lib/makit/tasks/format.rb +10 -10
  151. data/lib/makit/tasks/hook_manager.rb +443 -443
  152. data/lib/makit/tasks/info.rb +368 -368
  153. data/lib/makit/tasks/init.rb +49 -49
  154. data/lib/makit/tasks/integrate.rb +60 -60
  155. data/lib/makit/tasks/pull_incoming.rb +13 -13
  156. data/lib/makit/tasks/secrets.rb +7 -7
  157. data/lib/makit/tasks/setup.rb +16 -16
  158. data/lib/makit/tasks/sync.rb +14 -14
  159. data/lib/makit/tasks/tag.rb +27 -27
  160. data/lib/makit/tasks/task_monkey_patch.rb +81 -81
  161. data/lib/makit/tasks/test.rb +22 -22
  162. data/lib/makit/tasks/update.rb +21 -21
  163. data/lib/makit/tasks/version.rb +6 -6
  164. data/lib/makit/tasks.rb +24 -24
  165. data/lib/makit/test_cache.rb +239 -239
  166. data/lib/makit/tree.rb +37 -37
  167. data/lib/makit/v1/configuration/project_service_impl.rb +370 -370
  168. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -295
  169. data/lib/makit/v1/makit.v1_pb.rb +35 -35
  170. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  171. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -572
  172. data/lib/makit/version.rb +661 -661
  173. data/lib/makit/version_util.rb +21 -21
  174. data/lib/makit/wix.rb +95 -95
  175. data/lib/makit/yaml.rb +29 -29
  176. data/lib/makit/zip.rb +17 -17
  177. data/lib/makit copy.rb +44 -44
  178. data/lib/makit.rb +121 -121
  179. metadata +2 -2
@@ -1,202 +1,202 @@
1
- require "net/http"
2
- require "json"
3
- require "uri"
4
-
5
- module Makit
6
- module GitHubActions
7
- # Gets the current git branch, defaulting to "main" if not available
8
- #
9
- # @return [String] Current branch name
10
- def self.get_current_branch
11
- branch = `git rev-parse --abbrev-ref HEAD`.strip
12
- branch.empty? ? "main" : branch
13
- end
14
-
15
- # Gets GitHub token from secrets or environment variable
16
- #
17
- # @return [String, nil] GitHub token if available
18
- def self.get_token
19
- if defined?(Makit::Secrets) && Makit::Secrets.has_key?("github_token")
20
- Makit::Secrets.get("github_token")
21
- else
22
- ENV["GITHUB_TOKEN"]
23
- end
24
- end
25
-
26
- # Formats and displays workflow status information
27
- #
28
- # @param result [Hash] Workflow status result from workflow_status
29
- # @param owner [String] Repository owner (for display)
30
- # @param repo [String] Repository name (for display)
31
- # @param branch [String] Branch name (for display)
32
- def self.display_status(result, owner, repo, branch)
33
- if result[:status] == "not_found"
34
- puts "⚠️ #{result[:message]}"
35
- else
36
- status_emoji = case result[:conclusion]
37
- when "success"
38
- "✅"
39
- when "failure"
40
- "❌"
41
- when "cancelled"
42
- "🚫"
43
- when nil
44
- result[:status] == "completed" ? "⏸️" : "🔄"
45
- else
46
- "❓"
47
- end
48
-
49
- puts "\n#{status_emoji} Workflow Status: #{result[:workflow_name] || "Unknown"}"
50
- puts " Status: #{result[:status]}"
51
- puts " Conclusion: #{result[:conclusion] || "N/A"}" if result[:conclusion]
52
- puts " Run Number: ##{result[:run_number]}" if result[:run_number]
53
- puts " Created: #{result[:created_at]}" if result[:created_at]
54
- puts " Updated: #{result[:updated_at]}" if result[:updated_at]
55
- puts " URL: #{result[:html_url]}" if result[:html_url]
56
- end
57
- end
58
-
59
- # Queries and displays GitHub Actions workflow status
60
- # Handles all logic including branch detection, token retrieval, and output formatting
61
- #
62
- # @param branch [String, nil] Branch name to query (default: auto-detect from git)
63
- # @param workflow_id [String, nil] Specific workflow ID to query (optional)
64
- # @param token [String, nil] GitHub Personal Access Token (optional, will try secrets/env if not provided)
65
- # @raise [RuntimeError] If authentication fails or API error occurs
66
- def self.query_and_display_status(branch: nil, workflow_id: nil, token: nil)
67
- branch ||= get_current_branch
68
- owner, repo = get_repo_from_git
69
-
70
- puts "Querying GitHub Actions status for #{owner}/#{repo} (branch: #{branch})..."
71
-
72
- token ||= get_token
73
- if token.nil? || token.empty?
74
- puts "github_token SECRET not available"
75
- end
76
-
77
- result = workflow_status(branch: branch, workflow_id: workflow_id, token: token)
78
- display_status(result, owner, repo, branch)
79
- rescue => e
80
- puts "❌ Error: #{e.message}"
81
- raise
82
- end
83
- # Extracts GitHub repository owner and name from a URL or git remote URL
84
- #
85
- # @param url [String] GitHub repository URL (https://github.com/owner/repo or git@github.com:owner/repo)
86
- # @return [Array<String>] Array containing [owner, repo_name]
87
- # @raise [ArgumentError] If URL cannot be parsed
88
- #
89
- # @example HTTPS URL format
90
- # parse_repo_url("https://github.com/node-net/Node.Net.git")
91
- # # => ["node-net", "Node.Net"]
92
- #
93
- # @example SSH URL format
94
- # parse_repo_url("git@github.com:node-net/Node.Net.git")
95
- # # => ["node-net", "Node.Net"]
96
- #
97
- # @example URL without .git extension
98
- # parse_repo_url("https://github.com/microsoft/dotnet")
99
- # # => ["microsoft", "dotnet"]
100
- def self.parse_repo_url(url)
101
- match = url.match(%r{github\.com[:/]([^/]+)/([^/]+)(?:\.git)?$})
102
- if match
103
- owner = match[1]
104
- repo = match[2].gsub(/\.git$/, "")
105
- return [owner, repo]
106
- else
107
- raise ArgumentError, "Could not parse GitHub repository from URL: #{url}"
108
- end
109
- end
110
-
111
- # Gets GitHub repository info from git remote origin
112
- #
113
- # @return [Array<String>] Array containing [owner, repo_name]
114
- # @raise [RuntimeError] If git remote URL cannot be determined or parsed
115
- def self.get_repo_from_git
116
- remote_url = `git config --get remote.origin.url`.strip
117
- if remote_url.empty?
118
- raise "Could not determine git remote URL. Make sure you're in a git repository with a remote configured."
119
- end
120
- parse_repo_url(remote_url)
121
- end
122
-
123
- # Queries GitHub Actions API for workflow run status
124
- #
125
- # @param owner [String, nil] Repository owner (required if repo_url is nil)
126
- # @param repo [String, nil] Repository name (required if repo_url is nil)
127
- # @param repo_url [String, nil] GitHub repository URL or git remote URL (alternative to owner/repo)
128
- # @param workflow_id [String, nil] Specific workflow ID to query (optional)
129
- # @param branch [String] Branch name to query (default: "main")
130
- # @param token [String, nil] GitHub Personal Access Token (optional, will use GITHUB_TOKEN env var if not provided)
131
- # @return [Hash] Workflow status information
132
- # @raise [RuntimeError] If authentication fails or API error occurs
133
- def self.workflow_status(owner: nil, repo: nil, repo_url: nil, workflow_id: nil, branch: "main", token: nil)
134
- # Determine owner and repo from URL if provided
135
- if repo_url
136
- owner, repo = parse_repo_url(repo_url)
137
- elsif owner.nil? || repo.nil?
138
- # Try to get from git if not provided
139
- owner, repo = get_repo_from_git
140
- end
141
- # Token should be provided by caller, but fallback to environment variable if not provided
142
- token ||= ENV["GITHUB_TOKEN"]
143
-
144
- if token.nil? || token.empty?
145
- raise "GitHub token not found. Set GITHUB_TOKEN environment variable or configure github_token secret."
146
- end
147
-
148
- base_url = "https://api.github.com/repos/#{owner}/#{repo}"
149
-
150
- if workflow_id
151
- # Get status for a specific workflow
152
- url = "#{base_url}/actions/workflows/#{workflow_id}/runs?branch=#{branch}&per_page=1"
153
- else
154
- # Get status for all workflows (latest run)
155
- url = "#{base_url}/actions/runs?branch=#{branch}&per_page=1"
156
- end
157
-
158
- uri = URI(url)
159
- http = Net::HTTP.new(uri.host, uri.port)
160
- http.use_ssl = true
161
-
162
- request = Net::HTTP::Get.new(uri)
163
- request["Accept"] = "application/vnd.github.v3+json"
164
- request["Authorization"] = "Bearer #{token}"
165
- request["User-Agent"] = "Node.Net-Rake-Task"
166
-
167
- response = http.request(request)
168
-
169
- case response.code.to_i
170
- when 200
171
- data = JSON.parse(response.body)
172
- runs = data["workflow_runs"] || []
173
-
174
- if runs.empty?
175
- return {
176
- status: "not_found",
177
- message: "No workflow runs found for branch '#{branch}'",
178
- }
179
- end
180
-
181
- latest_run = runs.first
182
- workflow_name = latest_run["name"] || latest_run.dig("workflow", "name") || "Unknown"
183
-
184
- {
185
- status: latest_run["status"], # queued, in_progress, completed
186
- conclusion: latest_run["conclusion"], # success, failure, cancelled, etc.
187
- workflow_name: workflow_name,
188
- run_number: latest_run["run_number"],
189
- html_url: latest_run["html_url"],
190
- created_at: latest_run["created_at"],
191
- updated_at: latest_run["updated_at"],
192
- }
193
- when 401
194
- raise "GitHub API authentication failed. Check your token."
195
- when 404
196
- raise "Repository #{owner}/#{repo} not found or access denied."
197
- else
198
- raise "GitHub API error: #{response.code} - #{response.message}"
199
- end
200
- end
201
- end
202
- end
1
+ require "net/http"
2
+ require "json"
3
+ require "uri"
4
+
5
+ module Makit
6
+ module GitHubActions
7
+ # Gets the current git branch, defaulting to "main" if not available
8
+ #
9
+ # @return [String] Current branch name
10
+ def self.get_current_branch
11
+ branch = `git rev-parse --abbrev-ref HEAD`.strip
12
+ branch.empty? ? "main" : branch
13
+ end
14
+
15
+ # Gets GitHub token from secrets or environment variable
16
+ #
17
+ # @return [String, nil] GitHub token if available
18
+ def self.get_token
19
+ if defined?(Makit::Secrets) && Makit::Secrets.has_key?("github_token")
20
+ Makit::Secrets.get("github_token")
21
+ else
22
+ ENV["GITHUB_TOKEN"]
23
+ end
24
+ end
25
+
26
+ # Formats and displays workflow status information
27
+ #
28
+ # @param result [Hash] Workflow status result from workflow_status
29
+ # @param owner [String] Repository owner (for display)
30
+ # @param repo [String] Repository name (for display)
31
+ # @param branch [String] Branch name (for display)
32
+ def self.display_status(result, owner, repo, branch)
33
+ if result[:status] == "not_found"
34
+ puts "⚠️ #{result[:message]}"
35
+ else
36
+ status_emoji = case result[:conclusion]
37
+ when "success"
38
+ "✅"
39
+ when "failure"
40
+ "❌"
41
+ when "cancelled"
42
+ "🚫"
43
+ when nil
44
+ result[:status] == "completed" ? "⏸️" : "🔄"
45
+ else
46
+ "❓"
47
+ end
48
+
49
+ puts "\n#{status_emoji} Workflow Status: #{result[:workflow_name] || "Unknown"}"
50
+ puts " Status: #{result[:status]}"
51
+ puts " Conclusion: #{result[:conclusion] || "N/A"}" if result[:conclusion]
52
+ puts " Run Number: ##{result[:run_number]}" if result[:run_number]
53
+ puts " Created: #{result[:created_at]}" if result[:created_at]
54
+ puts " Updated: #{result[:updated_at]}" if result[:updated_at]
55
+ puts " URL: #{result[:html_url]}" if result[:html_url]
56
+ end
57
+ end
58
+
59
+ # Queries and displays GitHub Actions workflow status
60
+ # Handles all logic including branch detection, token retrieval, and output formatting
61
+ #
62
+ # @param branch [String, nil] Branch name to query (default: auto-detect from git)
63
+ # @param workflow_id [String, nil] Specific workflow ID to query (optional)
64
+ # @param token [String, nil] GitHub Personal Access Token (optional, will try secrets/env if not provided)
65
+ # @raise [RuntimeError] If authentication fails or API error occurs
66
+ def self.query_and_display_status(branch: nil, workflow_id: nil, token: nil)
67
+ branch ||= get_current_branch
68
+ owner, repo = get_repo_from_git
69
+
70
+ puts "Querying GitHub Actions status for #{owner}/#{repo} (branch: #{branch})..."
71
+
72
+ token ||= get_token
73
+ if token.nil? || token.empty?
74
+ puts "github_token SECRET not available"
75
+ end
76
+
77
+ result = workflow_status(branch: branch, workflow_id: workflow_id, token: token)
78
+ display_status(result, owner, repo, branch)
79
+ rescue => e
80
+ puts "❌ Error: #{e.message}"
81
+ raise
82
+ end
83
+ # Extracts GitHub repository owner and name from a URL or git remote URL
84
+ #
85
+ # @param url [String] GitHub repository URL (https://github.com/owner/repo or git@github.com:owner/repo)
86
+ # @return [Array<String>] Array containing [owner, repo_name]
87
+ # @raise [ArgumentError] If URL cannot be parsed
88
+ #
89
+ # @example HTTPS URL format
90
+ # parse_repo_url("https://github.com/node-net/Node.Net.git")
91
+ # # => ["node-net", "Node.Net"]
92
+ #
93
+ # @example SSH URL format
94
+ # parse_repo_url("git@github.com:node-net/Node.Net.git")
95
+ # # => ["node-net", "Node.Net"]
96
+ #
97
+ # @example URL without .git extension
98
+ # parse_repo_url("https://github.com/microsoft/dotnet")
99
+ # # => ["microsoft", "dotnet"]
100
+ def self.parse_repo_url(url)
101
+ match = url.match(%r{github\.com[:/]([^/]+)/([^/]+)(?:\.git)?$})
102
+ if match
103
+ owner = match[1]
104
+ repo = match[2].gsub(/\.git$/, "")
105
+ return [owner, repo]
106
+ else
107
+ raise ArgumentError, "Could not parse GitHub repository from URL: #{url}"
108
+ end
109
+ end
110
+
111
+ # Gets GitHub repository info from git remote origin
112
+ #
113
+ # @return [Array<String>] Array containing [owner, repo_name]
114
+ # @raise [RuntimeError] If git remote URL cannot be determined or parsed
115
+ def self.get_repo_from_git
116
+ remote_url = `git config --get remote.origin.url`.strip
117
+ if remote_url.empty?
118
+ raise "Could not determine git remote URL. Make sure you're in a git repository with a remote configured."
119
+ end
120
+ parse_repo_url(remote_url)
121
+ end
122
+
123
+ # Queries GitHub Actions API for workflow run status
124
+ #
125
+ # @param owner [String, nil] Repository owner (required if repo_url is nil)
126
+ # @param repo [String, nil] Repository name (required if repo_url is nil)
127
+ # @param repo_url [String, nil] GitHub repository URL or git remote URL (alternative to owner/repo)
128
+ # @param workflow_id [String, nil] Specific workflow ID to query (optional)
129
+ # @param branch [String] Branch name to query (default: "main")
130
+ # @param token [String, nil] GitHub Personal Access Token (optional, will use GITHUB_TOKEN env var if not provided)
131
+ # @return [Hash] Workflow status information
132
+ # @raise [RuntimeError] If authentication fails or API error occurs
133
+ def self.workflow_status(owner: nil, repo: nil, repo_url: nil, workflow_id: nil, branch: "main", token: nil)
134
+ # Determine owner and repo from URL if provided
135
+ if repo_url
136
+ owner, repo = parse_repo_url(repo_url)
137
+ elsif owner.nil? || repo.nil?
138
+ # Try to get from git if not provided
139
+ owner, repo = get_repo_from_git
140
+ end
141
+ # Token should be provided by caller, but fallback to environment variable if not provided
142
+ token ||= ENV["GITHUB_TOKEN"]
143
+
144
+ if token.nil? || token.empty?
145
+ raise "GitHub token not found. Set GITHUB_TOKEN environment variable or configure github_token secret."
146
+ end
147
+
148
+ base_url = "https://api.github.com/repos/#{owner}/#{repo}"
149
+
150
+ if workflow_id
151
+ # Get status for a specific workflow
152
+ url = "#{base_url}/actions/workflows/#{workflow_id}/runs?branch=#{branch}&per_page=1"
153
+ else
154
+ # Get status for all workflows (latest run)
155
+ url = "#{base_url}/actions/runs?branch=#{branch}&per_page=1"
156
+ end
157
+
158
+ uri = URI(url)
159
+ http = Net::HTTP.new(uri.host, uri.port)
160
+ http.use_ssl = true
161
+
162
+ request = Net::HTTP::Get.new(uri)
163
+ request["Accept"] = "application/vnd.github.v3+json"
164
+ request["Authorization"] = "Bearer #{token}"
165
+ request["User-Agent"] = "Node.Net-Rake-Task"
166
+
167
+ response = http.request(request)
168
+
169
+ case response.code.to_i
170
+ when 200
171
+ data = JSON.parse(response.body)
172
+ runs = data["workflow_runs"] || []
173
+
174
+ if runs.empty?
175
+ return {
176
+ status: "not_found",
177
+ message: "No workflow runs found for branch '#{branch}'",
178
+ }
179
+ end
180
+
181
+ latest_run = runs.first
182
+ workflow_name = latest_run["name"] || latest_run.dig("workflow", "name") || "Unknown"
183
+
184
+ {
185
+ status: latest_run["status"], # queued, in_progress, completed
186
+ conclusion: latest_run["conclusion"], # success, failure, cancelled, etc.
187
+ workflow_name: workflow_name,
188
+ run_number: latest_run["run_number"],
189
+ html_url: latest_run["html_url"],
190
+ created_at: latest_run["created_at"],
191
+ updated_at: latest_run["updated_at"],
192
+ }
193
+ when 401
194
+ raise "GitHub API authentication failed. Check your token."
195
+ when 404
196
+ raise "Repository #{owner}/#{repo} not found or access denied."
197
+ else
198
+ raise "GitHub API error: #{response.code} - #{response.message}"
199
+ end
200
+ end
201
+ end
202
+ end