danger-yajp 0.0.1 → 0.1.3
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 +4 -4
- data/.github/workflows/create-tag.yml +39 -0
- data/.rubocop.yml +1 -0
- data/Gemfile.lock +21 -21
- data/README.md +31 -15
- data/danger-yajp.gemspec +1 -1
- data/lib/yajp/gem_version.rb +1 -1
- data/lib/yajp/issue.rb +50 -0
- data/lib/yajp/plugin.rb +94 -32
- data/spec/support/remotelink.json +1 -0
- data/spec/yajp_spec.rb +54 -12
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b33191a7403d610580966c988913cd164f6eb2fba53b54aabb3bfc30c3d9796
|
4
|
+
data.tar.gz: b57ab4fe9c1a1b37b15647dd2358fd8640904f96801c91d680828a93d0b31779
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0df505bcf5ff1c4eaa239607e4c759a09dc098e477e078b7a622bc58c97db93d7c8b9d61413b2da137cf858890ab450cebe26593bcaf249264d9adfc82c9e3a3
|
7
|
+
data.tar.gz: a2a95d33414764499d4879b52be808547343e3e6478c0f2493efa8d2db89ad91aac3a7f1d21555a88d386e5dfa9de2bc5249b511b37da1dfec05a7a5feeb22bb
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: Create release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: main
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Retrieve version + create release
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
with:
|
15
|
+
fetch-depth: 0
|
16
|
+
|
17
|
+
- name: Set up Ruby 2.6
|
18
|
+
uses: actions/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.6.x
|
21
|
+
|
22
|
+
- name: Retrieve version
|
23
|
+
id: version
|
24
|
+
run: |
|
25
|
+
version=$(ruby -e 'require "./lib/yajp/gem_version.rb"' -e 'puts Yajp::VERSION')
|
26
|
+
echo "TAG_NAME=$version" >> $GITHUB_ENV
|
27
|
+
latest_tag=$(git describe --tags --abbrev=0)
|
28
|
+
echo 'VERSION_DESCRIPTION<<EOF' >> $GITHUB_ENV
|
29
|
+
git log --pretty='format:%h %s' ${latest_tag}..HEAD >> $GITHUB_ENV
|
30
|
+
echo $'\nEOF' >> $GITHUB_ENV
|
31
|
+
|
32
|
+
- name: Create release
|
33
|
+
uses: actions/create-release@v1
|
34
|
+
env:
|
35
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
36
|
+
with:
|
37
|
+
tag_name: ${{ env.TAG_NAME }}
|
38
|
+
release_name: v${{ env.TAG_NAME }}
|
39
|
+
body: ${{ env.VERSION_DESCRIPTION }}
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
danger-yajp (0.
|
4
|
+
danger-yajp (0.1.3)
|
5
5
|
danger-plugin-api
|
6
6
|
jira-ruby
|
7
7
|
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
cork (0.3.0)
|
31
31
|
colored2 (~> 3.1)
|
32
32
|
crack (0.4.4)
|
33
|
-
danger (8.2.
|
33
|
+
danger (8.2.1)
|
34
34
|
claide (~> 1.0)
|
35
35
|
claide-plugins (>= 0.9.2)
|
36
36
|
colored2 (~> 3.1)
|
@@ -82,7 +82,7 @@ GEM
|
|
82
82
|
rexml
|
83
83
|
kramdown-parser-gfm (1.1.0)
|
84
84
|
kramdown (~> 2.0)
|
85
|
-
listen (3.
|
85
|
+
listen (3.3.0)
|
86
86
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
87
87
|
rb-inotify (~> 0.9, >= 0.9.10)
|
88
88
|
lumberjack (1.2.8)
|
@@ -100,7 +100,7 @@ GEM
|
|
100
100
|
faraday (>= 0.9)
|
101
101
|
sawyer (~> 0.8.0, >= 0.5.3)
|
102
102
|
open4 (1.3.4)
|
103
|
-
parallel (1.
|
103
|
+
parallel (1.20.0)
|
104
104
|
parser (2.7.2.0)
|
105
105
|
ast (~> 2.4.1)
|
106
106
|
pry (0.13.1)
|
@@ -115,29 +115,29 @@ GEM
|
|
115
115
|
rchardet (1.8.0)
|
116
116
|
regexp_parser (1.8.2)
|
117
117
|
rexml (3.2.4)
|
118
|
-
rspec (3.
|
119
|
-
rspec-core (~> 3.
|
120
|
-
rspec-expectations (~> 3.
|
121
|
-
rspec-mocks (~> 3.
|
122
|
-
rspec-core (3.
|
123
|
-
rspec-support (~> 3.
|
124
|
-
rspec-expectations (3.
|
118
|
+
rspec (3.10.0)
|
119
|
+
rspec-core (~> 3.10.0)
|
120
|
+
rspec-expectations (~> 3.10.0)
|
121
|
+
rspec-mocks (~> 3.10.0)
|
122
|
+
rspec-core (3.10.0)
|
123
|
+
rspec-support (~> 3.10.0)
|
124
|
+
rspec-expectations (3.10.0)
|
125
125
|
diff-lcs (>= 1.2.0, < 2.0)
|
126
|
-
rspec-support (~> 3.
|
127
|
-
rspec-mocks (3.
|
126
|
+
rspec-support (~> 3.10.0)
|
127
|
+
rspec-mocks (3.10.0)
|
128
128
|
diff-lcs (>= 1.2.0, < 2.0)
|
129
|
-
rspec-support (~> 3.
|
130
|
-
rspec-support (3.
|
131
|
-
rubocop (1.
|
129
|
+
rspec-support (~> 3.10.0)
|
130
|
+
rspec-support (3.10.0)
|
131
|
+
rubocop (1.3.0)
|
132
132
|
parallel (~> 1.10)
|
133
133
|
parser (>= 2.7.1.5)
|
134
134
|
rainbow (>= 2.2.2, < 4.0)
|
135
135
|
regexp_parser (>= 1.8)
|
136
136
|
rexml
|
137
|
-
rubocop-ast (>=
|
137
|
+
rubocop-ast (>= 1.1.1)
|
138
138
|
ruby-progressbar (~> 1.7)
|
139
139
|
unicode-display_width (>= 1.4.0, < 2.0)
|
140
|
-
rubocop-ast (1.1.
|
140
|
+
rubocop-ast (1.1.1)
|
141
141
|
parser (>= 2.7.1.5)
|
142
142
|
ruby-progressbar (1.10.1)
|
143
143
|
ruby2_keywords (0.0.2)
|
@@ -149,10 +149,10 @@ GEM
|
|
149
149
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
150
150
|
thor (1.0.1)
|
151
151
|
thread_safe (0.3.6)
|
152
|
-
tzinfo (1.2.
|
152
|
+
tzinfo (1.2.8)
|
153
153
|
thread_safe (~> 0.1)
|
154
154
|
unicode-display_width (1.7.0)
|
155
|
-
webmock (3.
|
155
|
+
webmock (3.10.0)
|
156
156
|
addressable (>= 2.3.6)
|
157
157
|
crack (>= 0.3.2)
|
158
158
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -170,7 +170,7 @@ DEPENDENCIES
|
|
170
170
|
pry
|
171
171
|
rake (~> 13.0)
|
172
172
|
rspec (~> 3.9)
|
173
|
-
rubocop (
|
173
|
+
rubocop (>= 1.0.0)
|
174
174
|
webmock (~> 3.9)
|
175
175
|
yard (~> 0.9.11)
|
176
176
|
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Yet Another Jira Plugin
|
2
2
|
|
3
|
-
[](LICENSE)
|
4
|
+
[](https://rubygems.org/gems/danger-yajp)
|
5
|
+
[](https://libraries.io/rubygems/danger-yajp)
|
4
6
|
|
5
|
-
Yet Another Jira Plugin (in short: yajp) is a [Danger](https://danger.systems/ruby/) plugin that provides methods to easily find and manipulate issues from within the Dangerfile. The major difference with the existing Jira plugins is the ability to transition and update issues with the same feeling as manipulating PR data from Danger. This plugin was build in the same mind as Danger, meaning that you will find methods to easily manipulate Jira data, but no predefined warning and/or message.
|
7
|
+
Yet Another Jira Plugin (in short: yajp) is a [Danger](https://danger.systems/ruby/) plugin that provides methods to easily find and manipulate issues from within the Dangerfile. The major difference with the existing Jira plugins is the ability to transition and update issues with the same feeling as manipulating PR data from Danger. This plugin was build in the same mind as Danger, meaning that you will find methods to easily manipulate Jira data, but no predefined warning and/or message. It also does that by expanding the Issue class from `jira-ruby`.
|
6
8
|
|
7
9
|
Inspired by [danger-jira](https://github.com/RestlessThinker/danger-jira), from which I borrowed the issue search, and by [danger-jira_sync](https://github.com/roverdotcom/danger-jira_sync) for their usage of the awesome [jira-ruby](https://github.com/sumoheavy/jira-ruby) gem.
|
8
10
|
|
@@ -16,12 +18,12 @@ gem 'danger-yajp'
|
|
16
18
|
|
17
19
|
## Usage
|
18
20
|
|
19
|
-
You first need to define the environment variables `DANGER_JIRA_URL`, `DANGER_JIRA_USER` and `
|
21
|
+
You first need to define the environment variables `DANGER_JIRA_URL`, `DANGER_JIRA_USER` and `DANGER_JIRA_API_TOKEN` in your CI environment, for example:
|
20
22
|
|
21
23
|
```
|
22
24
|
DANGER_JIRA_URL: https://jira.company.com/jira
|
23
25
|
DANGER_JIRA_USER: username
|
24
|
-
|
26
|
+
DANGER_JIRA_API_TOKEN: abcd12345
|
25
27
|
```
|
26
28
|
|
27
29
|
### Find issues
|
@@ -43,26 +45,40 @@ end
|
|
43
45
|
|
44
46
|
### Transition / update issues
|
45
47
|
|
46
|
-
yajp allows to easily transition and update issues without the hassle of building custom json in the Dangerfile. The inputs are:
|
48
|
+
yajp allows to easily transition and update issues without the hassle of building custom json in the Dangerfile. The methods are available in the issue object, or to handle multiple issues in the plugin object. The inputs are:
|
47
49
|
|
48
|
-
* An issue (from `jira-ruby`) or an array of issues
|
49
50
|
* For the transition action, the ID of the transition
|
50
|
-
*
|
51
|
+
* When using the methods from the plugin object, the issues to handled, which is by default the issues found when the command `find_issues` was last run.
|
52
|
+
* Any number of fields to be updated in a hash: `key: value`
|
51
53
|
|
54
|
+
Example 1: transition all the issues found after running `find_issues`:
|
52
55
|
```rb
|
53
|
-
jira.
|
56
|
+
jira.transition_all(10, assignee: { name: 'username' }, customfield_11005: 'example')
|
54
57
|
```
|
55
58
|
|
56
|
-
|
59
|
+
Example 2: update a single issue:
|
60
|
+
```rb
|
61
|
+
issue.update(assignee: { name: 'username' }, customfield_11005: 'example')
|
62
|
+
```
|
63
|
+
|
64
|
+
The `transition` and `transition_all` methods only take fields available in the transition screen. Use the `split_transition_fields` method to separate the fields available in the transition screen, or use the `transition_and_update_all` method to transition and update issues (and automatically dispatch the fields to the correct action).
|
57
65
|
|
58
66
|
> Transition IDs can be found in Jira under Project Workflow > Edit Workflow in Text Mode.
|
59
67
|
|
68
|
+
### Reference the PR as a remote link
|
69
|
+
|
70
|
+
yajp can reference the PR as a remote link on Jira. It will use the icon of GitLab or Github depending on what you use. The remote link will use the URL of the PR as a `globalId` to not create duplicates. Optionnaly, you can specify the relationship with the issue (default is `relates to`), and the status, either as an object (eg. `{ "resolved": true, "icon": {...} }`) or as a boolean that will set the value of the property `resolved`. By default, no status is sent.
|
71
|
+
|
72
|
+
```rb
|
73
|
+
jira.pr_as_remotelink(issue, false)
|
74
|
+
```
|
75
|
+
|
60
76
|
### Issue URL
|
61
77
|
|
62
|
-
Use `
|
78
|
+
Use `link` to retrieve the browse URL of the Jira issue.
|
63
79
|
|
64
80
|
```rb
|
65
|
-
message "<a href='#{
|
81
|
+
message "<a href='#{issue.link}'>#{issue.key} - #{issue.summary}</a>"
|
66
82
|
```
|
67
83
|
|
68
84
|
### API
|
@@ -82,13 +98,13 @@ if issues.empty?
|
|
82
98
|
warn 'This PR does not contain any Jira issue.'
|
83
99
|
else
|
84
100
|
issues.each do |issue|
|
85
|
-
message "<a href='#{
|
101
|
+
message "<a href='#{issue.link}'>#{issue.key} - #{issue.summary}</a>"
|
86
102
|
|
87
|
-
case issue.status
|
103
|
+
case issue.status.name
|
88
104
|
when 'In Progress'
|
89
|
-
jira.
|
105
|
+
jira.transition_and_update_all(10, issue: issue, assignee: { name: 'username' }, customfield_11005: 'example')
|
90
106
|
when 'To Do', 'Blocked'
|
91
|
-
warn "Issue <a href='#{
|
107
|
+
warn "Issue <a href='#{issue.link}'>#{issue.key}</a> is not in Dev status, please make sure the issue you're working on is in the correct status"
|
92
108
|
end
|
93
109
|
end
|
94
110
|
end
|
data/danger-yajp.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'webmock', '~> 3.9'
|
34
34
|
|
35
35
|
# Linting code and docs
|
36
|
-
spec.add_development_dependency 'rubocop', '
|
36
|
+
spec.add_development_dependency 'rubocop', '>= 1.0.0'
|
37
37
|
spec.add_development_dependency 'yard', '~> 0.9.11'
|
38
38
|
|
39
39
|
# Makes testing easy via `bundle exec guard`
|
data/lib/yajp/gem_version.rb
CHANGED
data/lib/yajp/issue.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jira-ruby'
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
# This class extends (aka monkey patch) the `JIRA::Resource::Issue` class with straightforward methods to easily transition and update issues.
|
7
|
+
#
|
8
|
+
class JIRA::Resource::Issue
|
9
|
+
# Get the browse URL of the issue.
|
10
|
+
#
|
11
|
+
# @return [String] the URL of the issue
|
12
|
+
#
|
13
|
+
def link
|
14
|
+
"#{ENV['DANGER_JIRA_URL']}/browse/#{key}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Update the issue.
|
18
|
+
#
|
19
|
+
# @example Update the fields `assignee` and `customfield_11005`
|
20
|
+
# issue.update(assignee: { name: 'username' }, customfield_11005: 'example')
|
21
|
+
#
|
22
|
+
# @param [Hash] fields Fields to update
|
23
|
+
#
|
24
|
+
# @return [Boolean] `true` if the issue was updated successfully, `false` otherwise.
|
25
|
+
#
|
26
|
+
def update(**fields)
|
27
|
+
return if fields.empty?
|
28
|
+
|
29
|
+
save({ fields: fields })
|
30
|
+
end
|
31
|
+
|
32
|
+
# Transition the issue using the ID of the transition. Transition IDs can be found in Jira under Project Workflow > Edit Workflow in Text Mode.
|
33
|
+
# The fields that can be updated with this method are only the fields available in the transition screen of the transition. Otherwise use `transition_and_update`.
|
34
|
+
#
|
35
|
+
# @example Transition the issue and set the fields `assignee` and `customfield_11005` available on the transition screens
|
36
|
+
# jira.transition(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
|
37
|
+
#
|
38
|
+
# @param [Integer] transition_id
|
39
|
+
# @param [Hash] fields Fields that can be updated on the transition screen
|
40
|
+
#
|
41
|
+
# @return [Boolean] `true` if the issue was transitioned successfully, `false` otherwise.
|
42
|
+
#
|
43
|
+
def transition(transition_id, **fields)
|
44
|
+
data = { transition: { id: transition_id.to_s } }
|
45
|
+
data[:fields] = fields unless fields.empty?
|
46
|
+
|
47
|
+
transitions.build.save(data)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/yajp/plugin.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'issue'
|
4
4
|
|
5
5
|
module Danger
|
6
6
|
# Yet Another Jira Plugin (in short: yajp) provides methods to easily find and manipulate issues from within the Dangerfile.
|
@@ -18,13 +18,13 @@ module Danger
|
|
18
18
|
# warn 'This PR does not contain any Jira issue.'
|
19
19
|
# else
|
20
20
|
# issues.each do |issue|
|
21
|
-
# message "<a href='#{
|
21
|
+
# message "<a href='#{issue.link}'>#{issue.key} - #{issue.summary}</a>"
|
22
22
|
#
|
23
|
-
# case issue.status
|
23
|
+
# case issue.status.name
|
24
24
|
# when 'In Progress'
|
25
|
-
#
|
25
|
+
# issue.transition(10, assignee: { name: 'username' }, customfield_11005: 'example')
|
26
26
|
# when 'To Do', 'Blocked'
|
27
|
-
# warn "Issue <a href='#{
|
27
|
+
# warn "Issue <a href='#{issue.link}'>#{issue.key}</a> is not in Dev status, please make sure the issue you're working on is in the correct status"
|
28
28
|
# end
|
29
29
|
# end
|
30
30
|
# end
|
@@ -69,11 +69,11 @@ module Danger
|
|
69
69
|
# jira.find_issues('KEY', search_title: false, search_branch: true)
|
70
70
|
#
|
71
71
|
# @param [Array<String>] key An array of Jira project keys like `['KEY', 'JIRA']`, or a single `String` with a Jira project key
|
72
|
-
# @param [Boolean] search_title Option to search Jira issues from PR title
|
73
|
-
# @param [Boolean] search_commits Option to search Jira issues from from commit messages
|
74
|
-
# @param [Boolean] search_branch Option to search Jira issues from the name of the PR branch
|
72
|
+
# @param [Boolean] search_title Option to search Jira issues from PR title
|
73
|
+
# @param [Boolean] search_commits Option to search Jira issues from from commit messages
|
74
|
+
# @param [Boolean] search_branch Option to search Jira issues from the name of the PR branch
|
75
75
|
#
|
76
|
-
# @return [Array<JIRA::Issue>] An array containing all the unique issues found in the PR.
|
76
|
+
# @return [Array<JIRA::Resource::Issue>] An array containing all the unique issues found in the PR.
|
77
77
|
#
|
78
78
|
def find_issues(key, search_title: true, search_commits: false, search_branch: false)
|
79
79
|
regexp = build_regexp_from_key(key)
|
@@ -84,29 +84,27 @@ module Danger
|
|
84
84
|
jira_issues.concat(search_branch(regexp)) if search_branch
|
85
85
|
jira_issues.concat(search_pr_body(regexp)) if jira_issues.empty?
|
86
86
|
|
87
|
-
jira_issues.uniq.map { |issue_key| @api.Issue.find(issue_key) }
|
87
|
+
@issues = jira_issues.uniq(&:downcase).map { |issue_key| @api.Issue.find(issue_key) }
|
88
88
|
end
|
89
89
|
|
90
90
|
# Transition the given Jira issue(s) using the ID of the transition. Transition IDs can be found in Jira under Project Workflow > Edit Workflow in Text Mode.
|
91
91
|
# The fields that can be updated with this method are only the fields available in the transition screen of the transition. Otherwise use `transition_and_update`.
|
92
92
|
#
|
93
93
|
# @example Transition the issue `my_issue` and set the fields `assignee` and `customfield_11005` available on the transition screens
|
94
|
-
# jira.
|
94
|
+
# jira.transition_all(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
|
95
95
|
#
|
96
|
-
# @param [Array<JIRA::Issue>] issue An array of issues, or a single `JIRA::Issue`
|
97
96
|
# @param [Integer] transition_id
|
97
|
+
# @param [Array<JIRA::Resource::Issue>, JIRA::Resource::Issue] issue An array of issues, or a single issue
|
98
98
|
# @param [Hash] fields Fields that can be updated on the transition screen
|
99
99
|
#
|
100
100
|
# @return [Boolean] `true` if all the issues were transitioned successfully, `false` otherwise.
|
101
101
|
#
|
102
|
-
def
|
102
|
+
def transition_all(transition_id, issue: @issues, **fields)
|
103
103
|
issues = issue.kind_of?(Array) ? issue : [] << issue
|
104
|
-
data = { transition: { id: transition_id.to_s } }
|
105
|
-
data[:fields] = fields unless fields.empty?
|
106
104
|
result = true
|
107
105
|
|
108
106
|
issues.each do |key|
|
109
|
-
result &= key.
|
107
|
+
result &= key.transition(transition_id, **fields)
|
110
108
|
end
|
111
109
|
|
112
110
|
return result
|
@@ -115,27 +113,29 @@ module Danger
|
|
115
113
|
# Update the given Jira issue(s).
|
116
114
|
#
|
117
115
|
# @example Update the issue `my_issue` and set the fields `assignee` and `customfield_11005`
|
118
|
-
# jira.
|
116
|
+
# jira.update_all(my_issue, assignee: { name: 'username' }, customfield_11005: 'example')
|
119
117
|
#
|
120
|
-
# @param [Array<JIRA::Issue
|
118
|
+
# @param [Array<JIRA::Resource::Issue>, JIRA::Resource::Issue] issue An array of issue, or a single issue
|
121
119
|
# @param [Hash] fields Fields to update
|
122
120
|
#
|
123
121
|
# @return [Boolean] `true` if all the issues were updated successfully, `false` otherwise.
|
124
122
|
#
|
125
|
-
def
|
123
|
+
def update_all(issue: @issues, **fields)
|
126
124
|
return if fields.empty?
|
127
125
|
|
128
126
|
issues = issue.kind_of?(Array) ? issue : [] << issue
|
129
127
|
result = true
|
130
128
|
|
131
129
|
issues.each do |key|
|
132
|
-
result &= key.
|
130
|
+
result &= key.update(**fields)
|
133
131
|
end
|
132
|
+
|
133
|
+
return result
|
134
134
|
end
|
135
135
|
|
136
136
|
# Utility to split the given fields into fields that can be updated on the transition screen corresponding to the `transition_id` of the given `issue`.
|
137
137
|
#
|
138
|
-
# @param [JIRA::Issue] issue
|
138
|
+
# @param [JIRA::Resource::Issue] issue
|
139
139
|
# @param [Integer] transition_id
|
140
140
|
# @param [Hash] fields Fields to split
|
141
141
|
#
|
@@ -159,33 +159,77 @@ module Danger
|
|
159
159
|
# and use the other fields with the update action.
|
160
160
|
#
|
161
161
|
# @example Transition the issue `my_issue` and set the fields `assignee` and `customfield_11005`
|
162
|
-
# jira.
|
162
|
+
# jira.transition_and_update_all(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
|
163
163
|
#
|
164
|
-
# @param [Array<JIRA::Issue>] issue An array of issues, or a single `JIRA::Issue`
|
165
164
|
# @param [Integer] transition_id
|
165
|
+
# @param [Array<JIRA::Resource::Issue>, JIRA::Resource::Issue] issue An array of issues, or a single issue
|
166
166
|
# @param [Hash] fields Fields to update
|
167
167
|
#
|
168
168
|
# @return [Boolean] `true` if all the issues were transitioned and updated successfully, `false` otherwise.
|
169
169
|
#
|
170
|
-
def
|
170
|
+
def transition_and_update_all(transition_id, issue: @issues, **fields)
|
171
171
|
issues = issue.kind_of?(Array) ? issue : [] << issue
|
172
172
|
result = issues.first.split_transition_fields(transition_id, fields)
|
173
173
|
transition_fields = result[:transition_fields]
|
174
174
|
fields = result[:other_fields]
|
175
175
|
|
176
|
-
result = transition(
|
177
|
-
result & update(issues, **fields)
|
176
|
+
result = transition(transition_id, issue: issues, **transition_fields)
|
177
|
+
result & update(issue: issues, **fields)
|
178
178
|
end
|
179
179
|
|
180
|
-
#
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
180
|
+
# @deprecated Please use the new #{transition_and_update_all} method
|
181
|
+
def transition_and_update(issue, transition_id, **fields)
|
182
|
+
Warning.warn('Deprecated use of the transition_and_update method, please use the new method definition')
|
183
|
+
transition_and_update_all(transition_id, issue: issue, **fields)
|
184
|
+
end
|
185
|
+
|
186
|
+
# @deprecated Please use the new #{update_all} method
|
187
|
+
def update(issue, **fields)
|
188
|
+
Warning.warn('Deprecated use of the update method, please use the new method definition')
|
189
|
+
update_all(issue: issue, **fields)
|
190
|
+
end
|
191
|
+
|
192
|
+
# @deprecated Please use the new #{transition_all} method
|
193
|
+
def transition(issue, transition_id, **fields)
|
194
|
+
Warning.warn('Deprecated use of the transition method, please use the new method definition')
|
195
|
+
transition_all(transition_id, issue: issue, **fields)
|
196
|
+
end
|
197
|
+
|
198
|
+
# @deprecated Please use the method available on the issue directly [#JIRA::Resource::Issue.link]
|
185
199
|
def issue_link(issue)
|
200
|
+
Warning.warn('Deprecated use of the issue_link method, please use the same method available in the Issue class')
|
186
201
|
"#{ENV['DANGER_JIRA_URL']}/browse/#{issue.key}"
|
187
202
|
end
|
188
203
|
|
204
|
+
# Add a remote link to the PR in the given Jira issues. It uses the link of the PR as the `globalId` of the remote link, thus avoiding to create duplicates each time the PR is updated.
|
205
|
+
#
|
206
|
+
# @param [Array<JIRA::Resource::Issue>, JIRA::Resource::Issue] issue An array of issues, or a single issue
|
207
|
+
# @param [<String>] relation Option to set the relationship of the remote link
|
208
|
+
# @param [<Hash>, <Boolean>] status Option to set the status property of the remote link, it can be <Hash> or a <Boolean> that will set the value of the property `resolved`
|
209
|
+
#
|
210
|
+
# @return [Boolean] `true` if all the remote links were added successfully, `false` otherwise.
|
211
|
+
#
|
212
|
+
def pr_as_remotelink(issue, relation: 'relates to', status: nil)
|
213
|
+
issues = issue.kind_of?(Array) ? issue : [] << issue
|
214
|
+
result = true
|
215
|
+
|
216
|
+
remote_link_prop = { object: { url: pr_link, title: vcs_host.pr_title, icon: link_icon } }
|
217
|
+
remote_link_prop[:globalId] = pr_link
|
218
|
+
remote_link_prop[:relationship] = relation
|
219
|
+
|
220
|
+
if status.kind_of?(Hash)
|
221
|
+
remote_link_prop[:object][:status] = status
|
222
|
+
elsif !status.nil?
|
223
|
+
remote_link_prop[:object][:status] = { resolved: status }
|
224
|
+
end
|
225
|
+
|
226
|
+
issues.each do |key|
|
227
|
+
result &= key.remotelink.build.save(remote_link_prop)
|
228
|
+
end
|
229
|
+
|
230
|
+
return result
|
231
|
+
end
|
232
|
+
|
189
233
|
private
|
190
234
|
|
191
235
|
def vcs_host
|
@@ -194,9 +238,27 @@ module Danger
|
|
194
238
|
github
|
195
239
|
end
|
196
240
|
|
241
|
+
def pr_link
|
242
|
+
return @pr_link unless @pr_link.nil?
|
243
|
+
|
244
|
+
if defined? @dangerfile.gitlab
|
245
|
+
@pr_link = vcs_host.pr_json['web_url']
|
246
|
+
else
|
247
|
+
@pr_link = vcs_host.pr_json['html_url']
|
248
|
+
end
|
249
|
+
|
250
|
+
return @pr_link
|
251
|
+
end
|
252
|
+
|
253
|
+
def link_icon
|
254
|
+
return { title: 'Gitlab', url16x16: 'https://gitlab.com/favicon.ico' } if defined? @dangerfile.gitlab
|
255
|
+
|
256
|
+
{ title: 'Github', url16x16: 'https://github.com/favicon.ico' }
|
257
|
+
end
|
258
|
+
|
197
259
|
def build_regexp_from_key(key)
|
198
260
|
keys = key.kind_of?(Array) ? key.join('|') : key
|
199
|
-
return /((?:#{keys})-[0-9]+)/
|
261
|
+
return /((?:#{keys})-[0-9]+)/i
|
200
262
|
end
|
201
263
|
|
202
264
|
def search_title(regexp)
|
@@ -0,0 +1 @@
|
|
1
|
+
{"object":{"url":"https://github.com/test/pull/1234","title":"PR Title","icon":{"title":"Github","url16x16":"https://github.com/favicon.ico"},"status":{"resolved":true}},"globalId":"https://github.com/test/pull/1234","relationship":"relates to"}
|
data/spec/yajp_spec.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'spec_helper'
|
4
4
|
|
5
|
+
# rubocop:disable Metrics/ModuleLength
|
5
6
|
module Danger
|
6
7
|
describe Danger::DangerYajp do
|
8
|
+
before do
|
9
|
+
ENV['DANGER_JIRA_URL'] = 'https://jira.company.com/jira'
|
10
|
+
ENV['DANGER_JIRA_USER'] = 'username'
|
11
|
+
ENV['DANGER_JIRA_PASSWORD'] = 'password'
|
12
|
+
end
|
13
|
+
|
7
14
|
it 'should be a plugin' do
|
8
15
|
expect(Danger::DangerYajp.new(nil)).to be_a Danger::Plugin
|
9
16
|
end
|
@@ -13,9 +20,6 @@ module Danger
|
|
13
20
|
let(:plugin) { dangerfile.jira }
|
14
21
|
|
15
22
|
before do
|
16
|
-
ENV['DANGER_JIRA_URL'] = 'https://jira.company.com/jira'
|
17
|
-
ENV['DANGER_JIRA_USER'] = 'username'
|
18
|
-
ENV['DANGER_JIRA_PASSWORD'] = 'password'
|
19
23
|
DangerYajp.send(:public, *DangerYajp.private_instance_methods)
|
20
24
|
end
|
21
25
|
|
@@ -43,9 +47,9 @@ module Danger
|
|
43
47
|
end
|
44
48
|
|
45
49
|
it 'can find jira issues via branch name' do
|
46
|
-
allow(plugin).to receive_message_chain('github.branch_for_head').and_return('bugfix/
|
50
|
+
allow(plugin).to receive_message_chain('github.branch_for_head').and_return('bugfix/web-126')
|
47
51
|
issues = plugin.search_branch(plugin.build_regexp_from_key('WEB'))
|
48
|
-
expect(issues).to eq(['
|
52
|
+
expect(issues).to eq(['web-126'])
|
49
53
|
end
|
50
54
|
|
51
55
|
it 'can find jira issues in pr body' do
|
@@ -58,17 +62,19 @@ module Danger
|
|
58
62
|
issue = Object.new
|
59
63
|
|
60
64
|
def issue.find(key)
|
61
|
-
|
65
|
+
# The find method in jira-ruby plugin is not case sensitive, hence the upcase.
|
66
|
+
return key.upcase
|
62
67
|
end
|
63
68
|
|
64
69
|
allow_any_instance_of(JIRA::Client).to receive(:Issue).and_return(issue)
|
65
70
|
|
66
71
|
allow(plugin).to receive_message_chain('github.pr_title').and_return('Fix for WEB-128 and WEB-129')
|
67
|
-
allow(plugin).to receive_message_chain('github.branch_for_head').and_return('bugfix/
|
72
|
+
allow(plugin).to receive_message_chain('github.branch_for_head').and_return('bugfix/web-128')
|
68
73
|
issues = plugin.find_issues('WEB', search_branch: true)
|
69
74
|
expect(issues).to eq(['WEB-128', 'WEB-129'])
|
70
75
|
end
|
71
76
|
|
77
|
+
# rubocop:disable Naming/VariableNumber
|
72
78
|
it 'can split transition field from other fields' do
|
73
79
|
json = File.read("#{File.dirname(__FILE__)}/support/transitions.all.json")
|
74
80
|
url = "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/WEB-130/transitions"
|
@@ -86,16 +92,52 @@ module Danger
|
|
86
92
|
|
87
93
|
it 'can transition an issue' do
|
88
94
|
expected_json = '{"transition":{"id":"2"},"fields":{"assignee":{"name":"username"},"customfield_11005":"example"}}'
|
89
|
-
|
90
|
-
|
95
|
+
issue_id = Random.rand(1000)
|
96
|
+
url = "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/#{issue_id}/transitions"
|
97
|
+
issue = plugin.api.Issue.build({ 'id' => issue_id, 'key' => 'WEB-131' })
|
91
98
|
|
92
|
-
allow(issue).to receive(:key_value).and_return('WEB-131')
|
93
99
|
stub = stub_request(:post, url).
|
94
100
|
with(body: expected_json)
|
95
|
-
plugin.
|
101
|
+
result = plugin.transition_all(2, issue: issue, assignee: { name: 'username' }, customfield_11005: 'example')
|
102
|
+
|
103
|
+
expect(stub).to have_been_requested.once
|
104
|
+
expect(result).to be true
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'can update issues' do
|
108
|
+
expected_json = '{"fields":{"assignee":{"name":"username"},"customfield_11005":"example"}}'
|
109
|
+
uri_template = Addressable::Template.new "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/{issue}"
|
110
|
+
issue1 = plugin.api.Issue.build({ 'id' => Random.rand(1000), 'self' => "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/WEB-132", 'key' => 'WEB-132' })
|
111
|
+
issue2 = plugin.api.Issue.build({ 'id' => Random.rand(1000), 'self' => "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/WEB-133", 'key' => 'WEB-133' })
|
112
|
+
|
113
|
+
stub = stub_request(:put, uri_template).
|
114
|
+
with(body: expected_json)
|
115
|
+
result = plugin.update_all(issue: [issue1, issue2], assignee: { name: 'username' }, customfield_11005: 'example')
|
116
|
+
|
117
|
+
expect(stub).to have_been_requested.twice
|
118
|
+
expect(result).to be true
|
119
|
+
end
|
120
|
+
# rubocop:enable Naming/VariableNumber
|
121
|
+
|
122
|
+
it 'can add remote link' do
|
123
|
+
pr_title = 'PR Title'
|
124
|
+
pr_json = { 'html_url' => 'https://github.com/test/pull/1234' }
|
125
|
+
url = "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/WEB-134/remotelink"
|
126
|
+
json = File.read("#{File.dirname(__FILE__)}/support/remotelink.json")
|
127
|
+
issue = plugin.api.Issue.build
|
128
|
+
|
129
|
+
allow(issue).to receive(:key_value).and_return('WEB-134')
|
130
|
+
allow(dangerfile.github).to receive(:pr_json).and_return(pr_json)
|
131
|
+
allow(dangerfile.github).to receive(:pr_title).and_return(pr_title)
|
132
|
+
|
133
|
+
stub = stub_request(:post, url).
|
134
|
+
with(body: json)
|
135
|
+
result = plugin.pr_as_remotelink(issue, status: true)
|
96
136
|
|
97
137
|
expect(stub).to have_been_requested.once
|
138
|
+
expect(result).to be true
|
98
139
|
end
|
99
140
|
end
|
100
141
|
end
|
101
142
|
end
|
143
|
+
# rubocop:enable Metrics/ModuleLength
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger-yajp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- juliendms
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger-plugin-api
|
@@ -98,14 +98,14 @@ dependencies:
|
|
98
98
|
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 1.0.0
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.0.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
@@ -171,6 +171,7 @@ executables: []
|
|
171
171
|
extensions: []
|
172
172
|
extra_rdoc_files: []
|
173
173
|
files:
|
174
|
+
- ".github/workflows/create-tag.yml"
|
174
175
|
- ".github/workflows/gem-push.yml"
|
175
176
|
- ".gitignore"
|
176
177
|
- ".rubocop.yml"
|
@@ -185,8 +186,10 @@ files:
|
|
185
186
|
- lib/danger_plugin.rb
|
186
187
|
- lib/danger_yajp.rb
|
187
188
|
- lib/yajp/gem_version.rb
|
189
|
+
- lib/yajp/issue.rb
|
188
190
|
- lib/yajp/plugin.rb
|
189
191
|
- spec/spec_helper.rb
|
192
|
+
- spec/support/remotelink.json
|
190
193
|
- spec/support/transitions.all.json
|
191
194
|
- spec/yajp_spec.rb
|
192
195
|
homepage: https://github.com/juliendms/danger-yajp
|
@@ -215,5 +218,6 @@ summary: Yet Another Jira Plugin is a danger plugin to find issues, access their
|
|
215
218
|
and perform operations on them.
|
216
219
|
test_files:
|
217
220
|
- spec/spec_helper.rb
|
221
|
+
- spec/support/remotelink.json
|
218
222
|
- spec/support/transitions.all.json
|
219
223
|
- spec/yajp_spec.rb
|