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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66916c1769e7fecc6c05f5eb549e5775ae7bc8a98eac77bcf0efa727fdc5ec13
4
- data.tar.gz: 24cca5f396eda224b143d326a152960a6dab5281634f02891d51ed0dfedfc97e
3
+ metadata.gz: 2b33191a7403d610580966c988913cd164f6eb2fba53b54aabb3bfc30c3d9796
4
+ data.tar.gz: b57ab4fe9c1a1b37b15647dd2358fd8640904f96801c91d680828a93d0b31779
5
5
  SHA512:
6
- metadata.gz: 622b3ed1ff1e2168b1666861adfc20255a83573166a38ccf4edb352b9eaaf5e8d83e7eea900a3ce1d6e5954312ea3c6352ef89b23666b6b2f222c4079eaf5c9a
7
- data.tar.gz: 5efc4d116c9c8e053c89086bde433515e09cfa11da105fe48f51ec76da0280281b90caefd8e7bb79a5c8da7e6590e47df3b66e5714dd2883af187f47fbc36740
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 }}
@@ -4,6 +4,7 @@
4
4
 
5
5
  AllCops:
6
6
  TargetRubyVersion: 2.6
7
+ NewCops: enable
7
8
 
8
9
  Style/StringLiterals:
9
10
  EnforcedStyle: single_quotes
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- danger-yajp (0.0.1)
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.0)
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.2.1)
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.19.2)
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.9.0)
119
- rspec-core (~> 3.9.0)
120
- rspec-expectations (~> 3.9.0)
121
- rspec-mocks (~> 3.9.0)
122
- rspec-core (3.9.3)
123
- rspec-support (~> 3.9.3)
124
- rspec-expectations (3.9.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.9.0)
127
- rspec-mocks (3.9.1)
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.9.0)
130
- rspec-support (3.9.4)
131
- rubocop (1.0.0)
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 (>= 0.6.0)
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.0)
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.7)
152
+ tzinfo (1.2.8)
153
153
  thread_safe (~> 0.1)
154
154
  unicode-display_width (1.7.0)
155
- webmock (3.9.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 (~> 1.0.0)
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](http://img.shields.io/badge/license-MIT-green.svg?style=flat)](LICENSE)
3
+ [![License](https://img.shields.io/github/license/juliendms/danger-yajp)](LICENSE)
4
+ [![Gem](https://img.shields.io/gem/v/danger-yajp)](https://rubygems.org/gems/danger-yajp)
5
+ [![Dependencies](https://img.shields.io/librariesio/release/rubygems/danger-yajp)](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 `DANGER_JIRA_PASSWORD` in your CI environment, for example:
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
- DANGER_JIRA_PASSWORD: abcd12345
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
- * Any number of fields to be updated in the form: `key: value`
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.transition(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
56
+ jira.transition_all(10, assignee: { name: 'username' }, customfield_11005: 'example')
54
57
  ```
55
58
 
56
- The `transition` method only takes 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` method to transition and update issues (and automatically dispatch the fields to the correct action).
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 `issue_link` to retrieve the browse URL of the Jira issue.
78
+ Use `link` to retrieve the browse URL of the Jira issue.
63
79
 
64
80
  ```rb
65
- message "<a href='#{jira.issue_link(issue)}'>#{issue.key} - #{issue.summary}</a>"
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='#{jira.issue_link(issue)}'>#{issue.key} - #{issue.summary}</a>"
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.transition_and_update(issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
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='#{jira.issue_link(issue)}'>#{issue.key}</a> is not in Dev status, please make sure the issue you're working on is in the correct status"
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
@@ -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', '~> 1.0.0'
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`
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yajp
4
- VERSION = '0.0.1'
4
+ VERSION = '0.1.3'
5
5
  end
@@ -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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'jira-ruby'
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='#{jira.issue_link(issue)}'>#{issue.key} - #{issue.summary}</a>"
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
- # jira.transition_and_update(issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
25
+ # issue.transition(10, assignee: { name: 'username' }, customfield_11005: 'example')
26
26
  # when 'To Do', 'Blocked'
27
- # warn "Issue <a href='#{jira.issue_link(issue)}'>#{issue.key}</a> is not in Dev status, please make sure the issue you're working on is in the correct status"
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, default `true`
73
- # @param [Boolean] search_commits Option to search Jira issues from from commit messages, default `false`
74
- # @param [Boolean] search_branch Option to search Jira issues from the name of the PR branch, default `false`
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.transition(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
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 transition(issue, transition_id, **fields)
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.transitions.build.save(data)
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.update(my_issue, assignee: { name: 'username' }, customfield_11005: 'example')
116
+ # jira.update_all(my_issue, assignee: { name: 'username' }, customfield_11005: 'example')
119
117
  #
120
- # @param [Array<JIRA::Issue>] issue An array of issue, or a single `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 update(issue, **fields)
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.save(fields)
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.transition_and_update(my_issue, 10, assignee: { name: 'username' }, customfield_11005: 'example')
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 transition_and_update(issue, transition_id, **fields)
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(issues, transition_id, **transition_fields)
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
- # Get the browse URL of a Jira issue.
181
- #
182
- # @param [JIRA::Issue] issue
183
- #
184
- # @return [String] the URL of the issue
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"}
@@ -1,9 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('spec_helper', __dir__)
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/WEB-126')
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(['WEB-126'])
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
- return key
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/WEB-128')
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
- url = "#{ENV['DANGER_JIRA_URL']}/rest/api/2/issue/WEB-131/transitions"
90
- issue = plugin.api.Issue.build
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.transition(issue, 2, assignee: { name: 'username' }, customfield_11005: 'example')
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.0.1
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-02 00:00:00.000000000 Z
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