Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
6c17e4f0
Commit
6c17e4f0
authored
May 23, 2017
by
Jarka Kadlecova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add API URL to JIRA settings
parent
8f2af757
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
156 additions
and
54 deletions
+156
-54
app/models/project_services/jira_service.rb
app/models/project_services/jira_service.rb
+25
-12
changelogs/unreleased/31448-jira-urls.yml
changelogs/unreleased/31448-jira-urls.yml
+4
-0
doc/user/project/integrations/jira.md
doc/user/project/integrations/jira.md
+2
-1
features/steps/project/services.rb
features/steps/project/services.rb
+4
-2
lib/api/services.rb
lib/api/services.rb
+7
-1
spec/models/project_services/jira_service_spec.rb
spec/models/project_services/jira_service_spec.rb
+114
-38
No files found.
app/models/project_services/jira_service.rb
View file @
6c17e4f0
...
@@ -2,9 +2,10 @@ class JiraService < IssueTrackerService
...
@@ -2,9 +2,10 @@ class JiraService < IssueTrackerService
include
Gitlab
::
Routing
.
url_helpers
include
Gitlab
::
Routing
.
url_helpers
validates
:url
,
url:
true
,
presence:
true
,
if: :activated?
validates
:url
,
url:
true
,
presence:
true
,
if: :activated?
validates
:api_url
,
url:
true
,
allow_blank:
true
validates
:project_key
,
presence:
true
,
if: :activated?
validates
:project_key
,
presence:
true
,
if: :activated?
prop_accessor
:username
,
:password
,
:url
,
:project_key
,
prop_accessor
:username
,
:password
,
:url
,
:
api_url
,
:
project_key
,
:jira_issue_transition_id
,
:title
,
:description
:jira_issue_transition_id
,
:title
,
:description
before_update
:reset_password
before_update
:reset_password
...
@@ -25,20 +26,18 @@ class JiraService < IssueTrackerService
...
@@ -25,20 +26,18 @@ class JiraService < IssueTrackerService
super
do
super
do
self
.
properties
=
{
self
.
properties
=
{
title:
issues_tracker
[
'title'
],
title:
issues_tracker
[
'title'
],
url:
issues_tracker
[
'url'
]
url:
issues_tracker
[
'url'
],
api_url:
issues_tracker
[
'api_url'
]
}
}
end
end
end
end
def
reset_password
def
reset_password
# don't reset the password if a new one is provided
self
.
password
=
nil
if
reset_password?
if
url_changed?
&&
!
password_touched?
self
.
password
=
nil
end
end
end
def
options
def
options
url
=
URI
.
parse
(
self
.
url
)
url
=
URI
.
parse
(
client_
url
)
{
{
username:
self
.
username
,
username:
self
.
username
,
...
@@ -87,7 +86,8 @@ class JiraService < IssueTrackerService
...
@@ -87,7 +86,8 @@ class JiraService < IssueTrackerService
def
fields
def
fields
[
[
{
type:
'text'
,
name:
'url'
,
title:
'URL'
,
placeholder:
'https://jira.example.com'
},
{
type:
'text'
,
name:
'url'
,
title:
'Web URL'
,
placeholder:
'https://jira.example.com'
},
{
type:
'text'
,
name:
'api_url'
,
title:
'JIRA API URL'
,
placeholder:
'If different from Web URL'
},
{
type:
'text'
,
name:
'project_key'
,
placeholder:
'Project Key'
},
{
type:
'text'
,
name:
'project_key'
,
placeholder:
'Project Key'
},
{
type:
'text'
,
name:
'username'
,
placeholder:
''
},
{
type:
'text'
,
name:
'username'
,
placeholder:
''
},
{
type:
'password'
,
name:
'password'
,
placeholder:
''
},
{
type:
'password'
,
name:
'password'
,
placeholder:
''
},
...
@@ -186,7 +186,7 @@ class JiraService < IssueTrackerService
...
@@ -186,7 +186,7 @@ class JiraService < IssueTrackerService
end
end
def
test_settings
def
test_settings
return
unless
url
.
present?
return
unless
client_
url
.
present?
# Test settings by getting the project
# Test settings by getting the project
jira_request
{
jira_project
.
present?
}
jira_request
{
jira_project
.
present?
}
end
end
...
@@ -236,13 +236,13 @@ class JiraService < IssueTrackerService
...
@@ -236,13 +236,13 @@ class JiraService < IssueTrackerService
end
end
def
send_message
(
issue
,
message
,
remote_link_props
)
def
send_message
(
issue
,
message
,
remote_link_props
)
return
unless
url
.
present?
return
unless
client_
url
.
present?
jira_request
do
jira_request
do
if
issue
.
comments
.
build
.
save!
(
body:
message
)
if
issue
.
comments
.
build
.
save!
(
body:
message
)
remote_link
=
issue
.
remotelink
.
build
remote_link
=
issue
.
remotelink
.
build
remote_link
.
save!
(
remote_link_props
)
remote_link
.
save!
(
remote_link_props
)
result_message
=
"
#{
self
.
class
.
name
}
SUCCESS: Successfully posted to
#{
url
}
."
result_message
=
"
#{
self
.
class
.
name
}
SUCCESS: Successfully posted to
#{
client_
url
}
."
end
end
Rails
.
logger
.
info
(
result_message
)
Rails
.
logger
.
info
(
result_message
)
...
@@ -295,7 +295,20 @@ class JiraService < IssueTrackerService
...
@@ -295,7 +295,20 @@ class JiraService < IssueTrackerService
yield
yield
rescue
Timeout
::
Error
,
Errno
::
EINVAL
,
Errno
::
ECONNRESET
,
Errno
::
ECONNREFUSED
,
URI
::
InvalidURIError
,
JIRA
::
HTTPError
,
OpenSSL
::
SSL
::
SSLError
=>
e
rescue
Timeout
::
Error
,
Errno
::
EINVAL
,
Errno
::
ECONNRESET
,
Errno
::
ECONNREFUSED
,
URI
::
InvalidURIError
,
JIRA
::
HTTPError
,
OpenSSL
::
SSL
::
SSLError
=>
e
Rails
.
logger
.
info
"
#{
self
.
class
.
name
}
Send message ERROR:
#{
url
}
-
#{
e
.
message
}
"
Rails
.
logger
.
info
"
#{
self
.
class
.
name
}
Send message ERROR:
#{
client_
url
}
-
#{
e
.
message
}
"
nil
nil
end
end
def
client_url
api_url
.
present?
?
api_url
:
url
end
def
reset_password?
# don't reset the password if a new one is provided
return
false
if
password_touched?
return
true
if
api_url_changed?
return
false
if
api_url
.
present?
url_changed?
end
end
end
changelogs/unreleased/31448-jira-urls.yml
0 → 100644
View file @
6c17e4f0
---
title
:
Add API URL to JIRA settings
merge_request
:
author
:
doc/user/project/integrations/jira.md
View file @
6c17e4f0
...
@@ -97,7 +97,8 @@ in the table below.
...
@@ -97,7 +97,8 @@ in the table below.
|
Field | Description |
|
Field | Description |
|
----- | ----------- |
|
----- | ----------- |
|
`URL` | The base URL to the JIRA project which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
|
`Web URL` | The base URL to the JIRA instance web interface which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
|
`JIRA API URL` | The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., `https://jira-api.example.com`. |
|
`Project key` | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
|
`Project key` | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
|
`Username` | The user name created in [configuring JIRA step](#configuring-jira). |
|
`Username` | The user name created in [configuring JIRA step](#configuring-jira). |
|
`Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
|
`Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
...
...
features/steps/project/services.rb
View file @
6c17e4f0
...
@@ -178,7 +178,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
...
@@ -178,7 +178,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
end
end
step
'I fill jira settings'
do
step
'I fill jira settings'
do
fill_in
'URL'
,
with:
'http://jira.example'
fill_in
'Web URL'
,
with:
'http://jira.example'
fill_in
'JIRA API URL'
,
with:
'http://jira.example/api'
fill_in
'Username'
,
with:
'gitlab'
fill_in
'Username'
,
with:
'gitlab'
fill_in
'Password'
,
with:
'gitlab'
fill_in
'Password'
,
with:
'gitlab'
fill_in
'Project Key'
,
with:
'GITLAB'
fill_in
'Project Key'
,
with:
'GITLAB'
...
@@ -186,7 +187,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
...
@@ -186,7 +187,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
end
end
step
'I should see jira service settings saved'
do
step
'I should see jira service settings saved'
do
expect
(
find_field
(
'URL'
).
value
).
to
eq
'http://jira.example'
expect
(
find_field
(
'Web URL'
).
value
).
to
eq
'http://jira.example'
expect
(
find_field
(
'JIRA API URL'
).
value
).
to
eq
'http://jira.example/api'
expect
(
find_field
(
'Username'
).
value
).
to
eq
'gitlab'
expect
(
find_field
(
'Username'
).
value
).
to
eq
'gitlab'
expect
(
find_field
(
'Project Key'
).
value
).
to
eq
'GITLAB'
expect
(
find_field
(
'Project Key'
).
value
).
to
eq
'GITLAB'
end
end
...
...
lib/api/services.rb
View file @
6c17e4f0
...
@@ -304,7 +304,13 @@ module API
...
@@ -304,7 +304,13 @@ module API
required:
true
,
required:
true
,
name: :url
,
name: :url
,
type:
String
,
type:
String
,
desc:
'The URL to the JIRA project which is being linked to this GitLab project, e.g., https://jira.example.com'
desc:
'The base URL to the JIRA instance web interface which is being linked to this GitLab project. E.g., https://jira.example.com'
},
{
required:
false
,
name: :api_url
,
type:
String
,
desc:
'The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., https://jira-api.example.com'
},
},
{
{
required:
true
,
required:
true
,
...
...
spec/models/project_services/jira_service_spec.rb
View file @
6c17e4f0
...
@@ -22,6 +22,42 @@ describe JiraService, models: true do
...
@@ -22,6 +22,42 @@ describe JiraService, models: true do
it
{
is_expected
.
not_to
validate_presence_of
(
:url
)
}
it
{
is_expected
.
not_to
validate_presence_of
(
:url
)
}
end
end
context
'validating urls'
do
let
(
:service
)
do
described_class
.
new
(
project:
create
(
:empty_project
),
active:
true
,
username:
'username'
,
password:
'test'
,
project_key:
'TEST'
,
jira_issue_transition_id:
24
,
url:
'http://jira.test.com'
)
end
it
'is valid when all fields have required values'
do
expect
(
service
).
to
be_valid
end
it
'is not valid when url is not a valid url'
do
service
.
url
=
'not valid'
expect
(
service
).
not_to
be_valid
end
it
'is not valid when api url is not a valid url'
do
service
.
api_url
=
'not valid'
expect
(
service
).
not_to
be_valid
end
it
'is valid when api url is a valid url'
do
service
.
api_url
=
'http://jira.test.com/api'
expect
(
service
).
to
be_valid
end
end
end
end
describe
'#reference_pattern'
do
describe
'#reference_pattern'
do
...
@@ -187,22 +223,29 @@ describe JiraService, models: true do
...
@@ -187,22 +223,29 @@ describe JiraService, models: true do
describe
'#test_settings'
do
describe
'#test_settings'
do
let
(
:jira_service
)
do
let
(
:jira_service
)
do
described_class
.
new
(
described_class
.
new
(
project:
create
(
:project
),
url:
'http://jira.example.com'
,
url:
'http://jira.example.com'
,
username:
'
gitlab_
jira_username'
,
username:
'jira_username'
,
password:
'
gitlab_
jira_password'
,
password:
'jira_password'
,
project_key:
'GitLabProject'
project_key:
'GitLabProject'
)
)
end
end
let
(
:project_url
)
{
'http://gitlab_jira_username:gitlab_jira_password@jira.example.com/rest/api/2/project/GitLabProject'
}
before
do
def
test_settings
(
api_url
)
project_url
=
"http://jira_username:jira_password@
#{
api_url
}
/rest/api/2/project/GitLabProject"
WebMock
.
stub_request
(
:get
,
project_url
)
WebMock
.
stub_request
(
:get
,
project_url
)
end
it
'tries to get JIRA project'
do
jira_service
.
test_settings
jira_service
.
test_settings
end
it
'tries to get JIRA project with URL when API URL not set'
do
test_settings
(
'jira.example.com'
)
end
expect
(
WebMock
).
to
have_requested
(
:get
,
project_url
)
it
'tries to get JIRA project with API URL if set'
do
jira_service
.
update
(
api_url:
'http://jira.api.com'
)
test_settings
(
'jira.api.com'
)
end
end
end
end
...
@@ -214,34 +257,75 @@ describe JiraService, models: true do
...
@@ -214,34 +257,75 @@ describe JiraService, models: true do
@jira_service
=
JiraService
.
create!
(
@jira_service
=
JiraService
.
create!
(
project:
project
,
project:
project
,
properties:
{
properties:
{
url:
'http://jira.example.com/
rest/api/2
'
,
url:
'http://jira.example.com/
web
'
,
username:
'mic'
,
username:
'mic'
,
password:
"password"
password:
"password"
}
}
)
)
end
end
it
"reset password if url changed"
do
context
'when only web url present'
do
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
it
'reset password if url changed'
do
@jira_service
.
save
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
expect
(
@jira_service
.
password
).
to
be_nil
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
be_nil
end
it
'reset password if url not changed but api url added'
do
@jira_service
.
api_url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
be_nil
end
end
end
it
"does not reset password if username changed"
do
context
'when both web and api url present'
do
@jira_service
.
username
=
"some_name"
before
do
@jira_service
.
api_url
=
'http://jira.example.com/rest/api/2'
@jira_service
.
password
=
'password'
@jira_service
.
save
end
it
'reset password if api url changed'
do
@jira_service
.
api_url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
be_nil
end
it
'does not reset password if url changed'
do
@jira_service
.
url
=
'http://jira_edited.example.com/rweb'
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
eq
(
"password"
)
end
it
'reset password if api url set to ""'
do
@jira_service
.
api_url
=
''
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
be_nil
end
end
it
'does not reset password if username changed'
do
@jira_service
.
username
=
'some_name'
@jira_service
.
save
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
eq
(
"password"
)
expect
(
@jira_service
.
password
).
to
eq
(
'password'
)
end
end
it
"does not reset password if new url is set together with password, even if it's the same password"
do
it
'does not reset password if new url is set together with password, even if it\'s the same password'
do
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
password
=
'password'
@jira_service
.
password
=
'password'
@jira_service
.
save
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
eq
(
"password"
)
expect
(
@jira_service
.
url
).
to
eq
(
"http://jira_edited.example.com/rest/api/2"
)
expect
(
@jira_service
.
password
).
to
eq
(
'password'
)
expect
(
@jira_service
.
url
).
to
eq
(
'http://jira_edited.example.com/rest/api/2'
)
end
end
it
"resets password if url changed, even if setter called multiple times"
do
it
'resets password if url changed, even if setter called multiple times'
do
@jira_service
.
url
=
'http://jira1.example.com/rest/api/2'
@jira_service
.
url
=
'http://jira1.example.com/rest/api/2'
@jira_service
.
url
=
'http://jira1.example.com/rest/api/2'
@jira_service
.
url
=
'http://jira1.example.com/rest/api/2'
@jira_service
.
save
@jira_service
.
save
...
@@ -249,7 +333,7 @@ describe JiraService, models: true do
...
@@ -249,7 +333,7 @@ describe JiraService, models: true do
end
end
end
end
context
"when no password was previously set"
do
context
'when no password was previously set'
do
before
do
before
do
@jira_service
=
JiraService
.
create
(
@jira_service
=
JiraService
.
create
(
project:
project
,
project:
project
,
...
@@ -260,26 +344,16 @@ describe JiraService, models: true do
...
@@ -260,26 +344,16 @@ describe JiraService, models: true do
)
)
end
end
it
"saves password if new url is set together with password"
do
it
'saves password if new url is set together with password'
do
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
url
=
'http://jira_edited.example.com/rest/api/2'
@jira_service
.
password
=
'password'
@jira_service
.
password
=
'password'
@jira_service
.
save
@jira_service
.
save
expect
(
@jira_service
.
password
).
to
eq
(
"password"
)
expect
(
@jira_service
.
password
).
to
eq
(
'password'
)
expect
(
@jira_service
.
url
).
to
eq
(
"http://jira_edited.example.com/rest/api/2"
)
expect
(
@jira_service
.
url
).
to
eq
(
'http://jira_edited.example.com/rest/api/2'
)
end
end
end
end
end
end
describe
"Validations"
do
context
"active"
do
before
do
subject
.
active
=
true
end
it
{
is_expected
.
to
validate_presence_of
:url
}
end
end
describe
'description and title'
do
describe
'description and title'
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
)
}
...
@@ -321,9 +395,10 @@ describe JiraService, models: true do
...
@@ -321,9 +395,10 @@ describe JiraService, models: true do
context
'when gitlab.yml was initialized'
do
context
'when gitlab.yml was initialized'
do
before
do
before
do
settings
=
{
settings
=
{
"jira"
=>
{
'jira'
=>
{
"title"
=>
"Jira"
,
'title'
=>
'Jira'
,
"url"
=>
"http://jira.sample/projects/project_a"
'url'
=>
'http://jira.sample/projects/project_a'
,
'api_url'
=>
'http://jira.sample/api'
}
}
}
}
allow
(
Gitlab
.
config
).
to
receive
(
:issues_tracker
).
and_return
(
settings
)
allow
(
Gitlab
.
config
).
to
receive
(
:issues_tracker
).
and_return
(
settings
)
...
@@ -335,8 +410,9 @@ describe JiraService, models: true do
...
@@ -335,8 +410,9 @@ describe JiraService, models: true do
end
end
it
'is prepopulated with the settings'
do
it
'is prepopulated with the settings'
do
expect
(
@service
.
properties
[
"title"
]).
to
eq
(
'Jira'
)
expect
(
@service
.
properties
[
'title'
]).
to
eq
(
'Jira'
)
expect
(
@service
.
properties
[
"url"
]).
to
eq
(
'http://jira.sample/projects/project_a'
)
expect
(
@service
.
properties
[
'url'
]).
to
eq
(
'http://jira.sample/projects/project_a'
)
expect
(
@service
.
properties
[
'api_url'
]).
to
eq
(
'http://jira.sample/api'
)
end
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment