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 +4 -4
- data/README.md +8 -0
- data/lib/octokitted/common/issue.rb +77 -0
- data/lib/octokitted.rb +62 -5
- data/lib/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7fe4c051e60f41068c020cd9c0fbfe3bae4d1cb673e22de5dc17c3b76e46ea9
|
4
|
+
data.tar.gz: b6c569962b05022e655a077f9f692c5d17a2bab406e29722188887dc7be248cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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
|
-
|
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
|
-
|
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
|
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
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.
|
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-
|
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
|