errmine 0.1.1 → 0.2.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: 14575fe3e975be6308fefa8663defb90c80e552766ac0b1c552feee30c3e7209
4
- data.tar.gz: a967ca060190180ff8bb6d76abe237f131aab11b842f8b57c1ce6cef16fd417f
3
+ metadata.gz: 4f71e4d605d9ce77753b0ffdea51499feb507ecc8b65fc156890c04a86bad270
4
+ data.tar.gz: 2c1d3242c5daa6c66035e13a59f68c6a890156f9f48d7635a6d535c9762ba0bb
5
5
  SHA512:
6
- metadata.gz: e057ce4bd6639aa550b148c245bb2224ac126546a4cc287842fcb26d5cbf227fddfed1fc473a5d241bf0405511712be256308234a96cc0504e32149214b2489a
7
- data.tar.gz: 6291e7878535a180967c319a05d78379962f6209c4e972f062f8d1d0cdfa36c92be4fada846e8d552d9c983fb301d71833dad3cc52f418b4acf7de020e8f35ea
6
+ metadata.gz: dc3955573efbb9a1cff490071a3678f3a2bc7a6c04469f15a253b44560d275b0c4a26e84cd41583e80f47e421f11cfaf0b0a74ee5238b33ec8b8df27bfa6a140
7
+ data.tar.gz: 06eef437876a00211d6ccceaac6d06dca2846e1a1526c595e531e341379e30b788ce63f38aab46d97ff2b139e67ebb5f5ef83b06e22093b8b5af2785effb8ede
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Errmine changelog
2
2
 
3
+ ## 0.2.0 (2025-12-24)
4
+ - [Feature] Add app name to issue title for easy identification when multiple apps report to the same Redmine project.
5
+ - [Feature] Include app_name in checksum calculation so same errors in different apps create separate issues.
6
+ - [Feature] Add `Errmine.create_issue` method for creating custom Redmine issues with arbitrary subject, description, tracker, project, and tags.
7
+ - [Feature] Add tags support via `tag_list` parameter for both exception reporting and custom issues.
8
+ - [Feature] Add `default_tags` configuration option for tags applied to all issues.
9
+ - [Maintenance] Update actions/checkout to v6 in CI.
10
+
3
11
  ## 0.1.1 (2025-12-23)
4
12
  - [Fix] Fix file permissions for gem packaging.
5
13
  - [Fix] Fix gemspec metadata duplicate URI warning.
@@ -62,6 +62,38 @@ module Errmine
62
62
  @mutex.synchronize { @cache.clear }
63
63
  end
64
64
 
65
+ # Creates a custom issue in Redmine
66
+ #
67
+ # @param subject [String] issue subject/title
68
+ # @param description [String] issue description (Textile format)
69
+ # @param options [Hash] optional overrides
70
+ # @option options [String] :project_id Redmine project identifier
71
+ # @option options [Integer] :tracker_id Redmine tracker ID
72
+ # @option options [Array<String>] :tags tags to add to the issue
73
+ # @return [Hash, nil] the created issue or nil on failure
74
+ def create_custom_issue(subject:, description:, **options)
75
+ uri = build_uri('/issues.json')
76
+
77
+ issue_data = {
78
+ project_id: options[:project_id] || config.project_id,
79
+ tracker_id: options[:tracker_id] || config.tracker_id,
80
+ subject: subject,
81
+ description: description
82
+ }
83
+
84
+ tags = build_tag_list(options[:tags])
85
+ issue_data[:tag_list] = tags unless tags.empty?
86
+
87
+ response = http_post(uri, { issue: issue_data })
88
+ return nil unless response
89
+
90
+ data = JSON.parse(response.body)
91
+ data['issue']
92
+ rescue JSON::ParserError => e
93
+ warn "[Errmine] Failed to parse response: #{e.message}"
94
+ nil
95
+ end
96
+
65
97
  private
66
98
 
67
99
  # Returns the Errmine configuration
@@ -71,13 +103,23 @@ module Errmine
71
103
  Errmine.configuration
72
104
  end
73
105
 
106
+ # Builds a combined tag list from default tags and provided tags
107
+ #
108
+ # @param tags [Array<String>, nil] additional tags to include
109
+ # @return [Array<String>] combined unique tags
110
+ def build_tag_list(tags)
111
+ combined = config.default_tags.dup
112
+ combined.concat(Array(tags)) if tags
113
+ combined.uniq
114
+ end
115
+
74
116
  # Generates an 8-character checksum for the exception
75
117
  #
76
118
  # @param exception [Exception]
77
119
  # @return [String]
78
120
  def generate_checksum(exception)
79
121
  first_app_line = first_app_backtrace_line(exception)
80
- data = "#{exception.class}:#{exception.message}:#{first_app_line}"
122
+ data = "#{config.app_name}:#{exception.class}:#{exception.message}:#{first_app_line}"
81
123
  Digest::MD5.hexdigest(data)[0, 8]
82
124
  end
83
125
 
@@ -167,16 +209,17 @@ module Errmine
167
209
  subject = build_subject(checksum, 1, exception)
168
210
  description = build_description(exception, context)
169
211
 
170
- payload = {
171
- issue: {
172
- project_id: config.project_id,
173
- tracker_id: config.tracker_id,
174
- subject: subject,
175
- description: description
176
- }
212
+ issue_data = {
213
+ project_id: config.project_id,
214
+ tracker_id: config.tracker_id,
215
+ subject: subject,
216
+ description: description
177
217
  }
178
218
 
179
- response = http_post(uri, payload)
219
+ tags = build_tag_list(context[:tags])
220
+ issue_data[:tag_list] = tags unless tags.empty?
221
+
222
+ response = http_post(uri, { issue: issue_data })
180
223
  return nil unless response
181
224
 
182
225
  data = JSON.parse(response.body)
@@ -225,7 +268,7 @@ module Errmine
225
268
  truncated = message.length > SUBJECT_MESSAGE_LENGTH ? "#{message[0, SUBJECT_MESSAGE_LENGTH]}..." : message
226
269
  truncated = truncated.gsub(/[\r\n]+/, ' ').strip
227
270
 
228
- "[#{checksum}][#{count}] #{exception.class}: #{truncated}"
271
+ "[#{config.app_name}][#{checksum}][#{count}] #{exception.class}: #{truncated}"
229
272
  end
230
273
 
231
274
  # Builds the issue description in Textile format
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Errmine
4
4
  # Current version of the errmine gem
5
- VERSION = '0.1.1'
5
+ VERSION = '0.2.0'
6
6
  end
data/lib/errmine.rb CHANGED
@@ -29,6 +29,9 @@ module Errmine
29
29
  # @return [String] Application name shown in issues
30
30
  attr_accessor :app_name
31
31
 
32
+ # @return [Array<String>] Default tags to add to all issues
33
+ attr_accessor :default_tags
34
+
32
35
  # @return [Boolean] Whether notifications are enabled
33
36
  attr_accessor :enabled
34
37
 
@@ -37,13 +40,14 @@ module Errmine
37
40
 
38
41
  # Initializes configuration with defaults from environment variables
39
42
  def initialize
40
- @redmine_url = ENV.fetch('ERRMINE_REDMINE_URL', nil)
41
- @api_key = ENV.fetch('ERRMINE_API_KEY', nil)
42
- @project_id = ENV['ERRMINE_PROJECT'] || 'bug-tracker'
43
- @tracker_id = 1
44
- @app_name = ENV['ERRMINE_APP_NAME'] || 'unknown'
45
- @enabled = true
46
- @cooldown = 300
43
+ @redmine_url = ENV.fetch('ERRMINE_REDMINE_URL', nil)
44
+ @api_key = ENV.fetch('ERRMINE_API_KEY', nil)
45
+ @project_id = ENV['ERRMINE_PROJECT'] || 'bug-tracker'
46
+ @tracker_id = 1
47
+ @app_name = ENV['ERRMINE_APP_NAME'] || 'unknown'
48
+ @default_tags = []
49
+ @enabled = true
50
+ @cooldown = 300
47
51
  end
48
52
 
49
53
  # Checks if the configuration has required values
@@ -93,6 +97,25 @@ module Errmine
93
97
  warn "[Errmine] Failed to notify: #{e.message}"
94
98
  nil
95
99
  end
100
+
101
+ # Creates a custom issue in Redmine
102
+ #
103
+ # @param subject [String] issue subject/title
104
+ # @param description [String] issue description (Textile format)
105
+ # @param options [Hash] optional keyword arguments
106
+ # @option options [String] :project_id Redmine project identifier
107
+ # @option options [Integer] :tracker_id Redmine tracker ID
108
+ # @option options [Array<String>] :tags tags to add to the issue
109
+ # @return [Hash, nil] the created issue or nil on failure
110
+ def create_issue(subject:, description:, **options)
111
+ return unless configuration.enabled
112
+ return unless configuration.valid?
113
+
114
+ Notifier.instance.create_custom_issue(subject: subject, description: description, **options)
115
+ rescue StandardError => e
116
+ warn "[Errmine] Failed to create issue: #{e.message}"
117
+ nil
118
+ end
96
119
  end
97
120
  end
98
121
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: errmine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld