octokitted 0.0.6 → 0.0.8

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: 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