brainiac-github 0.2.3 → 0.2.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: 43962acb8ab8344a4e420e841550114d53082045252252ad340944dad73d267f
4
- data.tar.gz: eb8769a6f13771b1d057133fe8c72c3f3482602528ad0494475eb14022ea0d33
3
+ metadata.gz: 4cb6c5132e15d851261b150a636b895a0d8d8f6487b51a5049290a1ce2f12274
4
+ data.tar.gz: c6bf867e0bb5dbca4008e0971dc0568fb95755c2b296b7865e889e2d09645120
5
5
  SHA512:
6
- metadata.gz: bf3b0e3b90397dfd8232b2bd1fefab1f228dbb2b206d4f9b2766cbd064b6b2c9f4007bd651a7f3ab4ae91bd8934d674e814c931ef4549cf38eaa70b58d74b182
7
- data.tar.gz: b22dae8eacf0a45f9032eaadf63a33e945a17d4647ced3195254eb48d17962c2cf459a52214948d29407066c5217a09f21c093876cdd4dbde5e177e1296cabd2
6
+ metadata.gz: ed2481547416f7bd7d0194aff3ec96da00811c6fe2a4ee8478b4f90c63820fde0318e7ea2427ba07646bd5755abcba3ac2a3c32af78170abb6eebb461f54a4dc
7
+ data.tar.gz: 3df84f31506b7fbeeaf7636f84b8d8602a9e6fee9d6d8a6a4b18b4f5b76a9de666df79e5c2dccb9c81d1f90727bc8ffd60cc8b784776ea8f55ef0385e3234791
@@ -16,7 +16,8 @@ module Brainiac
16
16
  default_branch = payload.dig("repository", "default_branch") || "main"
17
17
 
18
18
  # Extract card number from branch name (e.g., "fizzy-1182-add-goodbye-method" → 1182)
19
- card_number_from_branch = branch&.match(/^fizzy-(\d+)-/)&.[](1)&.to_i
19
+ card_number_from_branch = branch&.match(/^fizzy-(\d+)-/)
20
+ card_number_from_branch = card_number_from_branch[1].to_i if card_number_from_branch
20
21
 
21
22
  # Emit a hook for ALL merges (including epic branches) so consumers can decide
22
23
  if card_number_from_branch
@@ -126,6 +127,14 @@ module Brainiac
126
127
  review_state = review["state"]
127
128
  reviewer = review.dig("user", "login")
128
129
 
130
+ # If the PR was opened by a remote agent bot (not local to this machine),
131
+ # skip dispatch — the other machine that owns the agent will handle it.
132
+ unless pr_owned_locally?(pr)
133
+ pr_author = pr.dig("user", "login")
134
+ LOG.info "[GitHub] PR ##{pr_number} owned by remote agent (#{pr_author}) — skipping dispatch"
135
+ return [200, { status: "ignored", reason: "PR owned by remote agent" }.to_json]
136
+ end
137
+
129
138
  project_result = identify_project_by_repo(repo_name)
130
139
  return [200, { status: "ignored", reason: "no matching project" }.to_json] unless project_result
131
140
 
@@ -192,6 +201,16 @@ module Brainiac
192
201
  return [200, { status: "ignored", reason: "not a PR comment" }.to_json]
193
202
  end
194
203
 
204
+ # If the PR was opened by a remote agent bot (not local to this machine),
205
+ # skip dispatch — the other machine that owns the agent will handle it.
206
+ pr_author = issue.dig("user", "login")
207
+ pr_author_type = issue.dig("user", "type")
208
+ unless pr_author_owned_locally?(pr_author, pr_author_type)
209
+ pr_number = issue["number"]
210
+ LOG.info "[GitHub] PR ##{pr_number} owned by remote agent (#{pr_author}) — skipping dispatch"
211
+ return [200, { status: "ignored", reason: "PR owned by remote agent" }.to_json]
212
+ end
213
+
195
214
  project_result = identify_project_by_repo(repo_name)
196
215
  unless project_result
197
216
  LOG.info "No project found for GitHub repo #{repo_name}"
@@ -317,6 +336,52 @@ module Brainiac
317
336
  nil
318
337
  end
319
338
 
339
+ # Determine if this machine should handle a PR based on who opened it.
340
+ # If the PR was opened by a bot that maps to a known agent, only the
341
+ # machine where that agent is local should dispatch. Human-opened PRs
342
+ # are always considered local (handled by normal routing logic).
343
+ #
344
+ # This prevents both machines from dispatching when they share the same
345
+ # GitHub webhook — e.g. Adam's Kaylee opens a PR, only Adam's machine handles it.
346
+ def pr_owned_locally?(pull_request)
347
+ pr_author = pull_request.dig("user", "login")
348
+ pr_author_type = pull_request.dig("user", "type")
349
+ pr_author_owned_locally?(pr_author, pr_author_type)
350
+ end
351
+
352
+ # Check PR ownership given the author login and account type.
353
+ # Used by both pull_request_review (has full PR object) and issue_comment
354
+ # (has issue.user which is the PR author on PR-linked issues).
355
+ def pr_author_owned_locally?(pr_author, pr_author_type)
356
+ # Human-opened PRs are always handled (normal routing applies)
357
+ return true unless pr_author_type == "Bot"
358
+
359
+ # Extract agent name from bot login (e.g. "kaylee-brainiac[bot]" → "Kaylee")
360
+ agent_from_bot = agent_name_from_bot_login(pr_author)
361
+ return true unless agent_from_bot
362
+
363
+ # If the bot's agent is local to this machine, we own it
364
+ local_agent_names.include?(agent_from_bot)
365
+ end
366
+
367
+ # Extract a Brainiac agent display name from a GitHub bot login.
368
+ # Bot logins follow the pattern "<name>-brainiac[bot]" or "<name>-brainiac".
369
+ # Returns the matched agent display name, or nil if not a known agent bot.
370
+ def agent_name_from_bot_login(bot_login)
371
+ return nil unless bot_login
372
+
373
+ # Normalize: remove [bot] suffix, lowercase
374
+ normalized = bot_login.to_s.downcase.delete_suffix("[bot]").strip
375
+
376
+ # Match against known agents — bot logins are "<agent>-brainiac"
377
+ all_agent_names.each do |name|
378
+ return name if normalized == "#{name.downcase}-brainiac"
379
+ return name if normalized == name.downcase
380
+ end
381
+
382
+ nil
383
+ end
384
+
320
385
  # Generate a GH_TOKEN env var for the agent process so `gh` CLI
321
386
  # authenticates as the app bot instead of the user's personal account.
322
387
  # Falls back to the shared "brainiac" app if the agent's own app isn't configured.
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Github
6
- VERSION = "0.2.3"
6
+ VERSION = "0.2.4"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis