github_events_agent.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. require 'github_api'
  2. module Agents
  3. class GithubEventsAgent < Agent
  4. cannot_receive_events!
  5. default_schedule "every_1h"
  6. gem_dependency_check { defined?(Github) }
  7. description <<-MD
  8. #{'## Include `github_api` in your Gemfile to use this Agent!' if dependencies_missing?}
  9. The GithubEventsAgent follows the events of a Github user or organization.
  10. Provide a Github `user` or `org` to monitor.
  11. Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
  12. MD
  13. event_description <<-MD
  14. Events are the raw JSON provided by the Github API. Should look something like:
  15. {"id"=>"2390633886",
  16. "type"=>"PullRequestReviewCommentEvent",
  17. "actor"=>
  18. {"id"=>66577,
  19. "login"=>"JakeWharton",
  20. ...
  21. "repo"=>
  22. {"id"=>7764585,
  23. "name"=>"square/spoon",
  24. "url"=>"https://api.github.com/repos/square/spoon"},
  25. "payload"=>
  26. {"action"=>"created",
  27. ...
  28. "public"=>true,
  29. "created_at"=>"2014-11-06T22:47:57Z",
  30. "org"=>
  31. {"id"=>82592,
  32. "login"=>"square",
  33. "url"=>"https://api.github.com/orgs/square",
  34. "avatar_url"=>"https://avatars.githubusercontent.com/u/82592?"
  35. ...
  36. }
  37. MD
  38. def validate_options
  39. errors.add(:base, "expected_update_period_in_days option required") unless options[:expected_update_period_in_days].present?
  40. unless options[:org].present? || options[:user].present?
  41. errors.add(:base, "The 'user' or 'org' option is required")
  42. end
  43. end
  44. def working?
  45. event_created_within?(options[:expected_update_period_in_days]) && !recent_error_logs?
  46. end
  47. def default_options
  48. {
  49. :user => "cantino",
  50. :expected_update_period_in_days => "2"
  51. }
  52. end
  53. def mode
  54. if options['user'].present?
  55. "user-#{options[:user]}"
  56. elsif options['org'].present?
  57. "org-#{options[:org]}"
  58. end
  59. end
  60. def github_events
  61. if options['user'].present?
  62. Github.activity.events.public(options[:user])
  63. elsif options['org'].present?
  64. Github.activity.events.org(options[:org])
  65. else
  66. raise "Must provide org or user"
  67. end
  68. end
  69. def check
  70. events = github_events
  71. if memory[:mode] == mode
  72. only_newer_than = memory[:max_event_id]
  73. else
  74. only_newer_than = 0
  75. end
  76. events.each do |event|
  77. if event.id > only_newer_than
  78. create_event :payload => event.as_json
  79. end
  80. end
  81. memory[:max_event_id] = events.map(&:id).max
  82. memory[:mode] = mode
  83. end
  84. end
  85. end