octokitted 0.0.6 → 0.0.8

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: f50897f06c435796e586cc57693cd25e312344890f209d463df1a967879b36e3
4
- data.tar.gz: 7895d7418b7baaf86e33ac9cd457e3d80c9df0b16776cc4a23e9eec2183e02f2
3
+ metadata.gz: c7fe4c051e60f41068c020cd9c0fbfe3bae4d1cb673e22de5dc17c3b76e46ea9
4
+ data.tar.gz: b6c569962b05022e655a077f9f692c5d17a2bab406e29722188887dc7be248cc
5
5
  SHA512:
6
- metadata.gz: 32fc230ed082aebecc9c20a046a19dee3f98d1863385506d8cd12b1be5ac86a40bed13a55cabcd561fd0b865db7d7509e34fd4ec34f31993e306812df415aa8c
7
- data.tar.gz: 233c1748bfcba805594a9158ec56ef8197d4df432b8024fbf72756d38187b6e9d503e0bb68248b824760333f85e04dd9bf79ae40fead940bdba13d78055c951e
6
+ metadata.gz: b3a9add54171018622c44d309e6ac50435d3c225fe4795eb917c9812a3a567881210fa8f538b6b575eb00cb7bc7d2831da3899cfa9f29115ef30ce42fffa384f
7
+ data.tar.gz: 2cb81e5b5a4e078cfc7dec09202092c01c609a888ffc2c6e176390f45de1ebcdd3f4c9873378a90ccd33fddc4d4425493846af1288886ee2f1489a7e38432dbe
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,34 +5,56 @@ 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 = []
25
- org_and_repo_hash = fetch_org_and_repo
41
+ @event_path = event_path || ENV.fetch("GITHUB_EVENT_PATH", nil)
42
+ @sha = ENV.fetch("GITHUB_SHA", nil)
43
+ org_and_repo_hash = fetch_org_and_repo(org, repo)
26
44
  @login = login
27
45
  @org = org || org_and_repo_hash[:org]
28
46
  @repo = repo || org_and_repo_hash[:repo]
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}")
@@ -115,8 +137,11 @@ class Octokitted
115
137
 
116
138
  # Fetch the org and repo from the environment
117
139
  # :return: A hash containing the org and repo, and the org and repo separately
118
- Contract None => HashOf[Symbol, String]
119
- def fetch_org_and_repo
140
+ Contract Maybe[String], Maybe[String] => Hash
141
+ def fetch_org_and_repo(org, repo)
142
+ # if org and repo are provided, and not nil, use them
143
+ return { org_and_repo: "#{org}/#{repo}", org:, repo: } if org && repo
144
+
120
145
  org_and_repo = ENV.fetch("GITHUB_REPOSITORY", nil)
121
146
  org = nil
122
147
  repo = nil
@@ -127,6 +152,38 @@ class Octokitted
127
152
  return { org_and_repo:, org:, repo: }
128
153
  end
129
154
 
155
+ # A helper method that attempts to self-hydrate context from the GitHub event data
156
+ # In Actions, the GITHUB_EVENT_PATH env var is set to a file containing the GitHub json event data
157
+ # If it exists, we try to load it into this class
158
+ # :param event_path: The path to the GitHub event data (defaults to the GITHUB_EVENT_PATH env var)
159
+ # :return: A Hash of the GitHub event data or nil if not found
160
+ Contract Maybe[String] => Maybe[Hash]
161
+ def fetch_github_event(event_path)
162
+ unless event_path
163
+ @log.warn("GITHUB_EVENT_PATH env var not found")
164
+ return nil
165
+ end
166
+
167
+ @log.info("GitHub Event data auto-hydrated")
168
+ return JSON.parse(File.read(event_path), symbolize_names: true)
169
+ end
170
+
171
+ # A helper method that attempts to self-hydrate the issue_number from the GitHub event data
172
+ # :param github_event: The GitHub event data (Hash)
173
+ # :return: The issue_number or nil if not found
174
+ Contract Maybe[Hash] => Maybe[Numeric]
175
+ def fetch_issue_number(github_event)
176
+ if github_event.nil?
177
+ @log.debug("GitHub event data not found - issue_number not auto-hydrated")
178
+ return nil
179
+ end
180
+
181
+ issue_number = (github_event[:issue] || github_event[:pull_request] || github_event)[:number]
182
+
183
+ @log.info("issue_number auto-hydrated - issue_number: #{issue_number}")
184
+ return issue_number
185
+ end
186
+
130
187
  # fetch the GitHub token from the environment
131
188
  # :return: The GitHub token or nil if not found
132
189
  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.8"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
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.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Birkinbine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-16 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts
@@ -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