lex-github 0.2.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2b41a2645cf0a1f493ee1ef0f3d2f22266991bd9dfa5c813c1cba1648a937fac
4
+ data.tar.gz: 5d3e0a486b37e90636342ce17be51ce181ef60a6c1a9699cbcbb47f2626e1f7c
5
+ SHA512:
6
+ metadata.gz: f2a930630311be550739e8f26817c58f3cd5baa1282dcec0b10c9e2354dd1f94f102d9426704b610c296633a429a7a5e24710a3909237ae9bfa91ce04db0ab4d
7
+ data.tar.gz: 9c9d927e3e3067fdc20932d48fa4e18f3a85e02b8793810c2fc0c065cd5c279e371a2ac76b67d0fdcf8fc6b7bd0a5e4f0e6eb001f9e63d5944c24842619c6409
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,53 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
6
+ Layout/LineLength:
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
16
+ Metrics/MethodLength:
17
+ Max: 50
18
+
19
+ Metrics/ClassLength:
20
+ Max: 1500
21
+
22
+ Metrics/ModuleLength:
23
+ Max: 1500
24
+
25
+ Metrics/BlockLength:
26
+ Max: 40
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
30
+ Metrics/ParameterLists:
31
+ Max: 8
32
+
33
+ Metrics/AbcSize:
34
+ Max: 60
35
+
36
+ Metrics/CyclomaticComplexity:
37
+ Max: 15
38
+
39
+ Metrics/PerceivedComplexity:
40
+ Max: 17
41
+
42
+ Style/Documentation:
43
+ Enabled: false
44
+
45
+ Style/SymbolArray:
46
+ Enabled: true
47
+
48
+ Style/FrozenStringLiteralComment:
49
+ Enabled: true
50
+ EnforcedStyle: always
51
+
52
+ Naming/FileName:
53
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2026-03-15
4
+
5
+ ### Added
6
+ - `Runners::Labels` — full label management: `list_labels`, `get_label`, `create_label`, `update_label`, `delete_label`, `add_labels_to_issue`, `remove_label_from_issue`
7
+ - `Runners::Comments` — issue comment threads: `list_comments`, `get_comment`, `create_comment`, `update_comment`, `delete_comment`
8
+ - `Runners::PullRequests#list_pull_request_reviews` — GET reviews for a pull request
9
+ - `Runners::Commits` included in `Client` class (was already implemented but not wired up)
10
+ - Specs for all new methods
11
+
12
+ ## [0.1.0] - 2026-03-13
13
+
14
+ ### Added
15
+ - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,71 @@
1
+ # lex-github: GitHub Integration for LegionIO
2
+
3
+ **Repository Level 3 Documentation**
4
+ - **Parent (Level 2)**: `/Users/miverso2/rubymine/legion/extensions/CLAUDE.md`
5
+ - **Parent (Level 1)**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Legion Extension that connects LegionIO to GitHub. Provides runners for interacting with the GitHub REST API covering repositories, issues, pull requests, users, organizations, gists, search, labels, comments, and commits.
10
+
11
+ **GitHub**: https://github.com/LegionIO/lex-github
12
+ **License**: MIT
13
+ **Version**: 0.2.0
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ Legion::Extensions::Github
19
+ ├── Runners/
20
+ │ ├── Repositories # CRUD repos, list branches/tags
21
+ │ ├── Issues # CRUD issues
22
+ │ ├── PullRequests # CRUD PRs, merge, list commits/files/reviews
23
+ │ ├── Users # Get users, list followers/following
24
+ │ ├── Organizations # Get orgs, list repos/members
25
+ │ ├── Gists # CRUD gists
26
+ │ ├── Search # Search repos, issues, users, code
27
+ │ ├── Labels # CRUD labels, add/remove issue labels
28
+ │ ├── Comments # CRUD issue/PR comments
29
+ │ └── Commits # List, get, compare commits
30
+ ├── Helpers/
31
+ │ └── Client # Faraday connection builder (GitHub API v3)
32
+ └── Client # Standalone client class (includes all runners)
33
+ ```
34
+
35
+ ## Dependencies
36
+
37
+ | Gem | Purpose |
38
+ |-----|---------|
39
+ | `faraday` | HTTP client for GitHub REST API |
40
+
41
+ ## Key Files
42
+
43
+ | File | Purpose |
44
+ |------|---------|
45
+ | `lib/legion/extensions/github.rb` | Extension entry point, requires all runners |
46
+ | `lib/legion/extensions/github/client.rb` | Standalone client class |
47
+ | `lib/legion/extensions/github/helpers/client.rb` | Faraday connection builder |
48
+ | `lib/legion/extensions/github/runners/repositories.rb` | Repo CRUD, branches, tags |
49
+ | `lib/legion/extensions/github/runners/issues.rb` | Issue CRUD |
50
+ | `lib/legion/extensions/github/runners/pull_requests.rb` | PR CRUD, merge, files, reviews |
51
+ | `lib/legion/extensions/github/runners/users.rb` | User lookup, followers/following |
52
+ | `lib/legion/extensions/github/runners/organizations.rb` | Org info, repos, members |
53
+ | `lib/legion/extensions/github/runners/gists.rb` | Gist CRUD |
54
+ | `lib/legion/extensions/github/runners/search.rb` | Search repos/issues/users/code |
55
+ | `lib/legion/extensions/github/runners/labels.rb` | Label CRUD, add/remove on issues |
56
+ | `lib/legion/extensions/github/runners/comments.rb` | Issue/PR comment CRUD |
57
+ | `lib/legion/extensions/github/runners/commits.rb` | List, get, compare commits |
58
+
59
+ ## Testing
60
+
61
+ 47 specs across 13 spec files.
62
+
63
+ ```bash
64
+ bundle install
65
+ bundle exec rspec
66
+ bundle exec rubocop
67
+ ```
68
+
69
+ ---
70
+
71
+ **Maintained By**: Matthew Iverson (@Esity)
data/Dockerfile ADDED
@@ -0,0 +1,6 @@
1
+ FROM legionio/legion
2
+
3
+ COPY . /usr/src/app/lex-github
4
+
5
+ WORKDIR /usr/src/app/lex-github
6
+ RUN bundle install
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'rspec_junit_formatter'
10
+ gem 'rubocop'
11
+ gem 'simplecov'
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,98 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lex-github (0.2.0)
5
+ faraday (>= 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.8.9)
11
+ public_suffix (>= 2.0.2, < 8.0)
12
+ ast (2.4.3)
13
+ bigdecimal (4.0.1)
14
+ diff-lcs (1.6.2)
15
+ docile (1.4.1)
16
+ faraday (2.14.1)
17
+ faraday-net_http (>= 2.0, < 3.5)
18
+ json
19
+ logger
20
+ faraday-net_http (3.4.2)
21
+ net-http (~> 0.5)
22
+ json (2.19.1)
23
+ json-schema (6.2.0)
24
+ addressable (~> 2.8)
25
+ bigdecimal (>= 3.1, < 5)
26
+ language_server-protocol (3.17.0.5)
27
+ lint_roller (1.1.0)
28
+ logger (1.7.0)
29
+ mcp (0.8.0)
30
+ json-schema (>= 4.1)
31
+ net-http (0.9.1)
32
+ uri (>= 0.11.1)
33
+ parallel (1.27.0)
34
+ parser (3.3.10.2)
35
+ ast (~> 2.4.1)
36
+ racc
37
+ prism (1.9.0)
38
+ public_suffix (7.0.5)
39
+ racc (1.8.1)
40
+ rainbow (3.1.1)
41
+ rake (13.3.1)
42
+ regexp_parser (2.11.3)
43
+ rspec (3.13.2)
44
+ rspec-core (~> 3.13.0)
45
+ rspec-expectations (~> 3.13.0)
46
+ rspec-mocks (~> 3.13.0)
47
+ rspec-core (3.13.6)
48
+ rspec-support (~> 3.13.0)
49
+ rspec-expectations (3.13.5)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.13.0)
52
+ rspec-mocks (3.13.8)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.13.0)
55
+ rspec-support (3.13.7)
56
+ rspec_junit_formatter (0.6.0)
57
+ rspec-core (>= 2, < 4, != 2.12.0)
58
+ rubocop (1.85.1)
59
+ json (~> 2.3)
60
+ language_server-protocol (~> 3.17.0.2)
61
+ lint_roller (~> 1.1.0)
62
+ mcp (~> 0.6)
63
+ parallel (~> 1.10)
64
+ parser (>= 3.3.0.2)
65
+ rainbow (>= 2.2.2, < 4.0)
66
+ regexp_parser (>= 2.9.3, < 3.0)
67
+ rubocop-ast (>= 1.49.0, < 2.0)
68
+ ruby-progressbar (~> 1.7)
69
+ unicode-display_width (>= 2.4.0, < 4.0)
70
+ rubocop-ast (1.49.1)
71
+ parser (>= 3.3.7.2)
72
+ prism (~> 1.7)
73
+ ruby-progressbar (1.13.0)
74
+ simplecov (0.22.0)
75
+ docile (~> 1.1)
76
+ simplecov-html (~> 0.11)
77
+ simplecov_json_formatter (~> 0.1)
78
+ simplecov-html (0.13.2)
79
+ simplecov_json_formatter (0.1.4)
80
+ unicode-display_width (3.2.0)
81
+ unicode-emoji (~> 4.1)
82
+ unicode-emoji (4.2.0)
83
+ uri (1.1.1)
84
+
85
+ PLATFORMS
86
+ arm64-darwin-25
87
+ ruby
88
+
89
+ DEPENDENCIES
90
+ lex-github!
91
+ rake
92
+ rspec
93
+ rspec_junit_formatter
94
+ rubocop
95
+ simplecov
96
+
97
+ BUNDLED WITH
98
+ 2.6.9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Esity
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # lex-github
2
+
3
+ GitHub integration for [LegionIO](https://github.com/LegionIO/LegionIO). Provides runners for interacting with the GitHub REST API including repositories, issues, pull requests, labels, comments, commits, users, organizations, gists, and search.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install lex-github
9
+ ```
10
+
11
+ ## Standalone Usage
12
+
13
+ ```ruby
14
+ require 'legion/extensions/github'
15
+
16
+ client = Legion::Extensions::Github::Client.new(token: 'ghp_your_token')
17
+
18
+ # Repositories
19
+ client.list_repos(username: 'octocat')
20
+ client.get_repo(owner: 'octocat', repo: 'Hello-World')
21
+ client.create_repo(name: 'my-new-repo', private: true)
22
+
23
+ # Issues
24
+ client.list_issues(owner: 'octocat', repo: 'Hello-World')
25
+ client.create_issue(owner: 'octocat', repo: 'Hello-World', title: 'Bug report')
26
+
27
+ # Pull Requests
28
+ client.list_pull_requests(owner: 'octocat', repo: 'Hello-World')
29
+ client.create_pull_request(owner: 'octocat', repo: 'Hello-World', title: 'Fix', head: 'fix-branch', base: 'main')
30
+ client.merge_pull_request(owner: 'octocat', repo: 'Hello-World', pull_number: 42)
31
+ client.list_pull_request_reviews(owner: 'octocat', repo: 'Hello-World', pull_number: 42)
32
+
33
+ # Labels
34
+ client.list_labels(owner: 'octocat', repo: 'Hello-World')
35
+ client.create_label(owner: 'octocat', repo: 'Hello-World', name: 'bug', color: 'd73a4a')
36
+ client.add_labels_to_issue(owner: 'octocat', repo: 'Hello-World', issue_number: 1, labels: ['bug'])
37
+
38
+ # Comments
39
+ client.list_comments(owner: 'octocat', repo: 'Hello-World', issue_number: 1)
40
+ client.create_comment(owner: 'octocat', repo: 'Hello-World', issue_number: 1, body: 'Looks good!')
41
+ client.update_comment(owner: 'octocat', repo: 'Hello-World', comment_id: 42, body: 'Updated text')
42
+ client.delete_comment(owner: 'octocat', repo: 'Hello-World', comment_id: 42)
43
+
44
+ # Users
45
+ client.get_authenticated_user
46
+ client.get_user(username: 'octocat')
47
+
48
+ # Organizations
49
+ client.get_org(org: 'github')
50
+ client.list_org_repos(org: 'github')
51
+
52
+ # Gists
53
+ client.list_gists
54
+ client.create_gist(files: { 'hello.rb' => { content: 'puts "hello"' } })
55
+
56
+ # Search
57
+ client.search_repositories(query: 'ruby language:ruby')
58
+ client.search_issues(query: 'bug label:bug')
59
+ ```
60
+
61
+ ## Functions
62
+
63
+ ### Repositories
64
+ - `list_repos` - List repositories for a user
65
+ - `get_repo` - Get a single repository
66
+ - `create_repo` - Create a new repository
67
+ - `update_repo` - Update repository settings
68
+ - `delete_repo` - Delete a repository
69
+ - `list_branches` - List branches
70
+ - `list_tags` - List tags
71
+
72
+ ### Issues
73
+ - `list_issues` - List issues for a repository
74
+ - `get_issue` - Get a single issue
75
+ - `create_issue` - Create a new issue
76
+ - `update_issue` - Update an issue
77
+ - `list_issue_comments` - List comments on an issue
78
+ - `create_issue_comment` - Create a comment on an issue
79
+
80
+ ### Pull Requests
81
+ - `list_pull_requests` - List pull requests
82
+ - `get_pull_request` - Get a single pull request
83
+ - `create_pull_request` - Create a pull request
84
+ - `update_pull_request` - Update a pull request
85
+ - `merge_pull_request` - Merge a pull request
86
+ - `list_pull_request_commits` - List commits on a PR
87
+ - `list_pull_request_files` - List files changed in a PR
88
+ - `list_pull_request_reviews` - List reviews on a PR
89
+
90
+ ### Labels
91
+ - `list_labels` - List labels for a repository
92
+ - `get_label` - Get a single label by name
93
+ - `create_label` - Create a new label
94
+ - `update_label` - Update a label
95
+ - `delete_label` - Delete a label
96
+ - `add_labels_to_issue` - Add labels to an issue
97
+ - `remove_label_from_issue` - Remove a label from an issue
98
+
99
+ ### Comments
100
+ - `list_comments` - List comments on an issue or PR
101
+ - `get_comment` - Get a single comment by ID
102
+ - `create_comment` - Create a comment on an issue or PR
103
+ - `update_comment` - Update a comment
104
+ - `delete_comment` - Delete a comment
105
+
106
+ ### Users
107
+ - `get_authenticated_user` - Get the authenticated user
108
+ - `get_user` - Get a user by username
109
+ - `list_followers` - List followers
110
+ - `list_following` - List following
111
+
112
+ ### Organizations
113
+ - `list_user_orgs` - List organizations for a user
114
+ - `get_org` - Get an organization
115
+ - `list_org_repos` - List repos in an organization
116
+ - `list_org_members` - List organization members
117
+
118
+ ### Gists
119
+ - `list_gists` - List gists
120
+ - `get_gist` - Get a single gist
121
+ - `create_gist` - Create a gist
122
+ - `update_gist` - Update a gist
123
+ - `delete_gist` - Delete a gist
124
+
125
+ ### Search
126
+ - `search_repositories` - Search repositories
127
+ - `search_issues` - Search issues and PRs
128
+ - `search_users` - Search users
129
+ - `search_code` - Search code
130
+
131
+ ## Requirements
132
+
133
+ - Ruby >= 3.4
134
+ - [LegionIO](https://github.com/LegionIO/LegionIO) framework (optional for standalone client usage)
135
+ - GitHub personal access token or app token
136
+ - `faraday` >= 2.0
137
+
138
+ ## License
139
+
140
+ MIT
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/github/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-github'
7
+ spec.version = Legion::Extensions::Github::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Github'
12
+ spec.description = 'Connects LegionIO to GitHub'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-github'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-github'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-github'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-github'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-github/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'faraday', '>= 2.0'
30
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+ require 'legion/extensions/github/runners/repositories'
5
+ require 'legion/extensions/github/runners/issues'
6
+ require 'legion/extensions/github/runners/pull_requests'
7
+ require 'legion/extensions/github/runners/users'
8
+ require 'legion/extensions/github/runners/organizations'
9
+ require 'legion/extensions/github/runners/gists'
10
+ require 'legion/extensions/github/runners/search'
11
+ require 'legion/extensions/github/runners/commits'
12
+ require 'legion/extensions/github/runners/labels'
13
+ require 'legion/extensions/github/runners/comments'
14
+
15
+ module Legion
16
+ module Extensions
17
+ module Github
18
+ class Client
19
+ include Helpers::Client
20
+ include Runners::Repositories
21
+ include Runners::Issues
22
+ include Runners::PullRequests
23
+ include Runners::Users
24
+ include Runners::Organizations
25
+ include Runners::Gists
26
+ include Runners::Search
27
+ include Runners::Commits
28
+ include Runners::Labels
29
+ include Runners::Comments
30
+
31
+ attr_reader :opts
32
+
33
+ def initialize(token: nil, api_url: 'https://api.github.com', **extra)
34
+ @opts = { token: token, api_url: api_url, **extra }
35
+ end
36
+
37
+ def connection(**override)
38
+ super(**@opts.merge(override))
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Helpers
9
+ module Client
10
+ def connection(api_url: 'https://api.github.com', token: nil, **_opts)
11
+ Faraday.new(url: api_url) do |conn|
12
+ conn.request :json
13
+ conn.response :json, content_type: /\bjson$/
14
+ conn.headers['Accept'] = 'application/vnd.github+json'
15
+ conn.headers['Authorization'] = "Bearer #{token}" if token
16
+ conn.headers['X-GitHub-Api-Version'] = '2022-11-28'
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Comments
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_comments(owner:, repo:, issue_number:, per_page: 30, page: 1, **)
13
+ params = { per_page: per_page, page: page }
14
+ response = connection(**).get("/repos/#{owner}/#{repo}/issues/#{issue_number}/comments", params)
15
+ { result: response.body }
16
+ end
17
+
18
+ def get_comment(owner:, repo:, comment_id:, **)
19
+ response = connection(**).get("/repos/#{owner}/#{repo}/issues/comments/#{comment_id}")
20
+ { result: response.body }
21
+ end
22
+
23
+ def create_comment(owner:, repo:, issue_number:, body:, **)
24
+ response = connection(**).post("/repos/#{owner}/#{repo}/issues/#{issue_number}/comments", { body: body })
25
+ { result: response.body }
26
+ end
27
+
28
+ def update_comment(owner:, repo:, comment_id:, body:, **)
29
+ response = connection(**).patch("/repos/#{owner}/#{repo}/issues/comments/#{comment_id}", { body: body })
30
+ { result: response.body }
31
+ end
32
+
33
+ def delete_comment(owner:, repo:, comment_id:, **)
34
+ response = connection(**).delete("/repos/#{owner}/#{repo}/issues/comments/#{comment_id}")
35
+ { result: response.status == 204 }
36
+ end
37
+
38
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
39
+ Legion::Extensions::Helpers.const_defined?(:Lex)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Commits
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_commits(owner:, repo:, sha: nil, per_page: 30, page: 1, **)
13
+ params = { per_page: per_page, page: page }
14
+ params[:sha] = sha if sha
15
+ response = connection(**).get("/repos/#{owner}/#{repo}/commits", params)
16
+ { result: response.body }
17
+ end
18
+
19
+ def get_commit(owner:, repo:, ref:, **)
20
+ response = connection(**).get("/repos/#{owner}/#{repo}/commits/#{ref}")
21
+ { result: response.body }
22
+ end
23
+
24
+ def compare_commits(owner:, repo:, base:, head:, per_page: 30, page: 1, **)
25
+ params = { per_page: per_page, page: page }
26
+ response = connection(**).get("/repos/#{owner}/#{repo}/compare/#{base}...#{head}", params)
27
+ { result: response.body }
28
+ end
29
+
30
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
31
+ Legion::Extensions::Helpers.const_defined?(:Lex)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Gists
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_gists(per_page: 30, page: 1, **)
13
+ response = connection(**).get('/gists', per_page: per_page, page: page)
14
+ { result: response.body }
15
+ end
16
+
17
+ def get_gist(gist_id:, **)
18
+ response = connection(**).get("/gists/#{gist_id}")
19
+ { result: response.body }
20
+ end
21
+
22
+ def create_gist(files:, description: nil, public: false, **)
23
+ payload = { files: files, description: description, public: public }
24
+ response = connection(**).post('/gists', payload)
25
+ { result: response.body }
26
+ end
27
+
28
+ def update_gist(gist_id:, files: nil, description: nil, **)
29
+ payload = { files: files, description: description }.compact
30
+ response = connection(**).patch("/gists/#{gist_id}", payload)
31
+ { result: response.body }
32
+ end
33
+
34
+ def delete_gist(gist_id:, **)
35
+ response = connection(**).delete("/gists/#{gist_id}")
36
+ { result: response.status == 204 }
37
+ end
38
+
39
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
40
+ Legion::Extensions::Helpers.const_defined?(:Lex)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Issues
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_issues(owner:, repo:, state: 'open', per_page: 30, page: 1, **)
13
+ params = { state: state, per_page: per_page, page: page }
14
+ response = connection(**).get("/repos/#{owner}/#{repo}/issues", params)
15
+ { result: response.body }
16
+ end
17
+
18
+ def get_issue(owner:, repo:, issue_number:, **)
19
+ response = connection(**).get("/repos/#{owner}/#{repo}/issues/#{issue_number}")
20
+ { result: response.body }
21
+ end
22
+
23
+ def create_issue(owner:, repo:, title:, body: nil, labels: [], assignees: [], **)
24
+ payload = { title: title, body: body, labels: labels, assignees: assignees }
25
+ response = connection(**).post("/repos/#{owner}/#{repo}/issues", payload)
26
+ { result: response.body }
27
+ end
28
+
29
+ def update_issue(owner:, repo:, issue_number:, **opts)
30
+ payload = opts.slice(:title, :body, :state, :labels, :assignees)
31
+ response = connection(**opts).patch("/repos/#{owner}/#{repo}/issues/#{issue_number}", payload)
32
+ { result: response.body }
33
+ end
34
+
35
+ def list_issue_comments(owner:, repo:, issue_number:, per_page: 30, page: 1, **)
36
+ params = { per_page: per_page, page: page }
37
+ response = connection(**).get("/repos/#{owner}/#{repo}/issues/#{issue_number}/comments", params)
38
+ { result: response.body }
39
+ end
40
+
41
+ def create_issue_comment(owner:, repo:, issue_number:, body:, **)
42
+ response = connection(**).post("/repos/#{owner}/#{repo}/issues/#{issue_number}/comments", { body: body })
43
+ { result: response.body }
44
+ end
45
+
46
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
47
+ Legion::Extensions::Helpers.const_defined?(:Lex)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Labels
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_labels(owner:, repo:, per_page: 30, page: 1, **)
13
+ params = { per_page: per_page, page: page }
14
+ response = connection(**).get("/repos/#{owner}/#{repo}/labels", params)
15
+ { result: response.body }
16
+ end
17
+
18
+ def get_label(owner:, repo:, name:, **)
19
+ response = connection(**).get("/repos/#{owner}/#{repo}/labels/#{name}")
20
+ { result: response.body }
21
+ end
22
+
23
+ def create_label(owner:, repo:, name:, color:, description: nil, **)
24
+ payload = { name: name, color: color, description: description }.compact
25
+ response = connection(**).post("/repos/#{owner}/#{repo}/labels", payload)
26
+ { result: response.body }
27
+ end
28
+
29
+ def update_label(owner:, repo:, name:, new_name: nil, color: nil, description: nil, **)
30
+ payload = { new_name: new_name, color: color, description: description }.compact
31
+ response = connection(**).patch("/repos/#{owner}/#{repo}/labels/#{name}", payload)
32
+ { result: response.body }
33
+ end
34
+
35
+ def delete_label(owner:, repo:, name:, **)
36
+ response = connection(**).delete("/repos/#{owner}/#{repo}/labels/#{name}")
37
+ { result: response.status == 204 }
38
+ end
39
+
40
+ def add_labels_to_issue(owner:, repo:, issue_number:, labels:, **)
41
+ response = connection(**).post("/repos/#{owner}/#{repo}/issues/#{issue_number}/labels", { labels: labels })
42
+ { result: response.body }
43
+ end
44
+
45
+ def remove_label_from_issue(owner:, repo:, issue_number:, name:, **)
46
+ response = connection(**).delete("/repos/#{owner}/#{repo}/issues/#{issue_number}/labels/#{name}")
47
+ { result: response.status == 204 }
48
+ end
49
+
50
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
51
+ Legion::Extensions::Helpers.const_defined?(:Lex)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Organizations
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_user_orgs(username:, per_page: 30, page: 1, **)
13
+ response = connection(**).get("/users/#{username}/orgs", per_page: per_page, page: page)
14
+ { result: response.body }
15
+ end
16
+
17
+ def get_org(org:, **)
18
+ response = connection(**).get("/orgs/#{org}")
19
+ { result: response.body }
20
+ end
21
+
22
+ def list_org_repos(org:, type: 'all', per_page: 30, page: 1, **)
23
+ params = { type: type, per_page: per_page, page: page }
24
+ response = connection(**).get("/orgs/#{org}/repos", params)
25
+ { result: response.body }
26
+ end
27
+
28
+ def list_org_members(org:, per_page: 30, page: 1, **)
29
+ response = connection(**).get("/orgs/#{org}/members", per_page: per_page, page: page)
30
+ { result: response.body }
31
+ end
32
+
33
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
34
+ Legion::Extensions::Helpers.const_defined?(:Lex)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module PullRequests
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_pull_requests(owner:, repo:, state: 'open', per_page: 30, page: 1, **)
13
+ params = { state: state, per_page: per_page, page: page }
14
+ response = connection(**).get("/repos/#{owner}/#{repo}/pulls", params)
15
+ { result: response.body }
16
+ end
17
+
18
+ def get_pull_request(owner:, repo:, pull_number:, **)
19
+ response = connection(**).get("/repos/#{owner}/#{repo}/pulls/#{pull_number}")
20
+ { result: response.body }
21
+ end
22
+
23
+ def create_pull_request(owner:, repo:, title:, head:, base:, body: nil, draft: false, **)
24
+ payload = { title: title, head: head, base: base, body: body, draft: draft }
25
+ response = connection(**).post("/repos/#{owner}/#{repo}/pulls", payload)
26
+ { result: response.body }
27
+ end
28
+
29
+ def update_pull_request(owner:, repo:, pull_number:, **opts)
30
+ payload = opts.slice(:title, :body, :state, :base)
31
+ response = connection(**opts).patch("/repos/#{owner}/#{repo}/pulls/#{pull_number}", payload)
32
+ { result: response.body }
33
+ end
34
+
35
+ def merge_pull_request(owner:, repo:, pull_number:, commit_title: nil, merge_method: 'merge', **)
36
+ payload = { commit_title: commit_title, merge_method: merge_method }.compact
37
+ response = connection(**).put("/repos/#{owner}/#{repo}/pulls/#{pull_number}/merge", payload)
38
+ { result: response.body }
39
+ end
40
+
41
+ def list_pull_request_commits(owner:, repo:, pull_number:, per_page: 30, page: 1, **)
42
+ params = { per_page: per_page, page: page }
43
+ response = connection(**).get("/repos/#{owner}/#{repo}/pulls/#{pull_number}/commits", params)
44
+ { result: response.body }
45
+ end
46
+
47
+ def list_pull_request_files(owner:, repo:, pull_number:, per_page: 30, page: 1, **)
48
+ params = { per_page: per_page, page: page }
49
+ response = connection(**).get("/repos/#{owner}/#{repo}/pulls/#{pull_number}/files", params)
50
+ { result: response.body }
51
+ end
52
+
53
+ def list_pull_request_reviews(owner:, repo:, pull_number:, per_page: 30, page: 1, **)
54
+ params = { per_page: per_page, page: page }
55
+ response = connection(**).get("/repos/#{owner}/#{repo}/pulls/#{pull_number}/reviews", params)
56
+ { result: response.body }
57
+ end
58
+
59
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
60
+ Legion::Extensions::Helpers.const_defined?(:Lex)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Repositories
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def list_repos(username:, per_page: 30, page: 1, **)
13
+ response = connection(**).get("/users/#{username}/repos", per_page: per_page, page: page)
14
+ { result: response.body }
15
+ end
16
+
17
+ def get_repo(owner:, repo:, **)
18
+ response = connection(**).get("/repos/#{owner}/#{repo}")
19
+ { result: response.body }
20
+ end
21
+
22
+ def create_repo(name:, description: nil, private: false, **)
23
+ body = { name: name, description: description, private: private }
24
+ response = connection(**).post('/user/repos', body)
25
+ { result: response.body }
26
+ end
27
+
28
+ def update_repo(owner:, repo:, **opts)
29
+ body = opts.slice(:name, :description, :homepage, :private, :default_branch)
30
+ response = connection(**opts).patch("/repos/#{owner}/#{repo}", body)
31
+ { result: response.body }
32
+ end
33
+
34
+ def delete_repo(owner:, repo:, **)
35
+ response = connection(**).delete("/repos/#{owner}/#{repo}")
36
+ { result: response.status == 204 }
37
+ end
38
+
39
+ def list_branches(owner:, repo:, per_page: 30, page: 1, **)
40
+ response = connection(**).get("/repos/#{owner}/#{repo}/branches", per_page: per_page, page: page)
41
+ { result: response.body }
42
+ end
43
+
44
+ def list_tags(owner:, repo:, per_page: 30, page: 1, **)
45
+ response = connection(**).get("/repos/#{owner}/#{repo}/tags", per_page: per_page, page: page)
46
+ { result: response.body }
47
+ end
48
+
49
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
50
+ Legion::Extensions::Helpers.const_defined?(:Lex)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Search
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def search_repositories(query:, sort: nil, order: 'desc', per_page: 30, page: 1, **)
13
+ params = { q: query, sort: sort, order: order, per_page: per_page, page: page }.compact
14
+ response = connection(**).get('/search/repositories', params)
15
+ { result: response.body }
16
+ end
17
+
18
+ def search_issues(query:, sort: nil, order: 'desc', per_page: 30, page: 1, **)
19
+ params = { q: query, sort: sort, order: order, per_page: per_page, page: page }.compact
20
+ response = connection(**).get('/search/issues', params)
21
+ { result: response.body }
22
+ end
23
+
24
+ def search_users(query:, sort: nil, order: 'desc', per_page: 30, page: 1, **)
25
+ params = { q: query, sort: sort, order: order, per_page: per_page, page: page }.compact
26
+ response = connection(**).get('/search/users', params)
27
+ { result: response.body }
28
+ end
29
+
30
+ def search_code(query:, sort: nil, order: 'desc', per_page: 30, page: 1, **)
31
+ params = { q: query, sort: sort, order: order, per_page: per_page, page: page }.compact
32
+ response = connection(**).get('/search/code', params)
33
+ { result: response.body }
34
+ end
35
+
36
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
37
+ Legion::Extensions::Helpers.const_defined?(:Lex)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/helpers/client'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Github
8
+ module Runners
9
+ module Users
10
+ include Legion::Extensions::Github::Helpers::Client
11
+
12
+ def get_authenticated_user(**)
13
+ response = connection(**).get('/user')
14
+ { result: response.body }
15
+ end
16
+
17
+ def get_user(username:, **)
18
+ response = connection(**).get("/users/#{username}")
19
+ { result: response.body }
20
+ end
21
+
22
+ def list_followers(username:, per_page: 30, page: 1, **)
23
+ response = connection(**).get("/users/#{username}/followers", per_page: per_page, page: page)
24
+ { result: response.body }
25
+ end
26
+
27
+ def list_following(username:, per_page: 30, page: 1, **)
28
+ response = connection(**).get("/users/#{username}/following", per_page: per_page, page: page)
29
+ { result: response.body }
30
+ end
31
+
32
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
33
+ Legion::Extensions::Helpers.const_defined?(:Lex)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Github
6
+ VERSION = '0.2.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/github/version'
4
+ require 'legion/extensions/github/helpers/client'
5
+ require 'legion/extensions/github/runners/repositories'
6
+ require 'legion/extensions/github/runners/issues'
7
+ require 'legion/extensions/github/runners/pull_requests'
8
+ require 'legion/extensions/github/runners/users'
9
+ require 'legion/extensions/github/runners/organizations'
10
+ require 'legion/extensions/github/runners/gists'
11
+ require 'legion/extensions/github/runners/search'
12
+ require 'legion/extensions/github/runners/commits'
13
+ require 'legion/extensions/github/runners/labels'
14
+ require 'legion/extensions/github/runners/comments'
15
+ require 'legion/extensions/github/client'
16
+
17
+ module Legion
18
+ module Extensions
19
+ module Github
20
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-github
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ description: Connects LegionIO to GitHub
27
+ email:
28
+ - matthewdiverson@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ".github/workflows/ci.yml"
34
+ - ".gitignore"
35
+ - ".rspec"
36
+ - ".rubocop.yml"
37
+ - CHANGELOG.md
38
+ - CLAUDE.md
39
+ - Dockerfile
40
+ - Gemfile
41
+ - Gemfile.lock
42
+ - LICENSE
43
+ - README.md
44
+ - lex-github.gemspec
45
+ - lib/legion/extensions/github.rb
46
+ - lib/legion/extensions/github/client.rb
47
+ - lib/legion/extensions/github/helpers/client.rb
48
+ - lib/legion/extensions/github/runners/comments.rb
49
+ - lib/legion/extensions/github/runners/commits.rb
50
+ - lib/legion/extensions/github/runners/gists.rb
51
+ - lib/legion/extensions/github/runners/issues.rb
52
+ - lib/legion/extensions/github/runners/labels.rb
53
+ - lib/legion/extensions/github/runners/organizations.rb
54
+ - lib/legion/extensions/github/runners/pull_requests.rb
55
+ - lib/legion/extensions/github/runners/repositories.rb
56
+ - lib/legion/extensions/github/runners/search.rb
57
+ - lib/legion/extensions/github/runners/users.rb
58
+ - lib/legion/extensions/github/version.rb
59
+ homepage: https://github.com/LegionIO/lex-github
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ homepage_uri: https://github.com/LegionIO/lex-github
64
+ source_code_uri: https://github.com/LegionIO/lex-github
65
+ documentation_uri: https://github.com/LegionIO/lex-github
66
+ changelog_uri: https://github.com/LegionIO/lex-github
67
+ bug_tracker_uri: https://github.com/LegionIO/lex-github/issues
68
+ rubygems_mfa_required: 'true'
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '3.4'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.6.9
84
+ specification_version: 4
85
+ summary: LEX Github
86
+ test_files: []