lex-github 0.3.5 → 0.3.6
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/legion/extensions/github/absorbers/actor.rb +49 -0
- data/lib/legion/extensions/github/absorbers/helpers.rb +68 -0
- data/lib/legion/extensions/github/absorbers/issues.rb +200 -0
- data/lib/legion/extensions/github/absorbers/webhook_setup.rb +101 -0
- data/lib/legion/extensions/github/version.rb +1 -1
- data/lib/legion/extensions/github.rb +6 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 345057d3d4b8e4716221915d9f398ec586cbc5485674e07b3fd9cf79788fb281
|
|
4
|
+
data.tar.gz: d3a320f5202c7c77115b1ab28d7a65f2c975fe063864634ffadcb526b8370a65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c84b0641ad42300d82b2b073133bacacf9ab7aa89ccd7fb859ab16daf771f69d86102d2261fe36d785bbb09b9d48f1170dd463be08886e76388d670eb1184556
|
|
7
|
+
data.tar.gz: 3c0a0a2ab0861ec6eda83e1f1067e791583b556fe0d9166e072a8bba1f97cd458c874715ee88e74868a89aae64d3bcd9b0a75e8e3d4a8ba9f2396cd3f3559306
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.3.6] - 2026-04-14
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `Absorbers::Issues`: normalizes GitHub issue webhook events to fleet work items; filters bot-generated events, already-claimed issues (fleet labels), and ignored actions; stores raw payload in Redis; publishes to assessor queue
|
|
9
|
+
- `Absorbers::IssuesActor`: subscription actor with `pattern 'github.issues.*'` that delegates to `Absorbers::Issues`
|
|
10
|
+
- `Absorbers::WebhookSetup`: mixin for idempotent webhook registration and fleet label creation (`fleet:received`, `fleet:implementing`, `fleet:pr-open`, `fleet:escalated`) on target repos
|
|
11
|
+
- `Absorbers::Helpers`: shared utilities — `bot_generated?`, `has_fleet_label?`, `ignored?`, `work_item_fingerprint`, `generate_work_item_id`, `transport_connected?`
|
|
12
|
+
|
|
5
13
|
## [0.3.5] - 2026-04-13
|
|
6
14
|
|
|
7
15
|
### Added
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# lib/legion/extensions/github/absorbers/actor.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative 'issues'
|
|
5
|
+
|
|
6
|
+
module Legion
|
|
7
|
+
module Extensions
|
|
8
|
+
module Github
|
|
9
|
+
module Absorbers
|
|
10
|
+
# Subscription actor that listens on the absorber queue and delegates
|
|
11
|
+
# to the Issues absorber module.
|
|
12
|
+
#
|
|
13
|
+
# Queue: lex.github.absorbers.issues.absorb
|
|
14
|
+
# Exchange: lex.github
|
|
15
|
+
# Routing key: lex.github.absorbers.issues.absorb
|
|
16
|
+
#
|
|
17
|
+
# Per Wire Protocol section 17, absorber queues follow the pattern:
|
|
18
|
+
# lex.{lex_name}.absorbers.{absorber_name}.absorb
|
|
19
|
+
class IssuesActor < Legion::Extensions::Actors::Subscription
|
|
20
|
+
pattern 'github.issues.*'
|
|
21
|
+
|
|
22
|
+
def absorb(payload:, **)
|
|
23
|
+
Legion::Extensions::Github::Absorbers::Issues.absorb(payload: payload)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def runner_class
|
|
27
|
+
Legion::Extensions::Github::Absorbers::Issues
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def runner_function
|
|
31
|
+
'absorb'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def use_runner?
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def check_subtask?
|
|
39
|
+
false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def generate_task?
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# lib/legion/extensions/github/absorbers/helpers.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'digest'
|
|
5
|
+
require 'securerandom'
|
|
6
|
+
|
|
7
|
+
module Legion
|
|
8
|
+
module Extensions
|
|
9
|
+
module Github
|
|
10
|
+
module Absorbers
|
|
11
|
+
module Helpers
|
|
12
|
+
FLEET_LABELS = %w[
|
|
13
|
+
fleet:received fleet:implementing fleet:pr-open fleet:escalated
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
IGNORED_ACTIONS = %w[
|
|
17
|
+
closed transferred deleted pinned unpinned milestoned demilestoned
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
BOT_PATTERNS = /\[bot\]\z/i
|
|
21
|
+
|
|
22
|
+
def bot_generated?(payload)
|
|
23
|
+
sender = payload['sender'] || payload[:sender]
|
|
24
|
+
return false unless sender
|
|
25
|
+
|
|
26
|
+
login = sender['login'] || sender[:login] || ''
|
|
27
|
+
type = sender['type'] || sender[:type] || ''
|
|
28
|
+
|
|
29
|
+
type.downcase == 'bot' || login.match?(BOT_PATTERNS)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def has_fleet_label?(payload) # rubocop:disable Naming/PredicatePrefix
|
|
33
|
+
issue = payload['issue'] || payload[:issue]
|
|
34
|
+
return false unless issue
|
|
35
|
+
|
|
36
|
+
labels = issue['labels'] || issue[:labels] || []
|
|
37
|
+
labels.any? do |label|
|
|
38
|
+
name = label['name'] || label[:name]
|
|
39
|
+
FLEET_LABELS.include?(name)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def ignored?(payload)
|
|
44
|
+
action = payload['action'] || payload[:action]
|
|
45
|
+
IGNORED_ACTIONS.include?(action.to_s)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def work_item_fingerprint(source:, ref:, title:)
|
|
49
|
+
input = "#{source}:#{ref}:#{title}"
|
|
50
|
+
Digest::SHA256.hexdigest(input)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def generate_work_item_id
|
|
54
|
+
SecureRandom.uuid
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def transport_connected?
|
|
58
|
+
return false unless defined?(Legion::Settings)
|
|
59
|
+
|
|
60
|
+
!!Legion::Settings.dig(:transport, :connected)
|
|
61
|
+
rescue StandardError => _e
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# lib/legion/extensions/github/absorbers/issues.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative 'helpers'
|
|
5
|
+
|
|
6
|
+
module Legion
|
|
7
|
+
module Extensions
|
|
8
|
+
module Github
|
|
9
|
+
module Absorbers
|
|
10
|
+
# Absorbs GitHub issue events and normalizes them to fleet work items.
|
|
11
|
+
# Subscribes to lex.github.absorbers.issues queue.
|
|
12
|
+
#
|
|
13
|
+
# Filters: bot events, already-claimed issues (fleet labels), ignored
|
|
14
|
+
# actions (closed, transferred, etc.).
|
|
15
|
+
#
|
|
16
|
+
# Publishes normalized work items to the assessor queue via task chain.
|
|
17
|
+
module Issues
|
|
18
|
+
extend self
|
|
19
|
+
extend Helpers
|
|
20
|
+
|
|
21
|
+
CACHE_TTL = 86_400 # 24 hours
|
|
22
|
+
|
|
23
|
+
def description_max_bytes
|
|
24
|
+
Legion::Settings.dig(:fleet, :work_item, :description_max_bytes) || 32_768
|
|
25
|
+
rescue StandardError => _e
|
|
26
|
+
32_768
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Main entry point. Called by the subscription actor when a GitHub
|
|
30
|
+
# webhook event for issues arrives.
|
|
31
|
+
#
|
|
32
|
+
# @param payload [Hash] Raw GitHub webhook payload (string keys from JSON)
|
|
33
|
+
# @return [Hash] { absorbed: true/false, ... }
|
|
34
|
+
def absorb(payload:, **)
|
|
35
|
+
return { absorbed: false, reason: :bot_generated } if bot_generated?(payload)
|
|
36
|
+
return { absorbed: false, reason: :already_claimed } if has_fleet_label?(payload)
|
|
37
|
+
return { absorbed: false, reason: :ignored } if ignored?(payload)
|
|
38
|
+
|
|
39
|
+
work_item = normalize(payload)
|
|
40
|
+
|
|
41
|
+
# NOTE: Absorber does NOT call set_nx — the assessor is the single dedup authority.
|
|
42
|
+
# Source-specific dedup only: label checks, bot filter, action filter.
|
|
43
|
+
|
|
44
|
+
# Store large raw payload in Redis, not inline in AMQP message
|
|
45
|
+
cache_key = "fleet:payload:#{work_item[:work_item_id]}"
|
|
46
|
+
cache_set(cache_key, json_dump(payload), ttl: CACHE_TTL)
|
|
47
|
+
work_item[:raw_payload_ref] = cache_key
|
|
48
|
+
|
|
49
|
+
# Publish to assessor via transport
|
|
50
|
+
publish_result = publish_to_assessor(work_item)
|
|
51
|
+
|
|
52
|
+
# Propagate publish failures — do not swallow
|
|
53
|
+
return publish_result if publish_result.is_a?(Hash) && publish_result[:absorbed] == false
|
|
54
|
+
|
|
55
|
+
{ absorbed: true, work_item_id: work_item[:work_item_id] }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Normalize a raw GitHub webhook payload to the standard fleet work
|
|
59
|
+
# item format (design spec section 3).
|
|
60
|
+
#
|
|
61
|
+
# @param payload [Hash] Raw GitHub webhook payload (string keys)
|
|
62
|
+
# @return [Hash] Normalized work item (symbol keys)
|
|
63
|
+
def normalize(payload)
|
|
64
|
+
issue = payload['issue'] || {}
|
|
65
|
+
repo = payload['repository'] || {}
|
|
66
|
+
action = payload['action'] || 'opened'
|
|
67
|
+
owner = repo.dig('owner', 'login') || ''
|
|
68
|
+
repo_name = repo['name'] || ''
|
|
69
|
+
number = issue['number']
|
|
70
|
+
body = issue['body'] || ''
|
|
71
|
+
max_bytes = description_max_bytes
|
|
72
|
+
|
|
73
|
+
{
|
|
74
|
+
work_item_id: generate_work_item_id,
|
|
75
|
+
source: 'github',
|
|
76
|
+
source_ref: "#{owner}/#{repo_name}##{number}",
|
|
77
|
+
source_event: "issues.#{action}",
|
|
78
|
+
|
|
79
|
+
title: issue['title'] || '',
|
|
80
|
+
description: body.bytesize > max_bytes ? body.byteslice(0, max_bytes).scrub('') : body,
|
|
81
|
+
raw_payload_ref: nil, # set after cache write in absorb
|
|
82
|
+
|
|
83
|
+
repo: {
|
|
84
|
+
owner: owner,
|
|
85
|
+
name: repo_name,
|
|
86
|
+
default_branch: repo['default_branch'] || 'main',
|
|
87
|
+
language: repo['language'] || 'unknown'
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
instructions: [],
|
|
91
|
+
context: [],
|
|
92
|
+
|
|
93
|
+
config: default_config,
|
|
94
|
+
|
|
95
|
+
pipeline: {
|
|
96
|
+
stage: 'intake',
|
|
97
|
+
trace: [],
|
|
98
|
+
attempt: 0,
|
|
99
|
+
feedback_history: [],
|
|
100
|
+
plan: nil,
|
|
101
|
+
changes: nil,
|
|
102
|
+
review_result: nil,
|
|
103
|
+
pr_number: nil,
|
|
104
|
+
branch_name: nil,
|
|
105
|
+
context_ref: nil
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
def default_config
|
|
113
|
+
{
|
|
114
|
+
priority: :medium,
|
|
115
|
+
complexity: nil,
|
|
116
|
+
estimated_difficulty: nil,
|
|
117
|
+
planning: default_config_planning,
|
|
118
|
+
implementation: default_config_implementation,
|
|
119
|
+
validation: default_config_validation,
|
|
120
|
+
feedback: default_config_feedback,
|
|
121
|
+
workspace: { isolation: :worktree, cleanup_on_complete: true },
|
|
122
|
+
context: { load_repo_docs: true, load_file_tree: true, max_context_files: 50 },
|
|
123
|
+
tracing: { stage_comments: true, token_tracking: true },
|
|
124
|
+
safety: { poison_message_threshold: 2, cancel_allowed: true },
|
|
125
|
+
selection: { strategy: :test_winner },
|
|
126
|
+
escalation: { on_max_iterations: :human, consent_domain: 'fleet.shipping' }
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def default_config_planning
|
|
131
|
+
{ enabled: true, solvers: 1, validators: 1, max_iterations: 2 }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def default_config_implementation
|
|
135
|
+
{ solvers: 1, validators: 3, max_iterations: 5, models: nil }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def default_config_validation
|
|
139
|
+
{
|
|
140
|
+
enabled: true,
|
|
141
|
+
run_tests: true,
|
|
142
|
+
run_lint: true,
|
|
143
|
+
security_scan: true,
|
|
144
|
+
adversarial_review: true,
|
|
145
|
+
reviewer_models: nil
|
|
146
|
+
}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def default_config_feedback
|
|
150
|
+
{ drain_enabled: true, max_drain_rounds: 3, summarize_after: 2 }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Publish the normalized work item to the assessor's queue.
|
|
154
|
+
# Uses Legion::Transport::Messages::Task.
|
|
155
|
+
#
|
|
156
|
+
# generate_task_id returns a Hash { success:, task_id:, ... } — extract task_id.
|
|
157
|
+
# function: must be a String ('assess'), never a Symbol.
|
|
158
|
+
# Do NOT pass exchange: as String (broken until WS-00F lands).
|
|
159
|
+
#
|
|
160
|
+
# Propagates failures — returns { absorbed: false, reason: :publish_failed, ... }
|
|
161
|
+
def publish_to_assessor(work_item)
|
|
162
|
+
# Transport unavailable = lite mode / test environment. Not a publish failure; skip silently.
|
|
163
|
+
return unless transport_connected? && defined?(Legion::Runner)
|
|
164
|
+
|
|
165
|
+
result = Legion::Runner::Status.generate_task_id(
|
|
166
|
+
runner_class: 'Legion::Extensions::Assessor::Runners::Assessor',
|
|
167
|
+
function: 'assess'
|
|
168
|
+
)
|
|
169
|
+
task_id = result&.dig(:task_id)
|
|
170
|
+
raise 'Fleet: cannot create task record (is legion-data connected?)' if task_id.nil?
|
|
171
|
+
|
|
172
|
+
Legion::Transport::Messages::Task.new(
|
|
173
|
+
work_item: work_item,
|
|
174
|
+
function: 'assess',
|
|
175
|
+
task_id: task_id,
|
|
176
|
+
master_id: task_id,
|
|
177
|
+
routing_key: 'lex.assessor.runners.assessor.assess'
|
|
178
|
+
).publish
|
|
179
|
+
rescue StandardError => e
|
|
180
|
+
log.warn("Absorber publish failed: #{e.message}")
|
|
181
|
+
{ absorbed: false, reason: :publish_failed, message: e.message }
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Direct delegators to Legion::Cache and Legion::JSON.
|
|
185
|
+
# These thin wrappers satisfy the HelperMigration cops at call sites
|
|
186
|
+
# while preserving full control over key format and arguments.
|
|
187
|
+
# rubocop:disable Legion/HelperMigration/DirectCache, Legion/HelperMigration/DirectJson
|
|
188
|
+
def cache_set(key, value, ttl: nil)
|
|
189
|
+
Legion::Cache.set(key, value, ttl: ttl)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def json_dump(object)
|
|
193
|
+
Legion::JSON.dump(object)
|
|
194
|
+
end
|
|
195
|
+
# rubocop:enable Legion/HelperMigration/DirectCache, Legion/HelperMigration/DirectJson
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# lib/legion/extensions/github/absorbers/webhook_setup.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Legion
|
|
5
|
+
module Extensions
|
|
6
|
+
module Github
|
|
7
|
+
module Absorbers
|
|
8
|
+
# Mixin for auto-registering GitHub webhooks and fleet labels on a repo.
|
|
9
|
+
# Used by `legionio fleet add github` to wire up the absorber source.
|
|
10
|
+
#
|
|
11
|
+
# Include this module in a class that also includes the GitHub runners
|
|
12
|
+
# (RepositoryWebhooks, Labels).
|
|
13
|
+
module WebhookSetup
|
|
14
|
+
FLEET_WEBHOOK_EVENTS = %w[issues pull_request].freeze
|
|
15
|
+
|
|
16
|
+
FLEET_LABELS = [
|
|
17
|
+
{ name: 'fleet:received', color: '6f42c1', description: 'Fleet pipeline has received this issue' },
|
|
18
|
+
{ name: 'fleet:implementing', color: '0e8a16', description: 'Fleet is implementing a fix' },
|
|
19
|
+
{ name: 'fleet:pr-open', color: '1d76db', description: 'Fleet has opened a PR for this issue' },
|
|
20
|
+
{ name: 'fleet:escalated', color: 'e4e669', description: 'Fleet escalated this issue to a human' }
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
# Set up fleet webhook and labels on a GitHub repo.
|
|
24
|
+
#
|
|
25
|
+
# @param owner [String] Repository owner/org
|
|
26
|
+
# @param repo [String] Repository name
|
|
27
|
+
# @param webhook_url [String] Callback URL for webhook delivery
|
|
28
|
+
# @return [Hash] { success:, webhook_id:, labels_created: }
|
|
29
|
+
def setup_fleet_webhook(owner:, repo:, webhook_url:, **)
|
|
30
|
+
# Check if webhook already exists
|
|
31
|
+
existing = list_webhooks(owner: owner, repo: repo)
|
|
32
|
+
existing_hook = (existing[:result] || []).find do |hook|
|
|
33
|
+
url = hook.is_a?(Hash) ? (hook.dig('config', 'url') || hook.dig(:config, :url)) : nil
|
|
34
|
+
url == webhook_url
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if existing_hook
|
|
38
|
+
hook_id = existing_hook['id'] || existing_hook[:id]
|
|
39
|
+
labels = ensure_fleet_labels(owner: owner, repo: repo)
|
|
40
|
+
return { success: true, existing: true, webhook_id: hook_id, labels_created: labels }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Create webhook
|
|
44
|
+
config = {
|
|
45
|
+
url: webhook_url,
|
|
46
|
+
content_type: 'json',
|
|
47
|
+
insecure_ssl: '0'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
result = create_webhook(
|
|
51
|
+
owner: owner,
|
|
52
|
+
repo: repo,
|
|
53
|
+
config: config,
|
|
54
|
+
events: FLEET_WEBHOOK_EVENTS,
|
|
55
|
+
active: true
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
webhook_data = result[:result] || {}
|
|
59
|
+
webhook_id = webhook_data['id'] || webhook_data[:id]
|
|
60
|
+
|
|
61
|
+
return { success: false, error: 'webhook creation returned no id' } if webhook_id.nil?
|
|
62
|
+
|
|
63
|
+
# Create fleet labels
|
|
64
|
+
labels = ensure_fleet_labels(owner: owner, repo: repo)
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
success: true,
|
|
68
|
+
existing: false,
|
|
69
|
+
webhook_id: webhook_id,
|
|
70
|
+
webhook_url: webhook_url,
|
|
71
|
+
labels_created: labels
|
|
72
|
+
}
|
|
73
|
+
rescue StandardError => e
|
|
74
|
+
{ success: false, error: e.message }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def fleet_label_definitions
|
|
78
|
+
FLEET_LABELS
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def ensure_fleet_labels(owner:, repo:)
|
|
84
|
+
created = []
|
|
85
|
+
FLEET_LABELS.each do |label_def|
|
|
86
|
+
create_label(
|
|
87
|
+
owner: owner,
|
|
88
|
+
repo: repo,
|
|
89
|
+
name: label_def[:name],
|
|
90
|
+
color: label_def[:color],
|
|
91
|
+
description: label_def[:description]
|
|
92
|
+
)
|
|
93
|
+
created << label_def[:name]
|
|
94
|
+
end
|
|
95
|
+
created
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -37,6 +37,12 @@ require 'legion/extensions/github/runners/releases'
|
|
|
37
37
|
require 'legion/extensions/github/runners/deployments'
|
|
38
38
|
require 'legion/extensions/github/runners/auth'
|
|
39
39
|
require 'legion/extensions/github/runners/repository_webhooks'
|
|
40
|
+
|
|
41
|
+
# Absorber modules (fleet pipeline intake)
|
|
42
|
+
require 'legion/extensions/github/absorbers/helpers'
|
|
43
|
+
require 'legion/extensions/github/absorbers/issues'
|
|
44
|
+
require 'legion/extensions/github/absorbers/webhook_setup'
|
|
45
|
+
|
|
40
46
|
require 'legion/extensions/github/client'
|
|
41
47
|
require 'legion/extensions/github/cli/runner'
|
|
42
48
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-github
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -170,6 +170,10 @@ files:
|
|
|
170
170
|
- README.md
|
|
171
171
|
- lex-github.gemspec
|
|
172
172
|
- lib/legion/extensions/github.rb
|
|
173
|
+
- lib/legion/extensions/github/absorbers/actor.rb
|
|
174
|
+
- lib/legion/extensions/github/absorbers/helpers.rb
|
|
175
|
+
- lib/legion/extensions/github/absorbers/issues.rb
|
|
176
|
+
- lib/legion/extensions/github/absorbers/webhook_setup.rb
|
|
173
177
|
- lib/legion/extensions/github/app/actor/token_refresh.rb
|
|
174
178
|
- lib/legion/extensions/github/app/actor/webhook_poller.rb
|
|
175
179
|
- lib/legion/extensions/github/app/hooks/setup.rb
|