makit 0.0.165 → 0.0.167

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: ef09684cefaefec9805a934bb29dca1b258d7b9f2bd44b4443688c8b053ea904
4
- data.tar.gz: 4bffc3acb02eeeb00dc8301e75fd61bbf047441af01f9a2502db014a944c6c8e
3
+ metadata.gz: 981ebe579212bb1f5564fce546f684024510145881af327602af27d2e7203f81
4
+ data.tar.gz: 52404ee70c5a81b6f3feaa250b29cb992121d86d8728c1b318aea2a5c02c16f3
5
5
  SHA512:
6
- metadata.gz: 8e4fe9eeac014c765ae156166bbfdb4859c6df617ed89df85b59c6ee211a952b8c9e8077c21a762d21977c15f7b4fcd14b0ea47fada3107ebef35e274130d776
7
- data.tar.gz: 8cf1b0b48ec5a6cc423b8c4d9439f755959bf6ed9cde1ed6c504e048d7fbd18b146bbb98c016f5636efe7668b5af04157431b356f27442d8e8798c9795a85690
6
+ metadata.gz: 16c11cbd1fd9090703402f5a43f1dad8d44c5f13e5ce5d75610fb866f096b8b5ab6392fb576f25b799912e3c849e7242849d7a10e02410708b3675f37da527d1
7
+ data.tar.gz: ee847b727077884e1d777f8286e2483e72c89644c3b726955536cf0ccca62fe805bc667efb500924a5d61560d78f0b5777af83ef00cb0af4410b3e4807efded6
@@ -0,0 +1,188 @@
1
+ module Makit
2
+ class AzurePipelines
3
+ def self.status(project_name: nil, org: nil, project: nil, pipeline_id: nil, pipeline_name: nil, pat: nil)
4
+ require "net/http"
5
+ require "uri"
6
+ require "json"
7
+
8
+ # Get organization and project from git remote or environment variables
9
+ git_remote = `git remote get-url origin 2>/dev/null`.strip
10
+ if git_remote =~ /dev\.azure\.com\/([^\/]+)\/([^\/]+)/
11
+ org ||= $1
12
+ project ||= $2
13
+ else
14
+ org ||= ENV["AZURE_DEVOPS_ORG"] || "DevOpsMusco"
15
+ project ||= ENV["AZURE_DEVOPS_PROJECT"] || "Design"
16
+ end
17
+
18
+ # Pipeline ID can be set via environment variable, or we'll try to find it by name
19
+ pipeline_id ||= ENV["AZURE_PIPELINE_ID"]
20
+ pipeline_name ||= ENV["AZURE_PIPELINE_NAME"] || project_name
21
+
22
+ # Display values if show_value is available (from raykit)
23
+ if defined?(show_value)
24
+ show_value "Organization", org
25
+ show_value "Project", project
26
+ show_value "Pipeline", pipeline_name
27
+ end
28
+
29
+ # Try to get access token from parameter, environment variable, or Azure CLI
30
+ pat ||= ENV["AZURE_DEVOPS_PAT"]
31
+ if pat.nil? || pat.empty?
32
+ puts " AZURE_DEVOPS_PAT not set, attempting to use Azure CLI authentication..."
33
+ begin
34
+ # Get access token for Azure DevOps (resource ID: 499b84ac-1321-427f-aa5e-6d8b3c8c4123)
35
+ token_output = `az account get-access-token --resource 499b84ac-1321-427f-aa5e-6d8b3c8c4123 --query accessToken -o tsv 2>&1`
36
+ if $?.exitstatus == 0 && !token_output.strip.empty?
37
+ pat = token_output.strip
38
+ puts " Successfully obtained access token from Azure CLI"
39
+ else
40
+ raise "Azure CLI authentication failed"
41
+ end
42
+ rescue => e
43
+ puts " Error: Could not get access token from Azure CLI"
44
+ puts " Make sure you're logged in: az login"
45
+ puts " Or set AZURE_DEVOPS_PAT: export AZURE_DEVOPS_PAT=your_personal_access_token"
46
+ exit 1
47
+ end
48
+ end
49
+
50
+ # Helper lambda to set authorization header (Azure AD tokens can use Bearer, PAT uses Basic)
51
+ set_auth_header = lambda do |req, token|
52
+ # Azure AD tokens are typically longer and can use Bearer auth
53
+ # PAT tokens use Basic auth. Try Bearer first for longer tokens, Basic for shorter ones
54
+ if token.length > 100
55
+ req["Authorization"] = "Bearer #{token}"
56
+ else
57
+ req.basic_auth("", token)
58
+ end
59
+ end
60
+
61
+ # If pipeline ID is not set, try to find it by name
62
+ if pipeline_id.nil? || pipeline_id.empty?
63
+ puts " Looking up pipeline ID for '#{pipeline_name}'..."
64
+ uri = URI("https://dev.azure.com/#{org}/#{project}/_apis/pipelines?api-version=7.1")
65
+ req = Net::HTTP::Get.new(uri)
66
+ set_auth_header.call(req, pat)
67
+ req["Content-Type"] = "application/json"
68
+
69
+ res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
70
+ http.request(req)
71
+ end
72
+
73
+ if res.is_a?(Net::HTTPSuccess)
74
+ pipelines = JSON.parse(res.body)["value"]
75
+ pipeline = pipelines.find { |p| p["name"] == pipeline_name || p["name"].include?(pipeline_name) }
76
+ if pipeline
77
+ pipeline_id = pipeline["id"].to_s
78
+ puts " Found pipeline ID: #{pipeline_id}"
79
+ else
80
+ puts " Error: Could not find pipeline '#{pipeline_name}'"
81
+ puts " Available pipelines: #{pipelines.map { |p| p["name"] }.join(", ")}"
82
+ exit 1
83
+ end
84
+ else
85
+ puts " Error: Failed to list pipelines: #{res.code} #{res.message}"
86
+ exit 1
87
+ end
88
+ end
89
+
90
+ # Get the latest pipeline run
91
+ puts " Fetching latest pipeline run..."
92
+ uri = URI("https://dev.azure.com/#{org}/#{project}/_apis/pipelines/#{pipeline_id}/runs")
93
+ params = {
94
+ "$top" => 1,
95
+ "api-version" => "7.1",
96
+ }
97
+ uri.query = URI.encode_www_form(params)
98
+
99
+ req = Net::HTTP::Get.new(uri)
100
+ set_auth_header.call(req, pat)
101
+ req["Content-Type"] = "application/json"
102
+
103
+ res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
104
+ http.request(req)
105
+ end
106
+
107
+ if res.is_a?(Net::HTTPSuccess)
108
+ body = JSON.parse(res.body)
109
+ if body["value"] && body["value"].length > 0
110
+ run = body["value"].first
111
+ result = run["result"] || "unknown"
112
+ state = run["state"] || "unknown"
113
+ build_number = run["name"] || run["id"].to_s
114
+ finish_time = run["finishedDate"] || run["createdDate"] || "N/A"
115
+ url = run["_links"] && run["_links"]["web"] ? run["_links"]["web"]["href"] : "https://dev.azure.com/#{org}/#{project}/_build/results?buildId=#{run["id"]}"
116
+
117
+ puts " Latest Run:"
118
+ puts " Build Number: #{build_number}"
119
+ puts " State: #{state}"
120
+ puts " Result: #{result}"
121
+ puts " Finished: #{finish_time}"
122
+ puts " URL: #{url}"
123
+ else
124
+ puts " No pipeline runs found yet."
125
+ end
126
+ else
127
+ puts " Error: Failed to fetch pipeline runs: #{res.code} #{res.message}"
128
+ if res.body
129
+ error_body = JSON.parse(res.body) rescue nil
130
+ if error_body && error_body["message"]
131
+ puts " Message: #{error_body["message"]}"
132
+ end
133
+ end
134
+ exit 1
135
+ end
136
+ end
137
+ # Publishes a NuGet package to an Azure DevOps feed
138
+ #
139
+ # @param package_name [String] The name of the NuGet package
140
+ # @param package_version [String] The version of the package
141
+ # @param package_file [String] Path to the .nupkg file
142
+ # @param feed_source [String] The name of the Azure DevOps feed
143
+ # @param api_key [String, nil] Optional API key (defaults to "az" for Azure CLI)
144
+ # @raise [RuntimeError] If the push fails and it's not a duplicate package error
145
+ def self.publish(package_name:, package_version:, package_file:, feed_source:, api_key: "az")
146
+ puts " Checking if package #{package_name} version #{package_version} already exists in feed..."
147
+
148
+ # Check if package version already exists
149
+ list_command = "dotnet nuget list \"#{package_name}\" --source \"#{feed_source}\" --api-key #{api_key}"
150
+ list_output = `#{list_command} 2>&1`
151
+ list_exit_code = $?.exitstatus
152
+
153
+ if list_exit_code == 0 && list_output.include?(package_version)
154
+ puts " Package #{package_name} version #{package_version} already exists in feed. Skipping push."
155
+ elsif list_exit_code != 0 && list_output =~ /401|Unauthorized|credential/i
156
+ puts " Authentication failed when checking feed. Will attempt to push anyway."
157
+ puts " (To check manually, run: #{list_command} --interactive)"
158
+ push_package(package_file: package_file, feed_source: feed_source, api_key: api_key, package_name: package_name, package_version: package_version)
159
+ else
160
+ puts " Package #{package_name} version #{package_version} not found in feed (or unable to verify). Attempting to push..."
161
+ push_package(package_file: package_file, feed_source: feed_source, api_key: api_key, package_name: package_name, package_version: package_version)
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ def self.push_package(package_file:, feed_source:, api_key:, package_name:, package_version:)
168
+ push_command = "dotnet nuget push \"#{package_file}\" --source \"#{feed_source}\" --api-key #{api_key} --skip-duplicate"
169
+ push_output = `#{push_command} 2>&1`
170
+ push_exit_code = $?.exitstatus
171
+
172
+ if push_exit_code == 0
173
+ puts " Package pushed successfully to #{feed_source} feed."
174
+ elsif push_output =~ /already exists|conflict|409/i
175
+ puts " Package #{package_name} version #{package_version} already exists in feed. This is expected."
176
+ else
177
+ puts " Error pushing package to #{feed_source} feed:"
178
+ puts push_output
179
+ puts ""
180
+ puts " To retry manually, run:"
181
+ puts " #{push_command} --interactive"
182
+ puts ""
183
+ raise "Failed to push package to #{feed_source} feed"
184
+ end
185
+ end
186
+ end
187
+ end
188
+
data/lib/makit/dotnet.rb CHANGED
@@ -22,7 +22,7 @@ module Makit
22
22
 
23
23
  # Project-related methods
24
24
  def self.installed?
25
- Project.installed?
25
+ Makit::DotNet::Project.installed?
26
26
  end
27
27
 
28
28
  # Backward compatibility - deprecated method name
@@ -31,80 +31,80 @@ module Makit
31
31
  end
32
32
 
33
33
  def self.version
34
- Project.version
34
+ Makit::DotNet::Project.version
35
35
  end
36
36
 
37
37
  def self.project_short_name(project_path)
38
- Project.project_short_name(project_path)
38
+ Makit::DotNet::Project.project_short_name(project_path)
39
39
  end
40
40
 
41
41
  def self.new_project(template, name, output, args = "")
42
- Project.new_project(template, name, output, args)
42
+ Makit::DotNet::Project.new_project(template, name, output, args)
43
43
  end
44
44
 
45
45
  def self.set_project_target_framework(project_hint, target_framework)
46
- Project.set_project_target_framework(project_hint, target_framework)
46
+ Makit::DotNet::Project.set_project_target_framework(project_hint, target_framework)
47
47
  end
48
48
 
49
49
  def self.find_project(project_hint)
50
- Project.find_project(project_hint)
50
+ Makit::DotNet::Project.find_project(project_hint)
51
51
  end
52
52
 
53
53
  def self.add_package(project_path, package_name)
54
- Project.add_package(project_path, package_name)
54
+ Makit::DotNet::Project.add_package(project_path, package_name)
55
55
  end
56
56
 
57
57
  def self.add_packages(project_path, packages)
58
- Project.add_packages(project_path, packages)
58
+ Makit::DotNet::Project.add_packages(project_path, packages)
59
59
  end
60
60
 
61
61
  def self.add_reference(project_path, reference_path)
62
- Project.add_reference(project_path, reference_path)
62
+ Makit::DotNet::Project.add_reference(project_path, reference_path)
63
63
  end
64
64
 
65
65
  def self.add_references(project_path, references)
66
- Project.add_references(project_path, references)
66
+ Makit::DotNet::Project.add_references(project_path, references)
67
67
  end
68
68
 
69
69
  def self.build(project_path, configuration = "Release", output = "artifacts")
70
- Project.build(project_path, configuration, output)
70
+ Makit::DotNet::Project.build(project_path, configuration, output)
71
71
  end
72
72
 
73
73
  def self.publish(project_path, configuration = "Release", output = "artifacts")
74
- Project.publish(project_path, configuration, output)
74
+ Makit::DotNet::Project.publish(project_path, configuration, output)
75
75
  end
76
76
 
77
77
  def self.test(project_path, configuration = "Release", output = "artifacts")
78
- Project.test(project_path, configuration, output)
78
+ Makit::DotNet::Project.test(project_path, configuration, output)
79
79
  end
80
80
 
81
81
  def self.format_project(project_path)
82
- Project.format_project(project_path)
82
+ Makit::DotNet::Project.format_project(project_path)
83
83
  end
84
84
 
85
85
  def self.upgrade_project(project_path)
86
- Project.upgrade_project(project_path)
86
+ Makit::DotNet::Project.upgrade_project(project_path)
87
87
  end
88
88
 
89
89
  # CLI-related methods
90
90
  def self.new_solution(name)
91
- CLI.new_solution(name)
91
+ Makit::DotNet::CLI.new_solution(name)
92
92
  end
93
93
 
94
94
  def self.sln_add_projects(sln_name)
95
- CLI.sln_add_projects(sln_name)
95
+ Makit::DotNet::CLI.sln_add_projects(sln_name)
96
96
  end
97
97
 
98
98
  def self.generate_docs
99
- CLI.generate_docs
99
+ Makit::DotNet::CLI.generate_docs
100
100
  end
101
101
 
102
102
  def self.install_global_tool(tool_name)
103
- CLI.install_global_tool(tool_name)
103
+ Makit::DotNet::CLI.install_global_tool(tool_name)
104
104
  end
105
105
 
106
106
  def self.update_global_tool(tool_name)
107
- CLI.update_global_tool(tool_name)
107
+ Makit::DotNet::CLI.update_global_tool(tool_name)
108
108
  end
109
109
  end
110
110
  end
data/lib/makit/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Makit
4
4
  # Static version for now to avoid circular dependency issues
5
- #VERSION = "0.0.165"
5
+ #VERSION = "0.0.167"
6
6
 
7
7
  # Version management utilities for various file formats
8
8
  #
data/lib/makit.rb CHANGED
@@ -23,6 +23,7 @@ require_relative "makit/secrets"
23
23
  require_relative "makit/rubygems"
24
24
  require_relative "makit/azure/cli"
25
25
  require_relative "makit/azure/blob_storage"
26
+ require_relative "makit/azure-pipelines"
26
27
  require_relative "makit/humanize"
27
28
  require_relative "makit/directories"
28
29
  require_relative "makit/exceptions"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: makit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.165
4
+ version: 0.0.167
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lou Parslow
@@ -235,6 +235,7 @@ files:
235
235
  - lib/makit.rb
236
236
  - lib/makit/apache.rb
237
237
  - lib/makit/auto.rb
238
+ - lib/makit/azure-pipelines.rb
238
239
  - lib/makit/azure/blob_storage.rb
239
240
  - lib/makit/azure/cli.rb
240
241
  - lib/makit/cli/base.rb
@@ -426,7 +427,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
426
427
  - !ruby/object:Gem::Version
427
428
  version: '0'
428
429
  requirements: []
429
- rubygems_version: 4.0.0
430
+ rubygems_version: 4.0.4
430
431
  specification_version: 4
431
432
  summary: A Ruby gem to help with CI/CD tasks
432
433
  test_files: []