Module: Brainiac::Plugins::Github

Defined in:
lib/brainiac/plugins/github.rb,
lib/brainiac/plugins/github/cli.rb,
lib/brainiac/plugins/github/config.rb,
lib/brainiac/plugins/github/handler.rb,
lib/brainiac/plugins/github/prompts.rb,
lib/brainiac/plugins/github/version.rb,
lib/brainiac/plugins/github/metadata.rb,
lib/brainiac/plugins/github/notifications.rb

Defined Under Namespace

Modules: Cli, Config, Handler, Notifications, Prompts

Constant Summary collapse

VERSION =
"0.0.3"

Class Method Summary collapse

Class Method Details

.cli(args) ⇒ Object

Plugin CLI entry points



85
86
87
# File 'lib/brainiac/plugins/github/cli.rb', line 85

def self.cli(args)
  Cli.run(args)
end

.completionsObject



89
90
91
# File 'lib/brainiac/plugins/github/cli.rb', line 89

def self.completions
  %w[setup config status]
end

.configured?Boolean

Returns true if GitHub webhook secret is configured.

Returns:

  • (Boolean)


12
13
14
15
16
17
18
19
20
# File 'lib/brainiac/plugins/github/metadata.rb', line 12

def self.configured?
  config_file = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "github.json")
  return false unless File.exist?(config_file)

  config = JSON.parse(File.read(config_file))
  !config["webhook_secret"].to_s.empty?
rescue StandardError
  false
end

.help_textObject

Help text shown in brainiac help when the plugin is installed.



23
24
25
# File 'lib/brainiac/plugins/github/metadata.rb', line 23

def self.help_text
  "    brainiac github <command>     Manage GitHub webhooks (setup, config, status)"
end

.post_install(brainiac_dir) ⇒ Object

Called after brainiac install github — creates config from template.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/brainiac/plugins/github.rb', line 27

def post_install(brainiac_dir)
  config_file = File.join(brainiac_dir, "github.json")
  return if File.exist?(config_file)

  template = File.expand_path("../../../templates/github.json.example", __dir__)
  if File.exist?(template)
    FileUtils.cp(template, config_file)
  else
    default_config = { "webhook_secret" => "", "repos" => {} }
    File.write(config_file, JSON.pretty_generate(default_config))
  end
end

.register(app) ⇒ Object

Called by Brainiac plugin system during server startup.

Parameters:

  • app (Sinatra::Application)

    The running Brainiac server



18
19
20
21
22
23
24
# File 'lib/brainiac/plugins/github.rb', line 18

def register(app)
  Config.load!
  Brainiac.register_channel_prompt(:github, Prompts::CHANNEL, pre_post_check: Prompts::PRE_POST_CHECK)
  register_crash_handler!
  setup_routes(app)
  LOG.info "[GitHub] Plugin registered (webhook: /github)"
end

.verify_signature!(request, payload_body) ⇒ Object

Verify the X-Hub-Signature-256 header (HMAC-SHA256 of the raw body).



146
147
148
149
150
151
152
153
# File 'lib/brainiac/plugins/github.rb', line 146

def self.verify_signature!(request, payload_body)
  signature = request.env["HTTP_X_HUB_SIGNATURE_256"]
  halt 403, { error: "Missing GitHub signature" }.to_json unless signature
  secret = Config.webhook_secret
  halt 500, { error: "GitHub webhook secret not configured" }.to_json unless secret
  computed = "sha256=#{OpenSSL::HMAC.hexdigest("sha256", secret, payload_body)}"
  halt 403, { error: "Invalid GitHub signature" }.to_json unless Rack::Utils.secure_compare(signature, computed)
end