jira-ruby 1.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +5 -3
- data/Gemfile +7 -1
- data/Guardfile +1 -1
- data/README.md +452 -0
- data/Rakefile +6 -7
- data/example.rb +23 -1
- data/http-basic-example.rb +13 -12
- data/jira-ruby.gemspec +13 -13
- data/lib/jira/base.rb +53 -52
- data/lib/jira/base_factory.rb +3 -6
- data/lib/jira/client.rb +127 -30
- data/lib/jira/has_many_proxy.rb +0 -1
- data/lib/jira/http_client.rb +54 -16
- data/lib/jira/http_error.rb +3 -5
- data/lib/jira/jwt_client.rb +67 -0
- data/lib/jira/oauth_client.rb +47 -17
- data/lib/jira/request_client.rb +16 -5
- data/lib/jira/resource/agile.rb +34 -9
- data/lib/jira/resource/applinks.rb +5 -8
- data/lib/jira/resource/attachment.rb +41 -3
- data/lib/jira/resource/board.rb +91 -0
- data/lib/jira/resource/board_configuration.rb +9 -0
- data/lib/jira/resource/comment.rb +0 -2
- data/lib/jira/resource/component.rb +1 -3
- data/lib/jira/resource/createmeta.rb +12 -14
- data/lib/jira/resource/field.rb +22 -22
- data/lib/jira/resource/filter.rb +2 -2
- data/lib/jira/resource/issue.rb +69 -38
- data/lib/jira/resource/issue_picker_suggestions.rb +24 -0
- data/lib/jira/resource/issue_picker_suggestions_issue.rb +10 -0
- data/lib/jira/resource/issuelink.rb +3 -5
- data/lib/jira/resource/issuelinktype.rb +0 -1
- data/lib/jira/resource/issuetype.rb +1 -3
- data/lib/jira/resource/priority.rb +1 -3
- data/lib/jira/resource/project.rb +5 -7
- data/lib/jira/resource/rapidview.rb +28 -7
- data/lib/jira/resource/remotelink.rb +1 -4
- data/lib/jira/resource/resolution.rb +2 -4
- data/lib/jira/resource/serverinfo.rb +1 -2
- data/lib/jira/resource/sprint.rb +86 -17
- data/lib/jira/resource/sprint_report.rb +8 -0
- data/lib/jira/resource/status.rb +1 -3
- data/lib/jira/resource/suggested_issue.rb +9 -0
- data/lib/jira/resource/transition.rb +2 -6
- data/lib/jira/resource/user.rb +12 -2
- data/lib/jira/resource/version.rb +1 -3
- data/lib/jira/resource/watcher.rb +35 -0
- data/lib/jira/resource/webhook.rb +3 -6
- data/lib/jira/resource/worklog.rb +3 -5
- data/lib/jira/version.rb +1 -1
- data/lib/jira-ruby.rb +12 -2
- data/lib/tasks/generate.rake +4 -4
- data/spec/integration/attachment_spec.rb +17 -8
- data/spec/integration/comment_spec.rb +31 -34
- data/spec/integration/component_spec.rb +21 -24
- data/spec/integration/field_spec.rb +15 -18
- data/spec/integration/issue_spec.rb +45 -46
- data/spec/integration/issuelinktype_spec.rb +8 -11
- data/spec/integration/issuetype_spec.rb +5 -7
- data/spec/integration/priority_spec.rb +5 -8
- data/spec/integration/project_spec.rb +13 -20
- data/spec/integration/rapidview_spec.rb +17 -10
- data/spec/integration/resolution_spec.rb +7 -10
- data/spec/integration/status_spec.rb +5 -8
- data/spec/integration/transition_spec.rb +17 -20
- data/spec/integration/user_spec.rb +24 -8
- data/spec/integration/version_spec.rb +21 -25
- data/spec/integration/watcher_spec.rb +62 -0
- data/spec/integration/webhook.rb +8 -17
- data/spec/integration/worklog_spec.rb +30 -34
- data/spec/jira/base_factory_spec.rb +11 -12
- data/spec/jira/base_spec.rb +216 -229
- data/spec/jira/client_spec.rb +227 -159
- data/spec/jira/has_many_proxy_spec.rb +11 -12
- data/spec/jira/http_client_spec.rb +254 -31
- data/spec/jira/http_error_spec.rb +7 -9
- data/spec/jira/jwt_uri_builder_spec.rb +59 -0
- data/spec/jira/oauth_client_spec.rb +110 -39
- data/spec/jira/request_client_spec.rb +36 -9
- data/spec/jira/resource/agile_spec.rb +135 -0
- data/spec/jira/resource/attachment_spec.rb +127 -9
- data/spec/jira/resource/board_spec.rb +224 -0
- data/spec/jira/resource/createmeta_spec.rb +29 -32
- data/spec/jira/resource/field_spec.rb +42 -48
- data/spec/jira/resource/filter_spec.rb +40 -40
- data/spec/jira/resource/issue_picker_suggestions_spec.rb +79 -0
- data/spec/jira/resource/issue_spec.rb +88 -85
- data/spec/jira/resource/issuelink_spec.rb +1 -1
- data/spec/jira/resource/jira_picker_suggestions_issue_spec.rb +18 -0
- data/spec/jira/resource/project_factory_spec.rb +2 -4
- data/spec/jira/resource/project_spec.rb +33 -33
- data/spec/jira/resource/sprint_spec.rb +90 -0
- data/spec/jira/resource/user_factory_spec.rb +6 -8
- data/spec/jira/resource/worklog_spec.rb +9 -11
- data/spec/mock_responses/board/1.json +33 -0
- data/spec/mock_responses/board/1_issues.json +62 -0
- data/spec/mock_responses/empty_issues.json +8 -0
- data/spec/mock_responses/issue/10002/watchers.json +13 -0
- data/spec/mock_responses/issue.json +1 -1
- data/spec/mock_responses/sprint/1_issues.json +125 -0
- data/spec/spec_helper.rb +8 -9
- data/spec/support/clients_helper.rb +4 -4
- data/spec/support/shared_examples/integration.rb +60 -77
- metadata +115 -55
- data/.ruby-version +0 -1
- data/README.rdoc +0 -333
- /data/spec/mock_responses/{attachment → issue/10002/attachments}/10000.json +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 113ad755633d6eb87e63d7a97d3228f6649828547c01dee1ae1900ef0d575e2d
|
4
|
+
data.tar.gz: d59620f52976814ee7db58df10213bdb512f042a8b8214789ed07288f2899b65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e523698732b5cef8a220259ccf5c42c568ac7eea435ee2ed2f2018cdd25959597d23337a67fac037e00be85a8838d9d32a2c79a156da008380699d2c9529cb03
|
7
|
+
data.tar.gz: cefe63455cb070951d73420dc1144b0c0a4651836427f507d218d3eb0780936e6a740842f6f2df8f68b14be8034bb196b4f5069d21ac0c3cd9e2a4292e43b456
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
source
|
1
|
+
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
group :development do
|
4
|
+
gem 'guard'
|
5
|
+
gem 'guard-rspec'
|
4
6
|
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
5
7
|
end
|
6
8
|
|
9
|
+
group :development, :test do
|
10
|
+
gem 'pry' # this was in the original Gemfile - but only needed in development & test
|
11
|
+
end
|
12
|
+
|
7
13
|
# Specify your gem's dependencies in jira_api.gemspec
|
8
14
|
gemspec
|
data/Guardfile
CHANGED
data/README.md
ADDED
@@ -0,0 +1,452 @@
|
|
1
|
+
# JIRA API Gem
|
2
|
+
|
3
|
+
[![Code Climate](https://codeclimate.com/github/sumoheavy/jira-ruby.svg)](https://codeclimate.com/github/sumoheavy/jira-ruby)
|
4
|
+
[![Build Status](https://travis-ci.org/sumoheavy/jira-ruby.svg?branch=master)](https://travis-ci.org/sumoheavy/jira-ruby)
|
5
|
+
|
6
|
+
This gem provides access to the Atlassian JIRA REST API.
|
7
|
+
|
8
|
+
## Slack
|
9
|
+
|
10
|
+
Join our Slack channel! You can find us [here](https://jira-ruby-slackin.herokuapp.com/)
|
11
|
+
|
12
|
+
## Example usage
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'rubygems'
|
16
|
+
require 'jira-ruby'
|
17
|
+
|
18
|
+
options = {
|
19
|
+
:username => 'username',
|
20
|
+
:password => 'pass1234',
|
21
|
+
:site => 'http://mydomain.atlassian.net:443/',
|
22
|
+
:context_path => '',
|
23
|
+
:auth_type => :basic
|
24
|
+
}
|
25
|
+
|
26
|
+
client = JIRA::Client.new(options)
|
27
|
+
|
28
|
+
project = client.Project.find('SAMPLEPROJECT')
|
29
|
+
|
30
|
+
project.issues.each do |issue|
|
31
|
+
puts "#{issue.id} - #{issue.summary}"
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
## Links to JIRA REST API documentation
|
36
|
+
|
37
|
+
* [Overview](https://developer.atlassian.com/display/JIRADEV/JIRA+REST+APIs)
|
38
|
+
|
39
|
+
* [Reference](http://docs.atlassian.com/jira/REST/latest/)
|
40
|
+
|
41
|
+
## Running tests
|
42
|
+
|
43
|
+
Before running tests, you will need a public certificate generated.
|
44
|
+
|
45
|
+
```shell
|
46
|
+
rake jira:generate_public_cert
|
47
|
+
```
|
48
|
+
|
49
|
+
## Setting up the JIRA SDK
|
50
|
+
|
51
|
+
On Mac OS,
|
52
|
+
|
53
|
+
* Follow the instructions under "Mac OSX Installer" here: https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-linux-or-mac-system
|
54
|
+
* From within the archive directory, run:
|
55
|
+
|
56
|
+
```shell
|
57
|
+
./bin/atlas-run-standalone --product jira
|
58
|
+
```
|
59
|
+
|
60
|
+
Once this is running, you should be able to connect to
|
61
|
+
http://localhost:2990/ and login to the JIRA admin system using `admin:admin`
|
62
|
+
|
63
|
+
You'll need to create a dummy project and probably some issues to test using
|
64
|
+
this library.
|
65
|
+
|
66
|
+
## Configuring JIRA to use OAuth
|
67
|
+
|
68
|
+
From the JIRA API tutorial
|
69
|
+
|
70
|
+
> The first step is to register a new consumer in JIRA. This is done through
|
71
|
+
> the Application Links administration screens in JIRA. Create a new
|
72
|
+
> Application Link.
|
73
|
+
> [Administration/Plugins/Application Links](http://localhost:2990/jira/plugins/servlet/applinks/listApplicationLinks)
|
74
|
+
>
|
75
|
+
> When creating the Application Link use a placeholder URL or the correct URL
|
76
|
+
> to your client (e.g. `http://localhost:3000`), if your client can be reached
|
77
|
+
> via HTTP and choose the Generic Application type. After this Application Link
|
78
|
+
> has been created, edit the configuration and go to the incoming
|
79
|
+
> authentication configuration screen and select OAuth. Enter in this the
|
80
|
+
> public key and the consumer key which your client will use when making
|
81
|
+
> requests to JIRA.
|
82
|
+
|
83
|
+
This public key and consumer key will need to be generated by the Gem user, using OpenSSL
|
84
|
+
or similar to generate the public key and the provided rake task to generate the consumer
|
85
|
+
key.
|
86
|
+
|
87
|
+
> After you have entered all the information click OK and ensure OAuth authentication is
|
88
|
+
> enabled.
|
89
|
+
|
90
|
+
For 2 legged oauth in server mode only, not in cloud based JIRA, make sure to `Allow 2-Legged OAuth`
|
91
|
+
|
92
|
+
## Configuring JIRA to use HTTP Basic Auth
|
93
|
+
|
94
|
+
Follow the same steps described above to set up a new Application Link in JIRA,
|
95
|
+
however there is no need to set up any "incoming authentication" as this
|
96
|
+
defaults to HTTP Basic Auth.
|
97
|
+
|
98
|
+
## Configuring JIRA to use Cookie-Based Auth
|
99
|
+
|
100
|
+
Jira supports cookie based authentication whereby user credentials are passed
|
101
|
+
to JIRA via a JIRA REST API call. This call returns a session cookie which must
|
102
|
+
then be sent to all following JIRA REST API calls.
|
103
|
+
|
104
|
+
To enable cookie based authentication, set `:auth_type` to `:cookie`,
|
105
|
+
set `:use_cookies` to `true` and set `:username` and `:password` accordingly.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
require 'jira-ruby'
|
109
|
+
|
110
|
+
options = {
|
111
|
+
:username => 'username',
|
112
|
+
:password => 'pass1234',
|
113
|
+
:site => 'http://mydomain.atlassian.net:443/',
|
114
|
+
:context_path => '',
|
115
|
+
:auth_type => :cookie, # Set cookie based authentication
|
116
|
+
:use_cookies => true, # Send cookies with each request
|
117
|
+
:additional_cookies => ['AUTH=vV7uzixt0SScJKg7'] # Optional cookies to send
|
118
|
+
# with each request
|
119
|
+
}
|
120
|
+
|
121
|
+
client = JIRA::Client.new(options)
|
122
|
+
|
123
|
+
project = client.Project.find('SAMPLEPROJECT')
|
124
|
+
|
125
|
+
project.issues.each do |issue|
|
126
|
+
puts "#{issue.id} - #{issue.summary}"
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
Some authentication schemes might require additional cookies to be sent with
|
131
|
+
each request. Cookies added to the `:additional_cookies` option will be added
|
132
|
+
to each request. This option should be an array of strings representing each
|
133
|
+
cookie to add to the request.
|
134
|
+
|
135
|
+
Some authentication schemes that require additional cookies ignore the username
|
136
|
+
and password sent in the JIRA REST API call. For those use cases, `:username`
|
137
|
+
and `:password` may be omitted from `options`.
|
138
|
+
|
139
|
+
## Configuring JIRA to use Personal Access Tokens Auth
|
140
|
+
If your JIRA system is configured to support Personal Access Token authorization, minor modifications are needed in how credentials are communicated to the server. Specifically, the paremeters `:username` and `:password` are not needed. Also, the parameter `:default_headers` is needed to contain the api_token, which can be obtained following the official documentation from [Atlassian](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html). Please note that the Personal Access Token can only be used as it is. If it is encoded (with base64 or any other encoding method) then the token will not work correctly and authentication will fail.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
require 'jira-ruby'
|
144
|
+
|
145
|
+
# NOTE: the token should not be encoded
|
146
|
+
api_token = API_TOKEN_OBTAINED_FROM_JIRA_UI
|
147
|
+
|
148
|
+
options = {
|
149
|
+
:site => 'http://mydomain.atlassian.net:443/',
|
150
|
+
:context_path => '',
|
151
|
+
:username => '<the email you sign-in to Jira>',
|
152
|
+
:password => api_token,
|
153
|
+
:auth_type => :basic
|
154
|
+
}
|
155
|
+
|
156
|
+
client = JIRA::Client.new(options)
|
157
|
+
|
158
|
+
project = client.Project.find('SAMPLEPROJECT')
|
159
|
+
|
160
|
+
project.issues.each do |issue|
|
161
|
+
puts "#{issue.id} - #{issue.summary}"
|
162
|
+
end
|
163
|
+
```
|
164
|
+
## Using the API Gem in a command line application
|
165
|
+
|
166
|
+
Using HTTP Basic Authentication, configure and connect a client to your instance
|
167
|
+
of JIRA.
|
168
|
+
|
169
|
+
Note: If your Jira install is hosted on [atlassian.net](atlassian.net), it will have no context
|
170
|
+
path by default. If you're having issues connecting, try setting context_path
|
171
|
+
to an empty string in the options hash.
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
require 'rubygems'
|
175
|
+
require 'pp'
|
176
|
+
require 'jira-ruby'
|
177
|
+
|
178
|
+
# Consider the use of :use_ssl and :ssl_verify_mode options if running locally
|
179
|
+
# for tests.
|
180
|
+
|
181
|
+
# NOTE basic auth no longer works with Jira, you must generate an API token, to do so you must have jira instance access rights. You can generate a token here: https://id.atlassian.com/manage/api-tokens
|
182
|
+
|
183
|
+
# You will see JIRA::HTTPError (JIRA::HTTPError) if you attempt to use basic auth with your user's password
|
184
|
+
|
185
|
+
username = "myremoteuser"
|
186
|
+
api_token = "myApiToken"
|
187
|
+
|
188
|
+
options = {
|
189
|
+
:username => username,
|
190
|
+
:password => api_token,
|
191
|
+
:site => 'http://localhost:8080/', # or 'https://<your_subdomain>.atlassian.net/'
|
192
|
+
:context_path => '/myjira', # often blank
|
193
|
+
:auth_type => :basic,
|
194
|
+
:read_timeout => 120
|
195
|
+
}
|
196
|
+
|
197
|
+
client = JIRA::Client.new(options)
|
198
|
+
|
199
|
+
# Show all projects
|
200
|
+
projects = client.Project.all
|
201
|
+
|
202
|
+
projects.each do |project|
|
203
|
+
puts "Project -> key: #{project.key}, name: #{project.name}"
|
204
|
+
end
|
205
|
+
```
|
206
|
+
|
207
|
+
## Using the API Gem in your Rails application
|
208
|
+
|
209
|
+
Using oauth, the gem requires the consumer key and public certificate file (which
|
210
|
+
are generated in their respective rake tasks) to initialize an access token for
|
211
|
+
using the JIRA API.
|
212
|
+
|
213
|
+
Note that currently the rake task which generates the public certificate
|
214
|
+
requires OpenSSL to be installed on the machine.
|
215
|
+
|
216
|
+
Below is an example for setting up a rails application for OAuth authorization.
|
217
|
+
|
218
|
+
Ensure the JIRA gem is loaded correctly
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
# Gemfile
|
222
|
+
...
|
223
|
+
gem 'jira-ruby', :require => 'jira-ruby'
|
224
|
+
...
|
225
|
+
```
|
226
|
+
|
227
|
+
Add common methods to your application controller and ensure access token
|
228
|
+
errors are handled gracefully
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
# app/controllers/application_controller.rb
|
232
|
+
class ApplicationController < ActionController::Base
|
233
|
+
protect_from_forgery
|
234
|
+
|
235
|
+
rescue_from JIRA::OauthClient::UninitializedAccessTokenError do
|
236
|
+
redirect_to new_jira_session_url
|
237
|
+
end
|
238
|
+
|
239
|
+
private
|
240
|
+
|
241
|
+
def get_jira_client
|
242
|
+
|
243
|
+
# add any extra configuration options for your instance of JIRA,
|
244
|
+
# e.g. :use_ssl, :ssl_verify_mode, :context_path, :site
|
245
|
+
options = {
|
246
|
+
:private_key_file => "rsakey.pem",
|
247
|
+
:consumer_key => 'test'
|
248
|
+
}
|
249
|
+
|
250
|
+
@jira_client = JIRA::Client.new(options)
|
251
|
+
|
252
|
+
# Add AccessToken if authorised previously.
|
253
|
+
if session[:jira_auth]
|
254
|
+
@jira_client.set_access_token(
|
255
|
+
session[:jira_auth]['access_token'],
|
256
|
+
session[:jira_auth]['access_key']
|
257
|
+
)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
```
|
262
|
+
|
263
|
+
Create a controller for handling the OAuth conversation.
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
# app/controllers/jira_sessions_controller.rb
|
267
|
+
class JiraSessionsController < ApplicationController
|
268
|
+
|
269
|
+
before_filter :get_jira_client
|
270
|
+
|
271
|
+
def new
|
272
|
+
callback_url = 'http://callback'
|
273
|
+
request_token = @jira_client.request_token(oauth_callback: callback_url)
|
274
|
+
session[:request_token] = request_token.token
|
275
|
+
session[:request_secret] = request_token.secret
|
276
|
+
|
277
|
+
redirect_to request_token.authorize_url
|
278
|
+
end
|
279
|
+
|
280
|
+
def authorize
|
281
|
+
request_token = @jira_client.set_request_token(
|
282
|
+
session[:request_token], session[:request_secret]
|
283
|
+
)
|
284
|
+
access_token = @jira_client.init_access_token(
|
285
|
+
:oauth_verifier => params[:oauth_verifier]
|
286
|
+
)
|
287
|
+
|
288
|
+
session[:jira_auth] = {
|
289
|
+
:access_token => access_token.token,
|
290
|
+
:access_key => access_token.secret
|
291
|
+
}
|
292
|
+
|
293
|
+
session.delete(:request_token)
|
294
|
+
session.delete(:request_secret)
|
295
|
+
|
296
|
+
redirect_to projects_path
|
297
|
+
end
|
298
|
+
|
299
|
+
def destroy
|
300
|
+
session.data.delete(:jira_auth)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
```
|
304
|
+
|
305
|
+
Create your own controllers for the JIRA resources you wish to access.
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
# app/controllers/issues_controller.rb
|
309
|
+
class IssuesController < ApplicationController
|
310
|
+
before_filter :get_jira_client
|
311
|
+
def index
|
312
|
+
@issues = @jira_client.Issue.all
|
313
|
+
end
|
314
|
+
|
315
|
+
def show
|
316
|
+
@issue = @jira_client.Issue.find(params[:id])
|
317
|
+
end
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
321
|
+
## Using the API Gem in your Sinatra application
|
322
|
+
|
323
|
+
Here's the same example as a Sinatra application:
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
require 'jira-ruby'
|
327
|
+
class App < Sinatra::Base
|
328
|
+
enable :sessions
|
329
|
+
|
330
|
+
# This section gets called before every request. Here, we set up the
|
331
|
+
# OAuth consumer details including the consumer key, private key,
|
332
|
+
# site uri, and the request token, access token, and authorize paths
|
333
|
+
before do
|
334
|
+
options = {
|
335
|
+
:site => 'http://localhost:2990/',
|
336
|
+
:context_path => '/jira',
|
337
|
+
:signature_method => 'RSA-SHA1',
|
338
|
+
:request_token_path => "/plugins/servlet/oauth/request-token",
|
339
|
+
:authorize_path => "/plugins/servlet/oauth/authorize",
|
340
|
+
:access_token_path => "/plugins/servlet/oauth/access-token",
|
341
|
+
:private_key_file => "rsakey.pem",
|
342
|
+
:rest_base_path => "/rest/api/2",
|
343
|
+
:consumer_key => "jira-ruby-example"
|
344
|
+
}
|
345
|
+
|
346
|
+
@jira_client = JIRA::Client.new(options)
|
347
|
+
@jira_client.consumer.http.set_debug_output($stderr)
|
348
|
+
|
349
|
+
# Add AccessToken if authorised previously.
|
350
|
+
if session[:jira_auth]
|
351
|
+
@jira_client.set_access_token(
|
352
|
+
session[:jira_auth][:access_token],
|
353
|
+
session[:jira_auth][:access_key]
|
354
|
+
)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
|
359
|
+
# Starting point: http://<yourserver>/
|
360
|
+
# This will serve up a login link if you're not logged in. If you are, it'll show some user info and a
|
361
|
+
# signout link
|
362
|
+
get '/' do
|
363
|
+
if !session[:jira_auth]
|
364
|
+
# not logged in
|
365
|
+
<<-eos
|
366
|
+
<h1>jira-ruby (JIRA 5 Ruby Gem) demo </h1>You're not signed in. Why don't you
|
367
|
+
<a href=/signin>sign in</a> first.
|
368
|
+
eos
|
369
|
+
else
|
370
|
+
#logged in
|
371
|
+
@issues = @jira_client.Issue.all
|
372
|
+
|
373
|
+
# HTTP response inlined with bind data below...
|
374
|
+
<<-eos
|
375
|
+
You're now signed in. There #{@issues.count == 1 ? "is" : "are"} #{@issues.count}
|
376
|
+
issue#{@issues.count == 1 ? "" : "s"} in this JIRA instance. <a href='/signout'>Signout</a>
|
377
|
+
eos
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# http://<yourserver>/signin
|
382
|
+
# Initiates the OAuth dance by first requesting a token then redirecting to
|
383
|
+
# http://<yourserver>/auth to get the @access_token
|
384
|
+
get '/signin' do
|
385
|
+
callback_url = "#{request.base_url}/callback"
|
386
|
+
request_token = @jira_client.request_token(oauth_callback: callback_url)
|
387
|
+
session[:request_token] = request_token.token
|
388
|
+
session[:request_secret] = request_token.secret
|
389
|
+
|
390
|
+
redirect request_token.authorize_url
|
391
|
+
end
|
392
|
+
|
393
|
+
# http://<yourserver>/callback
|
394
|
+
# Retrieves the @access_token then stores it inside a session cookie. In a real app,
|
395
|
+
# you'll want to persist the token in a datastore associated with the user.
|
396
|
+
get "/callback" do
|
397
|
+
request_token = @jira_client.set_request_token(
|
398
|
+
session[:request_token], session[:request_secret]
|
399
|
+
)
|
400
|
+
access_token = @jira_client.init_access_token(
|
401
|
+
:oauth_verifier => params[:oauth_verifier]
|
402
|
+
)
|
403
|
+
|
404
|
+
session[:jira_auth] = {
|
405
|
+
:access_token => access_token.token,
|
406
|
+
:access_key => access_token.secret
|
407
|
+
}
|
408
|
+
|
409
|
+
session.delete(:request_token)
|
410
|
+
session.delete(:request_secret)
|
411
|
+
|
412
|
+
redirect "/"
|
413
|
+
end
|
414
|
+
|
415
|
+
# http://<yourserver>/signout
|
416
|
+
# Expires the session
|
417
|
+
get "/signout" do
|
418
|
+
session.delete(:jira_auth)
|
419
|
+
redirect "/"
|
420
|
+
end
|
421
|
+
end
|
422
|
+
```
|
423
|
+
|
424
|
+
## Using the API Gem in a 2 legged context
|
425
|
+
|
426
|
+
Here's an example on how to use 2 legged OAuth:
|
427
|
+
```ruby
|
428
|
+
require 'rubygems'
|
429
|
+
require 'pp'
|
430
|
+
require 'jira-ruby'
|
431
|
+
|
432
|
+
options = {
|
433
|
+
:site => 'http://localhost:2990/',
|
434
|
+
:context_path => '/jira',
|
435
|
+
:signature_method => 'RSA-SHA1',
|
436
|
+
:private_key_file => "rsakey.pem",
|
437
|
+
:rest_base_path => "/rest/api/2",
|
438
|
+
:auth_type => :oauth_2legged,
|
439
|
+
:consumer_key => "jira-ruby-example"
|
440
|
+
}
|
441
|
+
|
442
|
+
client = JIRA::Client.new(options)
|
443
|
+
|
444
|
+
client.set_access_token("","")
|
445
|
+
|
446
|
+
# Show all projects
|
447
|
+
projects = client.Project.all
|
448
|
+
|
449
|
+
projects.each do |project|
|
450
|
+
puts "Project -> key: #{project.key}, name: #{project.name}"
|
451
|
+
end
|
452
|
+
```
|
data/Rakefile
CHANGED
@@ -6,25 +6,24 @@ require 'rdoc/task'
|
|
6
6
|
|
7
7
|
Dir.glob('lib/tasks/*.rake').each { |r| import r }
|
8
8
|
|
9
|
-
task :
|
9
|
+
task default: [:test]
|
10
10
|
|
11
|
-
task :
|
11
|
+
task test: %i[prepare spec]
|
12
12
|
|
13
13
|
desc 'Prepare and run rspec tests'
|
14
14
|
task :prepare do
|
15
15
|
rsa_key = File.expand_path('rsakey.pem')
|
16
|
-
unless File.
|
17
|
-
|
16
|
+
unless File.exist?(rsa_key)
|
17
|
+
Rake::Task['jira:generate_public_cert'].invoke
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
desc 'Run RSpec tests'
|
22
|
-
#RSpec::Core::RakeTask.new(:spec)
|
23
|
-
RSpec::Core::RakeTask.new(:spec) do |task|
|
22
|
+
# RSpec::Core::RakeTask.new(:spec)
|
23
|
+
RSpec::Core::RakeTask.new(:spec, [] => [:prepare]) do |task|
|
24
24
|
task.rspec_opts = ['--color', '--format', 'doc']
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
27
|
Rake::RDocTask.new(:doc) do |rd|
|
29
28
|
rd.main = 'README.rdoc'
|
30
29
|
rd.rdoc_dir = 'doc'
|
data/example.rb
CHANGED
@@ -99,7 +99,16 @@ client.Issue.jql(a_normal_jql_search, max_results: 500)
|
|
99
99
|
# # Create an issue
|
100
100
|
# # ---------------
|
101
101
|
# issue = client.Issue.build
|
102
|
-
#
|
102
|
+
# labels = ['label1', 'label2']
|
103
|
+
# issue.save({
|
104
|
+
# "fields" => {
|
105
|
+
# "summary" => "blarg from in example.rb",
|
106
|
+
# "project" => {"key" => "SAMPLEPROJECT"},
|
107
|
+
# "issuetype" => {"id" => "3"},
|
108
|
+
# "labels" => labels,
|
109
|
+
# "priority" => {"id" => "1"}
|
110
|
+
# }
|
111
|
+
# })
|
103
112
|
# issue.fetch
|
104
113
|
# pp issue
|
105
114
|
#
|
@@ -123,6 +132,11 @@ client.Issue.jql(a_normal_jql_search, max_results: 500)
|
|
123
132
|
# user = client.User.find('admin')
|
124
133
|
# pp user
|
125
134
|
#
|
135
|
+
# # Get all issue watchers
|
136
|
+
# # ----------------------
|
137
|
+
# issue = client.Issue.find("10002")
|
138
|
+
# watchers = issue.watchers.all
|
139
|
+
# watchers = client.Watcher.all(:issue => issue)
|
126
140
|
# # Get all issue types
|
127
141
|
# # -------------------
|
128
142
|
# issuetypes = client.Issuetype.all
|
@@ -152,6 +166,14 @@ client.Issue.jql(a_normal_jql_search, max_results: 500)
|
|
152
166
|
# # --------------------------
|
153
167
|
# issue.comments.first.save({"body" => "an updated comment frome example.rb"})
|
154
168
|
|
169
|
+
|
170
|
+
# # Add attachment to Issue
|
171
|
+
# # ------------------------
|
172
|
+
# issue = client.Issue.find('PROJ-1')
|
173
|
+
# attachment = issue.attachments.build
|
174
|
+
# attachment.save('file': '/path/to/file')
|
175
|
+
#
|
176
|
+
|
155
177
|
# List all available link types
|
156
178
|
# ------------------------------
|
157
179
|
pp client.Issuelinktype.all
|
data/http-basic-example.rb
CHANGED
@@ -2,29 +2,30 @@ require 'rubygems'
|
|
2
2
|
require 'pp'
|
3
3
|
require 'jira-ruby'
|
4
4
|
|
5
|
-
if ARGV.
|
5
|
+
if ARGV.empty?
|
6
6
|
# If not passed any command line arguments, prompt the
|
7
7
|
# user for the username and password.
|
8
|
-
puts
|
8
|
+
puts 'Enter the username: '
|
9
9
|
username = gets.strip
|
10
10
|
|
11
|
-
puts
|
11
|
+
puts 'Enter the password: '
|
12
12
|
password = gets.strip
|
13
13
|
elsif ARGV.length == 2
|
14
|
-
username
|
14
|
+
username = ARGV[0]
|
15
|
+
password = ARGV[1]
|
15
16
|
else
|
16
17
|
# Script must be passed 0 or 2 arguments
|
17
|
-
raise "Usage: #{$
|
18
|
+
raise "Usage: #{$PROGRAM_NAME} [ username password ]"
|
18
19
|
end
|
19
20
|
|
20
21
|
options = {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
username: username,
|
23
|
+
password: password,
|
24
|
+
site: 'http://localhost:8080/',
|
25
|
+
context_path: '',
|
26
|
+
auth_type: :basic,
|
27
|
+
use_ssl: false
|
28
|
+
}
|
28
29
|
|
29
30
|
client = JIRA::Client.new(options)
|
30
31
|
|
data/jira-ruby.gemspec
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
|
2
|
-
$:.push File.expand_path('../lib', __FILE__)
|
1
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
3
2
|
require 'jira/version'
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = 'jira-ruby'
|
7
6
|
s.version = JIRA::VERSION
|
8
|
-
s.authors = ['SUMO Heavy Industries']
|
7
|
+
s.authors = ['SUMO Heavy Industries', 'test IO']
|
9
8
|
s.homepage = 'http://www.sumoheavy.com'
|
10
|
-
s.summary =
|
11
|
-
s.description =
|
9
|
+
s.summary = 'Ruby Gem for use with the Atlassian JIRA REST API'
|
10
|
+
s.description = 'API for JIRA'
|
12
11
|
s.licenses = ['MIT']
|
12
|
+
s.metadata = { 'source_code_uri' => 'https://github.com/sumoheavy/jira-ruby' }
|
13
13
|
|
14
14
|
s.required_ruby_version = '>= 1.9.3'
|
15
15
|
|
16
|
-
s.rubyforge_project = 'jira-ruby'
|
17
|
-
|
18
16
|
s.files = `git ls-files`.split("\n")
|
19
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
21
19
|
s.require_paths = ['lib']
|
22
20
|
|
23
21
|
# Runtime Dependencies
|
24
|
-
s.add_runtime_dependency 'oauth', '~> 0.5', '>= 0.5.0'
|
25
22
|
s.add_runtime_dependency 'activesupport'
|
23
|
+
s.add_runtime_dependency 'atlassian-jwt'
|
24
|
+
s.add_runtime_dependency 'multipart-post'
|
25
|
+
s.add_runtime_dependency 'oauth', '~> 0.5', '>= 0.5.0'
|
26
26
|
|
27
27
|
# Development Dependencies
|
28
|
-
s.add_development_dependency 'railties'
|
29
|
-
s.add_development_dependency 'webmock', '~> 1.18', '>= 1.18.0'
|
30
|
-
s.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
|
31
|
-
s.add_development_dependency 'rake', '~> 10.3', '>= 10.3.2'
|
32
28
|
s.add_development_dependency 'guard', '~> 2.13', '>= 2.13.0'
|
33
29
|
s.add_development_dependency 'guard-rspec', '~> 4.6', '>= 4.6.5'
|
34
30
|
s.add_development_dependency 'pry', '~> 0.10', '>= 0.10.3'
|
31
|
+
s.add_development_dependency 'railties'
|
32
|
+
s.add_development_dependency 'rake', '~> 10.3', '>= 10.3.2'
|
33
|
+
s.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
|
34
|
+
s.add_development_dependency 'webmock', '~> 1.18', '>= 1.18.0'
|
35
35
|
end
|