rails-informant 0.4.2 → 0.4.4

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: 206cb69356bdf4d40de95e2435428cf0413f85ed56f7cdbed4912431fb2ddd6e
4
- data.tar.gz: c2c7b3844c83ae2e92d389a9f8d914dfc3b4ff6ea599f741a6e31cdf10866254
3
+ metadata.gz: 452521455f3505485bde1a549f773545c459f78ecae46aea7aa1844a19cdc77c
4
+ data.tar.gz: 6c74d39ca5094a26bec34cd98fb7c0a8fbbdf0d6ac940265bef79484ab5e53d0
5
5
  SHA512:
6
- metadata.gz: 19e1887a018a41d07163385fc1a7868ea21f33ea9599de3c6f8aaae309c2939f93c386fc7a21582e109ff15c8df5f21702f1aed77bd2b92af5beb41bb26f73c6
7
- data.tar.gz: 5bd2451b4a52590e2687c2009b6603a5e1a2df42451508ad0bc1e24f5cb86377020bbb6b79336c2aa1fe2213061c4235911046b9423aaf575fcd2c2db47ffe31
6
+ metadata.gz: c0dafe1256811528cc18da9566369a8186e028fa4aaa8746ec2be68f6b1f533ffaebc369ec192e9d8e5ff282a15a49c87c4b40a58633054f1ea629d617036f71
7
+ data.tar.gz: ae248c9b2c78ed8d6e71d280c743144d75d6aef77459b1aecdd9be251f7bd7949593d96e35cdc018a9004b31b8c822cbc118cef426395c8a16656891b4269c77
@@ -1,9 +1,12 @@
1
+ require "json"
2
+ require "open3"
3
+
1
4
  module RailsInformant
2
5
  module Mcp
3
6
  module Tools
4
7
  class VerifyPendingFixes < BaseTool
5
8
  tool_name "verify_pending_fixes"
6
- description "Verify fix_pending errors by checking if their fix_sha is an ancestor of the deployed code. Resolves verified fixes. Requires git locally. Results reflect local git state — run git fetch first to ensure accuracy."
9
+ description "Verify fix_pending errors by checking whether the fix is in the deployed code: first by fix_sha ancestry, then — for squash/rebase merges, where fix_sha is not an ancestor of the deploy — by the fix PR's merge commit. Resolves verified fixes. Requires git locally (and gh for the PR fallback). Results reflect local git state — run git fetch first to ensure accuracy."
7
10
  input_schema(
8
11
  properties: {
9
12
  auto_resolve: { type: "boolean", description: "Resolve verified fixes automatically (default: true)" },
@@ -31,8 +34,7 @@ module RailsInformant
31
34
  pending = []
32
35
 
33
36
  errors.each do |error|
34
- fix_sha = error["fix_sha"]
35
- if fix_sha && ancestor?(fix_sha, ref)
37
+ if verified?(error, ref)
36
38
  verified << error
37
39
  else
38
40
  pending << error
@@ -55,10 +57,52 @@ module RailsInformant
55
57
 
56
58
  private
57
59
 
60
+ def verified?(error, target_ref)
61
+ fix_sha = error["fix_sha"]
62
+ return true if fix_sha && ancestor?(fix_sha, target_ref)
63
+
64
+ # Squash and rebase merges create a new commit unrelated to fix_sha, so the
65
+ # recorded SHA is never an ancestor of the deploy. Fall back to the PR's merge
66
+ # commit, which is in the deployed history regardless of merge strategy.
67
+ merge_sha = merged_pr_commit error["fix_pr_url"]
68
+ !merge_sha.nil? && ancestor?(merge_sha, target_ref)
69
+ end
70
+
58
71
  def ancestor?(fix_sha, target_ref)
59
72
  system "git", "merge-base", "--is-ancestor", fix_sha, target_ref, out: File::NULL, err: File::NULL
60
73
  end
61
74
 
75
+ # Returns the merge commit SHA of a merged PR, or nil if the PR is unmerged, the
76
+ # URL is blank, or gh is unavailable. Best-effort fetches the commit so the
77
+ # subsequent ancestry check can see it. Uses the array form (no shell) so the
78
+ # PR URL can't be interpreted as a command.
79
+ def merged_pr_commit(pr_url)
80
+ return if pr_url.nil? || pr_url.empty?
81
+ return unless gh_available?
82
+
83
+ output, status = Open3.capture2 "gh", "pr", "view", pr_url, "--json", "state,mergeCommit", err: File::NULL
84
+ return unless status.success? && !output.strip.empty?
85
+
86
+ data = JSON.parse output
87
+ return unless data["state"] == "MERGED"
88
+
89
+ merge_sha = data.dig "mergeCommit", "oid"
90
+ return if merge_sha.nil? || merge_sha.empty?
91
+
92
+ fetch_commit merge_sha
93
+ merge_sha
94
+ rescue JSON::ParserError
95
+ nil
96
+ end
97
+
98
+ def fetch_commit(sha)
99
+ system "git", "fetch", "--quiet", "origin", sha, out: File::NULL, err: File::NULL
100
+ end
101
+
102
+ def gh_available?
103
+ system "gh", "--version", out: File::NULL, err: File::NULL
104
+ end
105
+
62
106
  def fetch_all_fix_pending(client)
63
107
  errors = []
64
108
  page = 1
@@ -156,6 +156,12 @@ module RailsInformant
156
156
  return ENV[key] if ENV[key].present?
157
157
  end
158
158
 
159
+ revision_path = Rails.root.join("REVISION")
160
+ if revision_path.exist?
161
+ content = revision_path.read.strip
162
+ return content.match?(SHA_FORMAT) ? content : nil
163
+ end
164
+
159
165
  head = Rails.root.join(".git", "HEAD").read.strip
160
166
  if head.start_with?("ref: ")
161
167
  ref = head.delete_prefix("ref: ")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-informant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel López Prat
@@ -195,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
195
  - !ruby/object:Gem::Version
196
196
  version: '0'
197
197
  requirements: []
198
- rubygems_version: 4.0.6
198
+ rubygems_version: 4.0.10
199
199
  specification_version: 4
200
200
  summary: Self-hosted error monitoring for Rails with MCP server for agentic workflows
201
201
  test_files: []