octokitted 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f50897f06c435796e586cc57693cd25e312344890f209d463df1a967879b36e3
4
- data.tar.gz: 7895d7418b7baaf86e33ac9cd457e3d80c9df0b16776cc4a23e9eec2183e02f2
3
+ metadata.gz: 930bcddc8ee154391c8deb09e7a2c0e483e49d6cb3091adeb70239d0388d3e5d
4
+ data.tar.gz: b64e1ba7b33e4c2eeb73975825bf5fa7cd2eaf37f63383b01427e4adddbd7e4a
5
5
  SHA512:
6
- metadata.gz: 32fc230ed082aebecc9c20a046a19dee3f98d1863385506d8cd12b1be5ac86a40bed13a55cabcd561fd0b865db7d7509e34fd4ec34f31993e306812df415aa8c
7
- data.tar.gz: 233c1748bfcba805594a9158ec56ef8197d4df432b8024fbf72756d38187b6e9d503e0bb68248b824760333f85e04dd9bf79ae40fead940bdba13d78055c951e
6
+ metadata.gz: c2738d3e5a2bb9bb665a8ed84f76ecbe4594b753e46b27a49d504587fbceae86f4a5905bd704368373bf4868551fe5a014716555e274f22fcad95b8d29eb107c
7
+ data.tar.gz: 486cf3f74dc41658968876d79d11383c1d8bfe7577f822c4fe17660555e96f4fa5480f180acd86bd140cbd8af7c972ad4068bb74436a8d2127238ba56141afb9
data/README.md CHANGED
@@ -3,3 +3,11 @@
3
3
  [![test](https://github.com/GrantBirki/octokitted/actions/workflows/test.yml/badge.svg)](https://github.com/GrantBirki/octokitted/actions/workflows/test.yml) [![lint](https://github.com/GrantBirki/octokitted/actions/workflows/lint.yml/badge.svg)](https://github.com/GrantBirki/octokitted/actions/workflows/lint.yml) [![CodeQL](https://github.com/GrantBirki/octokitted/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/GrantBirki/octokitted/actions/workflows/codeql-analysis.yml)
4
4
 
5
5
  A self-hydrating version of Octokit for usage in CI systems - like GitHub Actions!
6
+
7
+ > **kit** or **kitted** (_verb_)
8
+ >
9
+ > Defintion: provide someone or something with the appropriate clothing or equipment.
10
+ >
11
+ > "we were all kitted out in life jackets", "our octokit client was kitted out for CI usage"
12
+
13
+ ![octokitted](./docs/assets/dalle.png)
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "contracts"
4
+
5
+ class Issue
6
+ include Contracts::Core
7
+ include Contracts::Builtin
8
+
9
+ # A helper class for common operations on GitHub Issues
10
+ def initialize(octokitted)
11
+ @octokit = octokitted.octokit
12
+ @log = octokitted.log
13
+ @octokitted = octokitted
14
+ end
15
+
16
+ # Adds a set of labels to an issue or pull request
17
+ # :param labels: The labels to add to the issue (Array of strings)
18
+ # :param issue_number: The issue number to add labels to
19
+ Contract KeywordArgs[labels: ArrayOf[String], issue_number: Maybe[Numeric]] => Any
20
+ def add_labels(labels:, issue_number: nil)
21
+ issue_number = construct_issue_numer(issue_number)
22
+ @log.debug("adding labels: #{labels} to issue: #{issue_number}")
23
+
24
+ @octokit.add_labels_to_an_issue(@octokitted.org_and_repo, issue_number, labels)
25
+ end
26
+
27
+ # Removes a set of labels from an issue or pull request
28
+ # If the label does not exist, the exception is caught and logged
29
+ # :param labels: The labels to remove from the issue (Array of strings)
30
+ # :param issue_number: The issue number to remove labels from
31
+ Contract KeywordArgs[labels: ArrayOf[String], issue_number: Maybe[Numeric]] => Any
32
+ def remove_labels(labels:, issue_number: nil)
33
+ issue_number = construct_issue_numer(issue_number)
34
+ @log.debug("removing labels: #{labels} from issue: #{issue_number}")
35
+
36
+ labels.each do |label|
37
+ @octokit.remove_label(@octokitted.org_and_repo, issue_number, label)
38
+ rescue Octokit::NotFound
39
+ @log.warn("label: #{label} not found on issue: #{issue_number}")
40
+ end
41
+ end
42
+
43
+ # Adds a comment to an issue or pull request
44
+ # :param comment: The comment to add to the issue (String)
45
+ # :param issue_number: The issue number to add the comment to
46
+ Contract KeywordArgs[comment: String, issue_number: Maybe[Numeric]] => Any
47
+ def add_comment(comment:, issue_number: nil)
48
+ issue_number = construct_issue_numer(issue_number)
49
+ @log.debug("adding comment: #{comment} to issue: #{issue_number}")
50
+
51
+ @octokit.add_comment(@octokitted.org_and_repo, issue_number, comment)
52
+ end
53
+
54
+ # Closes an issue
55
+ # :param issue_number: The issue number to close
56
+ Contract KeywordArgs[issue_number: Maybe[Numeric], options: Maybe[Hash]] => Any
57
+ def close(issue_number: nil, options: {})
58
+ issue_number = construct_issue_numer(issue_number)
59
+ @log.debug("closing issue: #{issue_number}")
60
+
61
+ @octokit.close_issue(@octokitted.org_and_repo, issue_number, options)
62
+ end
63
+
64
+ private
65
+
66
+ # Helper method to construct the issue number from the auto-hydrated issue_number if it exists
67
+ # :param issue_number: The issue number to use if not nil
68
+ # :return: The issue number to use
69
+ # Note: If the issue_number is nil, we trye use the auto-hydrated issue_number...
70
+ # ... if the issue_number is not nil, we use that
71
+ Contract Maybe[Numeric] => Numeric
72
+ def construct_issue_numer(issue_number)
73
+ return @octokitted.issue_number if issue_number.nil?
74
+
75
+ return issue_number
76
+ end
77
+ end
data/lib/octokitted.rb CHANGED
@@ -5,23 +5,41 @@ require "logger"
5
5
  require "contracts"
6
6
 
7
7
  require_relative "octokitted/git_plugin"
8
+ require_relative "octokitted/common/issue"
8
9
 
9
10
  class Octokitted
10
11
  # A Octokitted class to interact with the GitHub API
11
- attr_reader :login, :org, :repo, :org_and_repo, :octokit, :cloned_repos
12
+ attr_reader :login,
13
+ :org,
14
+ :repo,
15
+ :org_and_repo,
16
+ :octokit,
17
+ :cloned_repos,
18
+ :log,
19
+ :github_event,
20
+ :sha,
21
+ :issue_number,
22
+ :issue
12
23
 
13
24
  include Contracts::Core
14
25
  include Contracts::Builtin
15
26
 
16
27
  # Initialize the class
28
+ # :param event_path: The path to the GitHub event data (defaults to the GITHUB_EVENT_PATH env var)
17
29
  # :param login: The login to use for GitHubAPI interactions (defaults to the owner of the token)
18
30
  # :param org: The org to use with the Octokitted class
19
31
  # :param repo: The repo to interact with with the Octokitted class
32
+ # :param issue_number: The issue/pull_request number to interact with with the Octokitted class
20
33
  # :param token: The token to use to authenticate with the GitHub API
21
34
  # :param logger: The logger to use for logging
22
- def initialize(login: nil, org: nil, repo: nil, token: nil, logger: nil)
35
+ #
36
+ # Note: If you do not provide an org, repo, token, or issue_number, Octokitted will attempt to self-hydrate...
37
+ # ... these values from the environment and the GitHub event data when you call `.new` on the class
38
+ def initialize(event_path: nil, login: nil, org: nil, repo: nil, issue_number: nil, token: nil, logger: nil)
23
39
  @log = logger || setup_logger
24
40
  @cloned_repos = []
41
+ @event_path = event_path || ENV.fetch("GITHUB_EVENT_PATH", nil)
42
+ @sha = ENV.fetch("GITHUB_SHA", nil)
25
43
  org_and_repo_hash = fetch_org_and_repo
26
44
  @login = login
27
45
  @org = org || org_and_repo_hash[:org]
@@ -29,10 +47,14 @@ class Octokitted
29
47
  @token = token || fetch_token
30
48
  @octokit = setup_octokit_client
31
49
  @org_and_repo = org_and_repo_hash[:org_and_repo]
50
+ @github_event = fetch_github_event(@event_path)
51
+ @issue_number = issue_number || fetch_issue_number(@github_event)
32
52
  @login = @octokit.login if @login.nil? # reset the login to the owner of the token if not provided
33
53
 
34
54
  # setup the git plugin
35
55
  @git = GitPlugin.new(logger: @log, login: @login, token: @token)
56
+ # setup the common Issue plugin
57
+ @issue = Issue.new(self)
36
58
 
37
59
  @log.debug("Octokitted initialized")
38
60
  @log.debug("login: #{@octokit.login}")
@@ -127,6 +149,38 @@ class Octokitted
127
149
  return { org_and_repo:, org:, repo: }
128
150
  end
129
151
 
152
+ # A helper method that attempts to self-hydrate context from the GitHub event data
153
+ # In Actions, the GITHUB_EVENT_PATH env var is set to a file containing the GitHub json event data
154
+ # If it exists, we try to load it into this class
155
+ # :param event_path: The path to the GitHub event data (defaults to the GITHUB_EVENT_PATH env var)
156
+ # :return: A Hash of the GitHub event data or nil if not found
157
+ Contract Maybe[String] => Maybe[Hash]
158
+ def fetch_github_event(event_path)
159
+ unless event_path
160
+ @log.warn("GITHUB_EVENT_PATH env var not found")
161
+ return nil
162
+ end
163
+
164
+ @log.info("GitHub Event data auto-hydrated")
165
+ return JSON.parse(File.read(event_path), symbolize_names: true)
166
+ end
167
+
168
+ # A helper method that attempts to self-hydrate the issue_number from the GitHub event data
169
+ # :param github_event: The GitHub event data (Hash)
170
+ # :return: The issue_number or nil if not found
171
+ Contract Maybe[Hash] => Maybe[Numeric]
172
+ def fetch_issue_number(github_event)
173
+ if github_event.nil?
174
+ @log.debug("GitHub event data not found - issue_number not auto-hydrated")
175
+ return nil
176
+ end
177
+
178
+ issue_number = (github_event[:issue] || github_event[:pull_request] || github_event)[:number]
179
+
180
+ @log.info("issue_number auto-hydrated - issue_number: #{issue_number}")
181
+ return issue_number
182
+ end
183
+
130
184
  # fetch the GitHub token from the environment
131
185
  # :return: The GitHub token or nil if not found
132
186
  Contract None => Maybe[String]
data/lib/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Octokitted
4
4
  module Version
5
- VERSION = "0.0.6"
5
+ VERSION = "0.0.7"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octokitted
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Birkinbine
@@ -78,6 +78,7 @@ files:
78
78
  - LICENSE
79
79
  - README.md
80
80
  - lib/octokitted.rb
81
+ - lib/octokitted/common/issue.rb
81
82
  - lib/octokitted/git_plugin.rb
82
83
  - lib/version.rb
83
84
  - octokitted.gemspec