Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Runnable examples are available in the [`examples/`](./examples) directory:

- [`examples/basic_usage.rb`](./examples/basic_usage.rb) - Client setup, connections, integrations, and webhooks
- [`examples/proxy_api.rb`](./examples/proxy_api.rb) - Proxy API GET request with a connection
- [`examples/unify_api.rb`](./examples/unify_api.rb) - Unify Chat, Git, and PM endpoint usage
- [`examples/unify_api.rb`](./examples/unify_api.rb) - Unify Chat, Git, and Ticketing endpoint usage
- [`examples/README.md`](./examples/README.md) - Setup and execution instructions

## Quick Start
Expand Down Expand Up @@ -840,20 +840,20 @@ puts "Releases: #{result['data']}"
}
```

#### Project Management API
#### Ticketing API

The PM API provides a unified interface for project management platforms like Jira, Linear, and Asana.
The Ticketing API provides a unified interface for ticketing and project management platforms like Jira, Linear, and Asana.

##### List Issues
##### List Tickets

```ruby
result = unify.pm.issues(
result = unify.ticketing.tickets(
limit: 100,
after: nil,
include_raw: false
)

puts "Issues: #{result['data']}"
puts "Tickets: #{result['data']}"
```

**Response:**
Expand All @@ -880,8 +880,8 @@ puts "Issues: #{result['data']}"
**Filtering and sorting:**

```ruby
open_issues = result['data'].select { |issue| issue['status'] == 'open' }
sorted_by_date = result['data'].sort_by { |issue| Time.parse(issue['created_at']) }.reverse
open_tickets = result['data'].select { |ticket| ticket['status'] == 'open' }
sorted_by_date = result['data'].sort_by { |ticket| Time.parse(ticket['created_at']) }.reverse
```

## Error Handling
Expand Down Expand Up @@ -937,7 +937,7 @@ lib/
│ ├── base.rb # Base Unify class
│ ├── chat.rb # Chat Unify API
│ ├── git.rb # Git Unify API
│ └── pm.rb # PM Unify API
│ └── ticketing.rb # Ticketing Unify API
spec/ # Test files
```

Expand Down
1 change: 1 addition & 0 deletions bundleup-sdk.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rspec', '~> 3.12'
spec.add_development_dependency 'rubocop', '~> 1.50'
spec.add_development_dependency 'rubocop-capybara', '< 2.23'
spec.add_development_dependency 'rubocop-rake', '~> 0.6'
spec.add_development_dependency 'rubocop-rspec', '~> 2.20', '< 2.26'
spec.add_development_dependency 'vcr', '~> 6.1'
Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ ruby examples/unify_api.rb

- `basic_usage.rb` — initialize the SDK and list connections, integrations, and webhooks
- `proxy_api.rb` — send a GET request through the Proxy API
- `unify_api.rb` — call Unify Chat, Git, and PM endpoints
- `unify_api.rb` — call Unify Chat, Git, and Ticketing endpoints
6 changes: 2 additions & 4 deletions examples/basic_usage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

require 'bundleup'

api_key = ENV['BUNDLEUP_API_KEY']
api_key = ENV.fetch('BUNDLEUP_API_KEY', nil)

if api_key.nil? || api_key.empty?
abort 'BUNDLEUP_API_KEY is required'
end
abort 'BUNDLEUP_API_KEY is required' if api_key.nil? || api_key.empty?

client = BundleUp::Client.new(api_key)

Expand Down
12 changes: 4 additions & 8 deletions examples/proxy_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@

require 'bundleup'

api_key = ENV['BUNDLEUP_API_KEY']
connection_id = ENV['BUNDLEUP_CONNECTION_ID']
api_key = ENV.fetch('BUNDLEUP_API_KEY', nil)
connection_id = ENV.fetch('BUNDLEUP_CONNECTION_ID', nil)
path = ENV.fetch('BUNDLEUP_PROXY_PATH', '/users')

if api_key.nil? || api_key.empty?
abort 'BUNDLEUP_API_KEY is required'
end
abort 'BUNDLEUP_API_KEY is required' if api_key.nil? || api_key.empty?

if connection_id.nil? || connection_id.empty?
abort 'BUNDLEUP_CONNECTION_ID is required for proxy example'
end
abort 'BUNDLEUP_CONNECTION_ID is required for proxy example' if connection_id.nil? || connection_id.empty?

client = BundleUp::Client.new(api_key)
proxy = client.proxy(connection_id)
Expand Down
20 changes: 8 additions & 12 deletions examples/unify_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

require 'bundleup'

api_key = ENV['BUNDLEUP_API_KEY']
connection_id = ENV['BUNDLEUP_CONNECTION_ID']
api_key = ENV.fetch('BUNDLEUP_API_KEY', nil)
connection_id = ENV.fetch('BUNDLEUP_CONNECTION_ID', nil)

if api_key.nil? || api_key.empty?
abort 'BUNDLEUP_API_KEY is required'
end
abort 'BUNDLEUP_API_KEY is required' if api_key.nil? || api_key.empty?

if connection_id.nil? || connection_id.empty?
abort 'BUNDLEUP_CONNECTION_ID is required for unify example'
end
abort 'BUNDLEUP_CONNECTION_ID is required for unify example' if connection_id.nil? || connection_id.empty?

chat = BundleUp::Unify::Chat.new(api_key, connection_id)
git = BundleUp::Unify::Git.new(api_key, connection_id)
pm = BundleUp::Unify::PM.new(api_key, connection_id)
ticketing = BundleUp::Unify::Ticketing.new(api_key, connection_id)

puts 'Unify API example'

Expand All @@ -34,8 +30,8 @@
end

begin
issues = pm.issues(limit: 10)
puts "PM issues: #{issues['data']&.length || 0}"
tickets = ticketing.tickets(limit: 10)
puts "Ticketing tickets: #{tickets['data']&.length || 0}"
rescue StandardError => e
warn "Failed to fetch PM issues: #{e.message}"
warn "Failed to fetch tickets: #{e.message}"
end
2 changes: 1 addition & 1 deletion lib/bundleup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
require_relative 'bundleup/unify/base'
require_relative 'bundleup/unify/chat'
require_relative 'bundleup/unify/git'
require_relative 'bundleup/unify/pm'
require_relative 'bundleup/unify/ticketing'

# Main module for the BundleUp SDK.
module BundleUp
Expand Down
2 changes: 1 addition & 1 deletion lib/bundleup/unify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Client
attr_reader :api_key, :connection_id

def initialize(api_key, connection_id)
@pm = BundleUp::Unify::PM.new(api_key, connection_id)
@ticketing = BundleUp::Unify::Ticketing.new(api_key, connection_id)
@chat = BundleUp::Unify::Chat.new(api_key, connection_id)
@git = BundleUp::Unify::Git.new(api_key, connection_id)
end
Expand Down
19 changes: 0 additions & 19 deletions lib/bundleup/unify/pm.rb

This file was deleted.

19 changes: 19 additions & 0 deletions lib/bundleup/unify/ticketing.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module BundleUp
module Unify
# Client for ticketing Unify endpoints.
class Ticketing < Base
# Fetches tickets from the connected ticketing tool.
def tickets(params = {})
response = connection.get('ticketing/tickets') do |req|

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the documented PM issues route

The current BundleUp Unified API docs still list the project-management operation as GET /v1/pm/issues (docs), with no ticketing/tickets route exposed. With this path, every call through BundleUp::Unify::Ticketing#tickets will request /v1/ticketing/tickets and fail for Jira/Linear connections (typically 404), so the SDK loses the existing issue-listing endpoint.

Useful? React with 👍 / 👎.

req.params = params
end

raise "Failed to fetch ticketing/tickets: #{response.status}" unless response.success?

response.body
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

require 'spec_helper'

RSpec.describe BundleUp::Unify::PM do
RSpec.describe BundleUp::Unify::Ticketing do
let(:api_key) { 'test_api_key' }
let(:connection_id) { 'conn_123' }
let(:instance) { described_class.new(api_key, connection_id) }
let(:base_url) { 'https://unify.bundleup.io/v1' }

describe '#issues' do
it 'makes a GET request to issues endpoint' do
stub = stub_request(:get, "#{base_url}/pm/issues")
describe '#tickets' do
it 'makes a GET request to tickets endpoint' do
stub = stub_request(:get, "#{base_url}/ticketing/tickets")
.with(
headers: {
'Authorization' => "Bearer #{api_key}",
Expand All @@ -20,17 +20,17 @@
)
.to_return(
status: 200,
body: '{"data":[{"id":"issue_1","title":"Bug fix"}]}',
body: '{"data":[{"id":"ticket_1","title":"Bug fix"}]}',
headers: { 'Content-Type' => 'application/json' }
)

result = instance.issues
expect(result).to eq({ 'data' => [{ 'id' => 'issue_1', 'title' => 'Bug fix' }] })
result = instance.tickets
expect(result).to eq({ 'data' => [{ 'id' => 'ticket_1', 'title' => 'Bug fix' }] })
expect(stub).to have_been_requested
end

it 'supports additional query parameters' do
stub = stub_request(:get, "#{base_url}/pm/issues?status=open&assignee=john")
stub = stub_request(:get, "#{base_url}/ticketing/tickets?status=open&assignee=john")
.with(
headers: {
'Authorization' => "Bearer #{api_key}",
Expand All @@ -44,22 +44,22 @@
headers: { 'Content-Type' => 'application/json' }
)

instance.issues(status: 'open', assignee: 'john')
instance.tickets(status: 'open', assignee: 'john')
expect(stub).to have_been_requested
end

it 'raises error on 401' do
stub_request(:get, "#{base_url}/pm/issues")
stub_request(:get, "#{base_url}/ticketing/tickets")
.to_return(status: 401, body: '{"error":"Unauthorized"}')

expect { instance.issues }.to raise_error(Faraday::UnauthorizedError)
expect { instance.tickets }.to raise_error(Faraday::UnauthorizedError)
end

it 'raises error on 429 rate limit' do
stub_request(:get, "#{base_url}/pm/issues")
stub_request(:get, "#{base_url}/ticketing/tickets")
.to_return(status: 429, body: '{"error":"Rate limit exceeded"}')

expect { instance.issues }.to raise_error(Faraday::TooManyRequestsError)
expect { instance.tickets }.to raise_error(Faraday::TooManyRequestsError)
end
end
end
4 changes: 2 additions & 2 deletions spec/bundleup/unify_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
expect(client).to be_a(described_class)
end

it 'initializes pm, chat, and git instances' do
expect(client.instance_variable_get(:@pm)).to be_a(BundleUp::Unify::PM)
it 'initializes ticketing, chat, and git instances' do
expect(client.instance_variable_get(:@ticketing)).to be_a(BundleUp::Unify::Ticketing)
expect(client.instance_variable_get(:@chat)).to be_a(BundleUp::Unify::Chat)
expect(client.instance_variable_get(:@git)).to be_a(BundleUp::Unify::Git)
end
Expand Down