bundleup-sdk 0.1.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 +7 -0
- data/CHANGELOG.md +21 -0
- data/LICENSE +21 -0
- data/README.md +312 -0
- data/lib/bundleup/base.rb +110 -0
- data/lib/bundleup/client.rb +71 -0
- data/lib/bundleup/connection.rb +12 -0
- data/lib/bundleup/errors.rb +15 -0
- data/lib/bundleup/integration.rb +12 -0
- data/lib/bundleup/proxy.rb +115 -0
- data/lib/bundleup/unify/base.rb +74 -0
- data/lib/bundleup/unify/chat.rb +20 -0
- data/lib/bundleup/unify/git.rb +62 -0
- data/lib/bundleup/unify/pm.rb +20 -0
- data/lib/bundleup/version.rb +5 -0
- data/lib/bundleup/webhook.rb +12 -0
- data/lib/bundleup.rb +33 -0
- metadata +161 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 95aacf3ac3efd394ecf74d205e774de2b0d3aeb68b547ca2ff1fce1d17372ad5
|
|
4
|
+
data.tar.gz: 11e31c4b1f8f281fbfcac14c68301a3bac673ab90465cf967f9bdc3250fc3557
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 17a5a80b9b93634f6c8467fb95b6ef63ab447fef316d3d971aeb3f562feb3f9f6d7d2fc661b15a1661c4a85456a9db18018e4eeabf117ede2c226940561fb8fc
|
|
7
|
+
data.tar.gz: f13f062aaf534759784470397a260bfa4159ff70488df01784959c1e08c446a7693c24057369539bf28844ed623dce59a5ea67be108f5c0d5a2747947af2ac81
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-01-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of BundleUp Ruby SDK
|
|
12
|
+
- Support for Connections, Integrations, and Webhooks resources
|
|
13
|
+
- Proxy API for direct integration calls
|
|
14
|
+
- Unify API with Chat, Git, and PM modules
|
|
15
|
+
- Comprehensive error handling with custom exception classes
|
|
16
|
+
- Full HTTP method support (GET, POST, PUT, PATCH, DELETE)
|
|
17
|
+
- Automatic retry logic with exponential backoff
|
|
18
|
+
- JSON request/response handling
|
|
19
|
+
- Complete YARD documentation
|
|
20
|
+
|
|
21
|
+
[0.1.0]: https://github.com/bundleup/bundleup-sdk-ruby/releases/tag/v0.1.0
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BundleUp
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# BundleUp Ruby SDK
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/bundleup)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Official Ruby client library for the [BundleUp](https://bundleup.io) API. Connect to 100+ integrations with a single, unified API.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Add this line to your application's Gemfile:
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
gem 'bundleup'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bundle install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or install it yourself as:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
gem install bundleup
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- Ruby 2.7 or higher
|
|
31
|
+
- Bundler
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
require 'bundleup'
|
|
37
|
+
|
|
38
|
+
# Initialize the client with your API key
|
|
39
|
+
client = Bundleup::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
40
|
+
|
|
41
|
+
# List all connections
|
|
42
|
+
connections = client.connections.list
|
|
43
|
+
puts connections
|
|
44
|
+
|
|
45
|
+
# Create a new connection
|
|
46
|
+
new_connection = client.connections.create({
|
|
47
|
+
name: 'My Connection',
|
|
48
|
+
integration_id: 'integration_123'
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Authentication
|
|
53
|
+
|
|
54
|
+
The BundleUp SDK uses API keys for authentication. You can obtain your API key from the [BundleUp Dashboard](https://app.bundleup.io).
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
# Initialize with API key
|
|
58
|
+
client = Bundleup::Client.new('your_api_key_here')
|
|
59
|
+
|
|
60
|
+
# Or use environment variable (recommended)
|
|
61
|
+
client = Bundleup::Client.new(ENV['BUNDLEUP_API_KEY'])
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Security Best Practice:** Never commit your API keys to version control. Use environment variables or a secure credential management system.
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### Connections
|
|
69
|
+
|
|
70
|
+
Manage your integration connections:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
# List all connections
|
|
74
|
+
connections = client.connections.list
|
|
75
|
+
|
|
76
|
+
# List with pagination
|
|
77
|
+
connections = client.connections.list(limit: 10, page: 1)
|
|
78
|
+
|
|
79
|
+
# Retrieve a specific connection
|
|
80
|
+
connection = client.connections.retrieve('conn_123')
|
|
81
|
+
|
|
82
|
+
# Create a new connection
|
|
83
|
+
connection = client.connections.create({
|
|
84
|
+
name: 'GitHub Connection',
|
|
85
|
+
integration_id: 'int_github'
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
# Update a connection
|
|
89
|
+
updated = client.connections.update('conn_123', {
|
|
90
|
+
name: 'Updated GitHub Connection'
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
# Delete a connection
|
|
94
|
+
client.connections.delete('conn_123')
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Integrations
|
|
98
|
+
|
|
99
|
+
Work with available integrations:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
# List all integrations
|
|
103
|
+
integrations = client.integrations.list
|
|
104
|
+
|
|
105
|
+
# Retrieve a specific integration
|
|
106
|
+
integration = client.integrations.retrieve('int_123')
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Webhooks
|
|
110
|
+
|
|
111
|
+
Manage webhook subscriptions:
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
# List all webhooks
|
|
115
|
+
webhooks = client.webhooks.list
|
|
116
|
+
|
|
117
|
+
# Create a webhook
|
|
118
|
+
webhook = client.webhooks.create({
|
|
119
|
+
url: 'https://example.com/webhook',
|
|
120
|
+
events: ['connection.created', 'connection.deleted']
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
# Retrieve a webhook
|
|
124
|
+
webhook = client.webhooks.retrieve('webhook_123')
|
|
125
|
+
|
|
126
|
+
# Update a webhook
|
|
127
|
+
updated = client.webhooks.update('webhook_123', {
|
|
128
|
+
url: 'https://example.com/new-webhook'
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
# Delete a webhook
|
|
132
|
+
client.webhooks.delete('webhook_123')
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Proxy API
|
|
136
|
+
|
|
137
|
+
Make direct calls to the underlying integration APIs:
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
# Initialize proxy for a connection
|
|
141
|
+
proxy = client.proxy('conn_123')
|
|
142
|
+
|
|
143
|
+
# Make GET request
|
|
144
|
+
users = proxy.get('/api/users')
|
|
145
|
+
|
|
146
|
+
# Make POST request
|
|
147
|
+
new_user = proxy.post('/api/users', {
|
|
148
|
+
name: 'John Doe',
|
|
149
|
+
email: 'john@example.com'
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
# Make PUT request
|
|
153
|
+
updated_user = proxy.put('/api/users/123', {
|
|
154
|
+
name: 'Jane Doe'
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
# Make PATCH request
|
|
158
|
+
patched_user = proxy.patch('/api/users/123', {
|
|
159
|
+
email: 'jane@example.com'
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
# Make DELETE request
|
|
163
|
+
proxy.delete('/api/users/123')
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Unify API
|
|
167
|
+
|
|
168
|
+
Access unified, normalized data across different integrations:
|
|
169
|
+
|
|
170
|
+
#### Chat (Slack, Discord, Microsoft Teams, etc.)
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
# Get unified API instances for a connection
|
|
174
|
+
unify = client.unify('conn_123')
|
|
175
|
+
|
|
176
|
+
# List channels
|
|
177
|
+
channels = unify[:chat].channels(limit: 100)
|
|
178
|
+
|
|
179
|
+
# List channels with pagination
|
|
180
|
+
channels = unify[:chat].channels(limit: 50, cursor: 'next_page_token')
|
|
181
|
+
|
|
182
|
+
# Include raw response from the integration
|
|
183
|
+
channels = unify[:chat].channels(limit: 100, include_raw: true)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Git (GitHub, GitLab, Bitbucket, etc.)
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
unify = client.unify('conn_123')
|
|
190
|
+
|
|
191
|
+
# List repositories
|
|
192
|
+
repos = unify[:git].repos(limit: 50)
|
|
193
|
+
|
|
194
|
+
# List pull requests for a repository
|
|
195
|
+
pulls = unify[:git].pulls('owner/repo', limit: 20)
|
|
196
|
+
|
|
197
|
+
# List tags for a repository
|
|
198
|
+
tags = unify[:git].tags('owner/repo')
|
|
199
|
+
|
|
200
|
+
# List releases for a repository
|
|
201
|
+
releases = unify[:git].releases('owner/repo', limit: 10)
|
|
202
|
+
|
|
203
|
+
# Include raw response
|
|
204
|
+
repos = unify[:git].repos(include_raw: true)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Project Management (Jira, Linear, Asana, etc.)
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
unify = client.unify('conn_123')
|
|
211
|
+
|
|
212
|
+
# List issues
|
|
213
|
+
issues = unify[:pm].issues(limit: 100)
|
|
214
|
+
|
|
215
|
+
# List with pagination
|
|
216
|
+
issues = unify[:pm].issues(limit: 50, cursor: 'next_page_token')
|
|
217
|
+
|
|
218
|
+
# Include raw response
|
|
219
|
+
issues = unify[:pm].issues(include_raw: true)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Error Handling
|
|
223
|
+
|
|
224
|
+
The SDK provides custom exception classes for different error scenarios:
|
|
225
|
+
|
|
226
|
+
```ruby
|
|
227
|
+
begin
|
|
228
|
+
client = Bundleup::Client.new('invalid_key')
|
|
229
|
+
connections = client.connections.list
|
|
230
|
+
rescue Bundleup::AuthenticationError => e
|
|
231
|
+
puts "Authentication failed: #{e.message}"
|
|
232
|
+
rescue Bundleup::InvalidRequestError => e
|
|
233
|
+
puts "Invalid request: #{e.message}"
|
|
234
|
+
rescue Bundleup::APIError => e
|
|
235
|
+
puts "API error: #{e.message}"
|
|
236
|
+
rescue Bundleup::Error => e
|
|
237
|
+
puts "General error: #{e.message}"
|
|
238
|
+
end
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Exception Classes
|
|
242
|
+
|
|
243
|
+
- `Bundleup::Error` - Base class for all BundleUp errors
|
|
244
|
+
- `Bundleup::APIError` - Raised when an API error occurs
|
|
245
|
+
- `Bundleup::AuthenticationError` - Raised when authentication fails
|
|
246
|
+
- `Bundleup::InvalidRequestError` - Raised when a request is invalid
|
|
247
|
+
|
|
248
|
+
## Advanced Usage
|
|
249
|
+
|
|
250
|
+
### Custom Connection Configuration
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
# The SDK uses Faraday under the hood with automatic retries
|
|
254
|
+
# Retry logic is configured with:
|
|
255
|
+
# - Max retries: 3
|
|
256
|
+
# - Initial interval: 0.5 seconds
|
|
257
|
+
# - Backoff factor: 2
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Pagination
|
|
261
|
+
|
|
262
|
+
Most list endpoints support pagination:
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
# Using limit and page
|
|
266
|
+
connections = client.connections.list(limit: 10, page: 1)
|
|
267
|
+
|
|
268
|
+
# Using cursor-based pagination (for Unify API)
|
|
269
|
+
channels = unify[:chat].channels(limit: 50, cursor: 'next_page_token')
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Development
|
|
273
|
+
|
|
274
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
|
|
275
|
+
|
|
276
|
+
To install this gem onto your local machine, run:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
bundle exec rake install
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
To release a new version, update the version number in `lib/bundleup/version.rb`, and then run:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
bundle exec rake release
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Testing
|
|
289
|
+
|
|
290
|
+
Run the test suite:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
bundle exec rspec
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Contributing
|
|
297
|
+
|
|
298
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/bundleup/bundleup-sdk-ruby.
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
303
|
+
|
|
304
|
+
## Support
|
|
305
|
+
|
|
306
|
+
- Documentation: [https://docs.bundleup.io](https://docs.bundleup.io)
|
|
307
|
+
- Email: [support@bundleup.io](mailto:support@bundleup.io)
|
|
308
|
+
- GitHub Issues: [https://github.com/bundleup/bundleup-sdk-ruby/issues](https://github.com/bundleup/bundleup-sdk-ruby/issues)
|
|
309
|
+
|
|
310
|
+
## Code of Conduct
|
|
311
|
+
|
|
312
|
+
Everyone interacting in the BundleUp project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/bundleup/bundleup-sdk-ruby/blob/main/CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
# Base class for all BundleUp resources
|
|
5
|
+
class Base
|
|
6
|
+
BASE_URL = 'https://api.bundleup.io'
|
|
7
|
+
API_VERSION = 'v1'
|
|
8
|
+
|
|
9
|
+
attr_reader :api_key
|
|
10
|
+
|
|
11
|
+
def initialize(api_key)
|
|
12
|
+
@api_key = api_key
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# List all resources
|
|
16
|
+
#
|
|
17
|
+
# @param params [Hash] Query parameters
|
|
18
|
+
# @return [Hash] Response with data and pagination info
|
|
19
|
+
def list(params = {})
|
|
20
|
+
request(:get, resource_path, params)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Create a new resource
|
|
24
|
+
#
|
|
25
|
+
# @param data [Hash] Resource data
|
|
26
|
+
# @return [Hash] Created resource
|
|
27
|
+
def create(data)
|
|
28
|
+
request(:post, resource_path, data)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Retrieve a specific resource
|
|
32
|
+
#
|
|
33
|
+
# @param id [String] Resource ID
|
|
34
|
+
# @return [Hash] Resource data
|
|
35
|
+
def retrieve(id)
|
|
36
|
+
request(:get, "#{resource_path}/#{id}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Update a resource
|
|
40
|
+
#
|
|
41
|
+
# @param id [String] Resource ID
|
|
42
|
+
# @param data [Hash] Updated resource data
|
|
43
|
+
# @return [Hash] Updated resource
|
|
44
|
+
def update(id, data)
|
|
45
|
+
request(:patch, "#{resource_path}/#{id}", data)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Delete a resource
|
|
49
|
+
#
|
|
50
|
+
# @param id [String] Resource ID
|
|
51
|
+
# @return [Hash] Deletion response
|
|
52
|
+
def delete(id)
|
|
53
|
+
request(:delete, "#{resource_path}/#{id}")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def resource_path
|
|
59
|
+
"/#{API_VERSION}/#{resource_name}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def resource_name
|
|
63
|
+
raise NotImplementedError, 'Subclasses must implement resource_name'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def request(method, path, body = nil)
|
|
67
|
+
response = connection.public_send(method) do |req|
|
|
68
|
+
req.url path
|
|
69
|
+
req.headers['Content-Type'] = 'application/json'
|
|
70
|
+
req.headers['Authorization'] = "Bearer #{api_key}"
|
|
71
|
+
req.body = body.to_json if body && %i[post patch put].include?(method)
|
|
72
|
+
req.params.update(body) if body && method == :get
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
handle_response(response)
|
|
76
|
+
rescue Faraday::Error => e
|
|
77
|
+
raise APIError, "Request failed: #{e.message}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def connection
|
|
81
|
+
@connection ||= Faraday.new(url: BASE_URL) do |conn|
|
|
82
|
+
conn.request :retry, max: 3, interval: 0.5, backoff_factor: 2
|
|
83
|
+
conn.adapter Faraday.default_adapter
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def handle_response(response)
|
|
88
|
+
case response.status
|
|
89
|
+
when 200..299
|
|
90
|
+
response.body.empty? ? {} : JSON.parse(response.body)
|
|
91
|
+
when 401
|
|
92
|
+
raise AuthenticationError, 'Invalid API key'
|
|
93
|
+
when 400..499
|
|
94
|
+
error_message = extract_error_message(response)
|
|
95
|
+
raise InvalidRequestError, error_message
|
|
96
|
+
when 500..599
|
|
97
|
+
raise APIError, 'Server error occurred'
|
|
98
|
+
else
|
|
99
|
+
raise APIError, "Unexpected response status: #{response.status}"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def extract_error_message(response)
|
|
104
|
+
body = JSON.parse(response.body)
|
|
105
|
+
body['error'] || body['message'] || "Request failed with status #{response.status}"
|
|
106
|
+
rescue JSON::ParserError
|
|
107
|
+
"Request failed with status #{response.status}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
# Main client class for interacting with the BundleUp API
|
|
5
|
+
class Client
|
|
6
|
+
attr_reader :api_key
|
|
7
|
+
|
|
8
|
+
# Initialize a new BundleUp client
|
|
9
|
+
#
|
|
10
|
+
# @param api_key [String] Your BundleUp API key
|
|
11
|
+
# @raise [ArgumentError] if api_key is nil or empty
|
|
12
|
+
def initialize(api_key)
|
|
13
|
+
raise ArgumentError, 'API key is required to initialize BundleUp SDK.' if api_key.nil? || api_key.to_s.empty?
|
|
14
|
+
|
|
15
|
+
@api_key = api_key
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Access the Connections resource
|
|
19
|
+
#
|
|
20
|
+
# @return [Bundleup::Connection] Connection resource instance
|
|
21
|
+
def connections
|
|
22
|
+
@connections ||= Bundleup::Connection.new(@api_key)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Access the Integrations resource
|
|
26
|
+
#
|
|
27
|
+
# @return [Bundleup::Integration] Integration resource instance
|
|
28
|
+
def integrations
|
|
29
|
+
@integrations ||= Bundleup::Integration.new(@api_key)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Access the Webhooks resource
|
|
33
|
+
#
|
|
34
|
+
# @return [Bundleup::Webhook] Webhook resource instance
|
|
35
|
+
def webhooks
|
|
36
|
+
@webhooks ||= Bundleup::Webhook.new(@api_key)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Create a Proxy instance for a specific connection
|
|
40
|
+
#
|
|
41
|
+
# @param connection_id [String] The connection ID
|
|
42
|
+
# @return [Bundleup::Proxy] Proxy instance
|
|
43
|
+
# @raise [ArgumentError] if connection_id is nil or empty
|
|
44
|
+
def proxy(connection_id)
|
|
45
|
+
if connection_id.nil? || connection_id.to_s.empty?
|
|
46
|
+
raise ArgumentError,
|
|
47
|
+
'Connection ID is required to create a Proxy instance.'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Bundleup::Proxy.new(@api_key, connection_id)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Create Unify instances for a specific connection
|
|
54
|
+
#
|
|
55
|
+
# @param connection_id [String] The connection ID
|
|
56
|
+
# @return [Hash] Hash with :chat, :git, and :pm Unify instances
|
|
57
|
+
# @raise [ArgumentError] if connection_id is nil or empty
|
|
58
|
+
def unify(connection_id)
|
|
59
|
+
if connection_id.nil? || connection_id.to_s.empty?
|
|
60
|
+
raise ArgumentError,
|
|
61
|
+
'Connection ID is required to create a Unify instance.'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
chat: Bundleup::Unify::Chat.new(@api_key, connection_id),
|
|
66
|
+
git: Bundleup::Unify::Git.new(@api_key, connection_id),
|
|
67
|
+
pm: Bundleup::Unify::PM.new(@api_key, connection_id)
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
# Base error class for all BundleUp errors
|
|
5
|
+
class Error < StandardError; end
|
|
6
|
+
|
|
7
|
+
# Raised when an API error occurs
|
|
8
|
+
class APIError < Error; end
|
|
9
|
+
|
|
10
|
+
# Raised when authentication fails
|
|
11
|
+
class AuthenticationError < Error; end
|
|
12
|
+
|
|
13
|
+
# Raised when a request is invalid
|
|
14
|
+
class InvalidRequestError < Error; end
|
|
15
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
# Proxy class for making direct calls to integration APIs
|
|
5
|
+
class Proxy
|
|
6
|
+
BASE_URL = 'https://proxy.bundleup.io'
|
|
7
|
+
|
|
8
|
+
attr_reader :api_key, :connection_id
|
|
9
|
+
|
|
10
|
+
# Initialize a new Proxy instance
|
|
11
|
+
#
|
|
12
|
+
# @param api_key [String] Your BundleUp API key
|
|
13
|
+
# @param connection_id [String] The connection ID
|
|
14
|
+
def initialize(api_key, connection_id)
|
|
15
|
+
@api_key = api_key
|
|
16
|
+
@connection_id = connection_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Make a GET request
|
|
20
|
+
#
|
|
21
|
+
# @param path [String] The request path
|
|
22
|
+
# @param params [Hash] Query parameters
|
|
23
|
+
# @return [Hash] Response data
|
|
24
|
+
def get(path, params = {})
|
|
25
|
+
request(:get, path, params)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Make a POST request
|
|
29
|
+
#
|
|
30
|
+
# @param path [String] The request path
|
|
31
|
+
# @param body [Hash] Request body
|
|
32
|
+
# @return [Hash] Response data
|
|
33
|
+
def post(path, body = {})
|
|
34
|
+
request(:post, path, body)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Make a PUT request
|
|
38
|
+
#
|
|
39
|
+
# @param path [String] The request path
|
|
40
|
+
# @param body [Hash] Request body
|
|
41
|
+
# @return [Hash] Response data
|
|
42
|
+
def put(path, body = {})
|
|
43
|
+
request(:put, path, body)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Make a PATCH request
|
|
47
|
+
#
|
|
48
|
+
# @param path [String] The request path
|
|
49
|
+
# @param body [Hash] Request body
|
|
50
|
+
# @return [Hash] Response data
|
|
51
|
+
def patch(path, body = {})
|
|
52
|
+
request(:patch, path, body)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Make a DELETE request
|
|
56
|
+
#
|
|
57
|
+
# @param path [String] The request path
|
|
58
|
+
# @param params [Hash] Query parameters
|
|
59
|
+
# @return [Hash] Response data
|
|
60
|
+
def delete(path, params = {})
|
|
61
|
+
request(:delete, path, params)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def request(method, path, body = nil)
|
|
67
|
+
response = connection.public_send(method) do |req|
|
|
68
|
+
req.url path
|
|
69
|
+
req.headers['Content-Type'] = 'application/json'
|
|
70
|
+
req.headers['Authorization'] = "Bearer #{api_key}"
|
|
71
|
+
req.headers['BU-Connection-Id'] = connection_id
|
|
72
|
+
|
|
73
|
+
if body && %i[post patch put].include?(method)
|
|
74
|
+
req.body = body.to_json
|
|
75
|
+
elsif body && method == :get
|
|
76
|
+
req.params.update(body)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
handle_response(response)
|
|
81
|
+
rescue Faraday::Error => e
|
|
82
|
+
raise APIError, "Proxy request failed: #{e.message}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def connection
|
|
86
|
+
@connection ||= Faraday.new(url: BASE_URL) do |conn|
|
|
87
|
+
conn.request :retry, max: 3, interval: 0.5, backoff_factor: 2
|
|
88
|
+
conn.adapter Faraday.default_adapter
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def handle_response(response)
|
|
93
|
+
case response.status
|
|
94
|
+
when 200..299
|
|
95
|
+
response.body.empty? ? {} : JSON.parse(response.body)
|
|
96
|
+
when 401
|
|
97
|
+
raise AuthenticationError, 'Invalid API key'
|
|
98
|
+
when 400..499
|
|
99
|
+
error_message = extract_error_message(response)
|
|
100
|
+
raise InvalidRequestError, error_message
|
|
101
|
+
when 500..599
|
|
102
|
+
raise APIError, 'Server error occurred'
|
|
103
|
+
else
|
|
104
|
+
raise APIError, "Unexpected response status: #{response.status}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def extract_error_message(response)
|
|
109
|
+
body = JSON.parse(response.body)
|
|
110
|
+
body['error'] || body['message'] || "Request failed with status #{response.status}"
|
|
111
|
+
rescue JSON::ParserError
|
|
112
|
+
"Request failed with status #{response.status}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
module Unify
|
|
5
|
+
# Base class for all Unify resources
|
|
6
|
+
class Base
|
|
7
|
+
BASE_URL = 'https://unify.bundleup.io'
|
|
8
|
+
API_VERSION = 'v1'
|
|
9
|
+
|
|
10
|
+
attr_reader :api_key, :connection_id
|
|
11
|
+
|
|
12
|
+
# Initialize a new Unify resource
|
|
13
|
+
#
|
|
14
|
+
# @param api_key [String] Your BundleUp API key
|
|
15
|
+
# @param connection_id [String] The connection ID
|
|
16
|
+
def initialize(api_key, connection_id)
|
|
17
|
+
@api_key = api_key
|
|
18
|
+
@connection_id = connection_id
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def request(method, path, params = {}, include_raw: false)
|
|
24
|
+
response = connection.public_send(method) do |req|
|
|
25
|
+
req.url path
|
|
26
|
+
req.headers['Content-Type'] = 'application/json'
|
|
27
|
+
req.headers['Authorization'] = "Bearer #{api_key}"
|
|
28
|
+
req.headers['BU-Connection-Id'] = connection_id
|
|
29
|
+
req.headers['BU-Include-Raw'] = include_raw.to_s
|
|
30
|
+
|
|
31
|
+
if params && %i[post patch put].include?(method)
|
|
32
|
+
req.body = params.to_json
|
|
33
|
+
elsif params && method == :get
|
|
34
|
+
req.params.update(params)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
handle_response(response)
|
|
39
|
+
rescue Faraday::Error => e
|
|
40
|
+
raise APIError, "Unify request failed: #{e.message}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def connection
|
|
44
|
+
@connection ||= Faraday.new(url: BASE_URL) do |conn|
|
|
45
|
+
conn.request :retry, max: 3, interval: 0.5, backoff_factor: 2
|
|
46
|
+
conn.adapter Faraday.default_adapter
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def handle_response(response)
|
|
51
|
+
case response.status
|
|
52
|
+
when 200..299
|
|
53
|
+
response.body.empty? ? {} : JSON.parse(response.body)
|
|
54
|
+
when 401
|
|
55
|
+
raise AuthenticationError, 'Invalid API key'
|
|
56
|
+
when 400..499
|
|
57
|
+
error_message = extract_error_message(response)
|
|
58
|
+
raise InvalidRequestError, error_message
|
|
59
|
+
when 500..599
|
|
60
|
+
raise APIError, 'Server error occurred'
|
|
61
|
+
else
|
|
62
|
+
raise APIError, "Unexpected response status: #{response.status}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def extract_error_message(response)
|
|
67
|
+
body = JSON.parse(response.body)
|
|
68
|
+
body['error'] || body['message'] || "Request failed with status #{response.status}"
|
|
69
|
+
rescue JSON::ParserError
|
|
70
|
+
"Request failed with status #{response.status}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
module Unify
|
|
5
|
+
# Chat resource for unified chat operations
|
|
6
|
+
class Chat < Base
|
|
7
|
+
# List channels
|
|
8
|
+
#
|
|
9
|
+
# @param params [Hash] Query parameters
|
|
10
|
+
# @option params [Integer] :limit Number of results to return
|
|
11
|
+
# @option params [String] :cursor Pagination cursor
|
|
12
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
13
|
+
# @return [Hash] Channels data with pagination info
|
|
14
|
+
def channels(params = {})
|
|
15
|
+
include_raw = params.delete(:include_raw) || false
|
|
16
|
+
request(:get, "/#{API_VERSION}/chat/channels", params, include_raw: include_raw)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
module Unify
|
|
5
|
+
# Git resource for unified git operations
|
|
6
|
+
class Git < Base
|
|
7
|
+
# List repositories
|
|
8
|
+
#
|
|
9
|
+
# @param params [Hash] Query parameters
|
|
10
|
+
# @option params [Integer] :limit Number of results to return
|
|
11
|
+
# @option params [String] :cursor Pagination cursor
|
|
12
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
13
|
+
# @return [Hash] Repositories data with pagination info
|
|
14
|
+
def repos(params = {})
|
|
15
|
+
include_raw = params.delete(:include_raw) || false
|
|
16
|
+
request(:get, "/#{API_VERSION}/git/repos", params, include_raw: include_raw)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# List pull requests
|
|
20
|
+
#
|
|
21
|
+
# @param repo_name [String] Repository name
|
|
22
|
+
# @param params [Hash] Query parameters
|
|
23
|
+
# @option params [Integer] :limit Number of results to return
|
|
24
|
+
# @option params [String] :cursor Pagination cursor
|
|
25
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
26
|
+
# @return [Hash] Pull requests data with pagination info
|
|
27
|
+
def pulls(repo_name, params = {})
|
|
28
|
+
include_raw = params.delete(:include_raw) || false
|
|
29
|
+
params[:repo_name] = repo_name
|
|
30
|
+
request(:get, "/#{API_VERSION}/git/pulls", params, include_raw: include_raw)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# List tags
|
|
34
|
+
#
|
|
35
|
+
# @param repo_name [String] Repository name
|
|
36
|
+
# @param params [Hash] Query parameters
|
|
37
|
+
# @option params [Integer] :limit Number of results to return
|
|
38
|
+
# @option params [String] :cursor Pagination cursor
|
|
39
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
40
|
+
# @return [Hash] Tags data with pagination info
|
|
41
|
+
def tags(repo_name, params = {})
|
|
42
|
+
include_raw = params.delete(:include_raw) || false
|
|
43
|
+
params[:repo_name] = repo_name
|
|
44
|
+
request(:get, "/#{API_VERSION}/git/tags", params, include_raw: include_raw)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# List releases
|
|
48
|
+
#
|
|
49
|
+
# @param repo_name [String] Repository name
|
|
50
|
+
# @param params [Hash] Query parameters
|
|
51
|
+
# @option params [Integer] :limit Number of results to return
|
|
52
|
+
# @option params [String] :cursor Pagination cursor
|
|
53
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
54
|
+
# @return [Hash] Releases data with pagination info
|
|
55
|
+
def releases(repo_name, params = {})
|
|
56
|
+
include_raw = params.delete(:include_raw) || false
|
|
57
|
+
params[:repo_name] = repo_name
|
|
58
|
+
request(:get, "/#{API_VERSION}/git/releases", params, include_raw: include_raw)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundleup
|
|
4
|
+
module Unify
|
|
5
|
+
# PM (Project Management) resource for unified project management operations
|
|
6
|
+
class PM < Base
|
|
7
|
+
# List issues
|
|
8
|
+
#
|
|
9
|
+
# @param params [Hash] Query parameters
|
|
10
|
+
# @option params [Integer] :limit Number of results to return
|
|
11
|
+
# @option params [String] :cursor Pagination cursor
|
|
12
|
+
# @option params [Boolean] :include_raw Include raw response from the integration
|
|
13
|
+
# @return [Hash] Issues data with pagination info
|
|
14
|
+
def issues(params = {})
|
|
15
|
+
include_raw = params.delete(:include_raw) || false
|
|
16
|
+
request(:get, "/#{API_VERSION}/pm/issues", params, include_raw: include_raw)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/bundleup.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday/retry'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
require_relative 'bundleup/version'
|
|
8
|
+
require_relative 'bundleup/errors'
|
|
9
|
+
require_relative 'bundleup/base'
|
|
10
|
+
require_relative 'bundleup/client'
|
|
11
|
+
require_relative 'bundleup/connection'
|
|
12
|
+
require_relative 'bundleup/integration'
|
|
13
|
+
require_relative 'bundleup/webhook'
|
|
14
|
+
require_relative 'bundleup/proxy'
|
|
15
|
+
require_relative 'bundleup/unify/base'
|
|
16
|
+
require_relative 'bundleup/unify/chat'
|
|
17
|
+
require_relative 'bundleup/unify/git'
|
|
18
|
+
require_relative 'bundleup/unify/pm'
|
|
19
|
+
|
|
20
|
+
# BundleUp Ruby SDK
|
|
21
|
+
#
|
|
22
|
+
# Official Ruby client library for the BundleUp API
|
|
23
|
+
module Bundleup
|
|
24
|
+
class << self
|
|
25
|
+
# Create a new BundleUp client
|
|
26
|
+
#
|
|
27
|
+
# @param api_key [String] Your BundleUp API key
|
|
28
|
+
# @return [Bundleup::Client] A new client instance
|
|
29
|
+
def new(api_key)
|
|
30
|
+
Client.new(api_key)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bundleup-sdk
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- BundleUp
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday-retry
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.12'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.12'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rubocop
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.50'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.50'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: vcr
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '6.1'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '6.1'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: webmock
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '3.18'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '3.18'
|
|
111
|
+
description: Ruby client library for the BundleUp API
|
|
112
|
+
email:
|
|
113
|
+
- support@bundleup.io
|
|
114
|
+
executables: []
|
|
115
|
+
extensions: []
|
|
116
|
+
extra_rdoc_files: []
|
|
117
|
+
files:
|
|
118
|
+
- CHANGELOG.md
|
|
119
|
+
- LICENSE
|
|
120
|
+
- README.md
|
|
121
|
+
- lib/bundleup.rb
|
|
122
|
+
- lib/bundleup/base.rb
|
|
123
|
+
- lib/bundleup/client.rb
|
|
124
|
+
- lib/bundleup/connection.rb
|
|
125
|
+
- lib/bundleup/errors.rb
|
|
126
|
+
- lib/bundleup/integration.rb
|
|
127
|
+
- lib/bundleup/proxy.rb
|
|
128
|
+
- lib/bundleup/unify/base.rb
|
|
129
|
+
- lib/bundleup/unify/chat.rb
|
|
130
|
+
- lib/bundleup/unify/git.rb
|
|
131
|
+
- lib/bundleup/unify/pm.rb
|
|
132
|
+
- lib/bundleup/version.rb
|
|
133
|
+
- lib/bundleup/webhook.rb
|
|
134
|
+
homepage: https://github.com/bundleup/bundleup-sdk-ruby
|
|
135
|
+
licenses:
|
|
136
|
+
- MIT
|
|
137
|
+
metadata:
|
|
138
|
+
homepage_uri: https://github.com/bundleup/bundleup-sdk-ruby
|
|
139
|
+
source_code_uri: https://github.com/bundleup/bundleup-sdk-ruby
|
|
140
|
+
changelog_uri: https://github.com/bundleup/bundleup-sdk-ruby/blob/main/CHANGELOG.md
|
|
141
|
+
rubygems_mfa_required: 'true'
|
|
142
|
+
post_install_message:
|
|
143
|
+
rdoc_options: []
|
|
144
|
+
require_paths:
|
|
145
|
+
- lib
|
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - ">="
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: 2.7.0
|
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - ">="
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: '0'
|
|
156
|
+
requirements: []
|
|
157
|
+
rubygems_version: 3.5.22
|
|
158
|
+
signing_key:
|
|
159
|
+
specification_version: 4
|
|
160
|
+
summary: Official Ruby SDK for BundleUp
|
|
161
|
+
test_files: []
|