pivotoolz 2.0.0 → 2.4.0
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/Gemfile.lock +26 -24
- data/README.md +23 -0
- data/exe/get-story-info-from-id +1 -1
- data/exe/get-story-info-from-jira-id +61 -0
- data/exe/jira-stories-deployed +110 -0
- data/exe/jira-story-ids-deployed +25 -0
- data/lib/pivotoolz/version.rb +1 -1
- data/pivotoolz.gemspec +4 -4
- metadata +20 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4dd31c5a6721ed081086c98c0a069f4a38a4c1dde54b170e446780da2773bdd4
|
4
|
+
data.tar.gz: b099cfa80fdc349cead72eaded1c036467f793feb063fa8d54672a94f789d481
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 929634a5713e90745ae1bc2cac413855af3dee6441092c3f010854bc4159461f08d38872d9a6faa25cb2bae23ae7fba7094d487d5edbdc9b6601319c9b602a6a
|
7
|
+
data.tar.gz: 6437d69d3b64ed6c9dd380e3fb0028b94a71af256e3142e3d92946fb73fd8bae5c580c98c2ec532d73b3a4b467d6e03f6048077875f1ebe254cbade96c33411d
|
data/Gemfile.lock
CHANGED
@@ -1,51 +1,53 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pivotoolz (
|
5
|
-
rest-client (~> 2.
|
4
|
+
pivotoolz (2.2.0)
|
5
|
+
rest-client (~> 2.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
diff-lcs (1.
|
10
|
+
diff-lcs (1.4.4)
|
11
11
|
domain_name (0.5.20190701)
|
12
12
|
unf (>= 0.0.5, < 1.0.0)
|
13
|
-
http-
|
13
|
+
http-accept (1.7.0)
|
14
|
+
http-cookie (1.0.4)
|
14
15
|
domain_name (~> 0.5)
|
15
|
-
mime-types (3.3)
|
16
|
+
mime-types (3.3.1)
|
16
17
|
mime-types-data (~> 3.2015)
|
17
|
-
mime-types-data (3.
|
18
|
+
mime-types-data (3.2021.0901)
|
18
19
|
netrc (0.11.0)
|
19
|
-
rake (
|
20
|
-
rest-client (2.0
|
20
|
+
rake (13.0.6)
|
21
|
+
rest-client (2.1.0)
|
22
|
+
http-accept (>= 1.7.0, < 2.0)
|
21
23
|
http-cookie (>= 1.0.2, < 2.0)
|
22
24
|
mime-types (>= 1.16, < 4.0)
|
23
25
|
netrc (~> 0.8)
|
24
|
-
rspec (3.
|
25
|
-
rspec-core (~> 3.
|
26
|
-
rspec-expectations (~> 3.
|
27
|
-
rspec-mocks (~> 3.
|
28
|
-
rspec-core (3.
|
29
|
-
rspec-support (~> 3.
|
30
|
-
rspec-expectations (3.
|
26
|
+
rspec (3.10.0)
|
27
|
+
rspec-core (~> 3.10.0)
|
28
|
+
rspec-expectations (~> 3.10.0)
|
29
|
+
rspec-mocks (~> 3.10.0)
|
30
|
+
rspec-core (3.10.1)
|
31
|
+
rspec-support (~> 3.10.0)
|
32
|
+
rspec-expectations (3.10.1)
|
31
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
-
rspec-support (~> 3.
|
33
|
-
rspec-mocks (3.
|
34
|
+
rspec-support (~> 3.10.0)
|
35
|
+
rspec-mocks (3.10.2)
|
34
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
-
rspec-support (~> 3.
|
36
|
-
rspec-support (3.
|
37
|
+
rspec-support (~> 3.10.0)
|
38
|
+
rspec-support (3.10.2)
|
37
39
|
unf (0.1.4)
|
38
40
|
unf_ext
|
39
|
-
unf_ext (0.0.
|
41
|
+
unf_ext (0.0.8)
|
40
42
|
|
41
43
|
PLATFORMS
|
42
44
|
ruby
|
43
45
|
|
44
46
|
DEPENDENCIES
|
45
|
-
bundler (~>
|
47
|
+
bundler (~> 2.2)
|
46
48
|
pivotoolz!
|
47
|
-
rake (~>
|
48
|
-
rspec (~> 3.
|
49
|
+
rake (~> 13.0)
|
50
|
+
rspec (~> 3.10)
|
49
51
|
|
50
52
|
BUNDLED WITH
|
51
|
-
|
53
|
+
2.2.27
|
data/README.md
CHANGED
@@ -156,6 +156,29 @@ https://www.pivotaltracker.com/story/show/456
|
|
156
156
|
Use with `post-slack-message` to post a message in a slack deployment channel
|
157
157
|
with the list of stories that just got deployed.
|
158
158
|
|
159
|
+
For a slack-compatible formatted message, add the `--json` flag.
|
160
|
+
|
161
|
+
There are additional formatting flags if you want to see the name of the person who completed a story in the slack formatted message:
|
162
|
+
`--owners` - Show name of person who completed the story as part of the message
|
163
|
+
|
164
|
+
`--owners-footer` - Show name of person who completed the story as a footer (requires `--owners` flag)
|
165
|
+
|
166
|
+
`--bold-owners` - Show name of person who completed the story in bold text (requires `--owners` flag)
|
167
|
+
|
168
|
+
### `jira-stories-deployed`
|
169
|
+
|
170
|
+
Similar to `stories-deployed`, but for Jira! Now you can use your favourite development workflow accelerator, even if your
|
171
|
+
current team uses Jira!
|
172
|
+
|
173
|
+
Simply define the following environment variables, and you're ready to go!
|
174
|
+
|
175
|
+
```
|
176
|
+
export JIRA_API_BASIC_AUTH_BASE64_ENCODED=BASE_64_ENCODED_username:password # See https://developer.atlassian.com/server/jira/platform/basic-authentication/
|
177
|
+
export JIRA_API_BASE_URL=https://YOUR_ORG.atlassian.net/rest/api/3/issue/
|
178
|
+
export STORY_ID_REGEX=YOUR_STORY_ID_PATTERN_REGEX # Falls back to [[:alpha:]]+-\d+ if not set
|
179
|
+
```
|
180
|
+
Use `jira-stories-deployed` just as you would `stories-deployed`.
|
181
|
+
|
159
182
|
### `post-slack-message`
|
160
183
|
|
161
184
|
Post a message to a slack channel. You will need to [setup
|
data/exe/get-story-info-from-id
CHANGED
@@ -11,7 +11,7 @@ def get_story_info(story_id, flags = [])
|
|
11
11
|
begin
|
12
12
|
include_owner_names = flags.any? { |f| f == '--owners' || f == '-O' }
|
13
13
|
url = BASE_URL + "#{story_id}" + "/#{include_owner_names ? '?fields=:default,owners' : ''}"
|
14
|
-
open(
|
14
|
+
URI.open(
|
15
15
|
url,
|
16
16
|
'X-TrackerToken' => ENV['PIVOTAL_TRACKER_API_TOKEN']
|
17
17
|
).read
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
BASE_URL = ENV['JIRA_API_BASE_URL']
|
7
|
+
|
8
|
+
def get_story_info(story_id, flags = [], subdomain)
|
9
|
+
return nil if story_id.empty?
|
10
|
+
|
11
|
+
begin
|
12
|
+
url = BASE_URL + "#{story_id}"
|
13
|
+
URI.open(
|
14
|
+
url,
|
15
|
+
'Authorization' => "Basic #{ENV['JIRA_API_BASIC_AUTH_BASE64_ENCODED']}"
|
16
|
+
).read
|
17
|
+
rescue StandardError => e
|
18
|
+
story_link = "https://#{subdomain}.atlassian.net/browse/#{story_id}"
|
19
|
+
|
20
|
+
JSON.generate({
|
21
|
+
error: "Could not get story info for story #{story_id}: #{e.message}\n\nStory info may be available at #{story_link}",
|
22
|
+
story_link: story_link
|
23
|
+
})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if BASE_URL.nil? || BASE_URL.empty?
|
28
|
+
puts "Please set JIRA_API_BASE_URL. It looks something like 'https://YOUR-COMPANY.atlassian.net/rest/api/2/issue/'"
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
subdomain = URI.parse(BASE_URL).host.split('.atlassian.net').first
|
34
|
+
rescue => e
|
35
|
+
puts "Error determining your Jira subdomain. Please check your JIRA_API_BASE_URL environment variable"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
flags = ARGV.reduce([]) do |reduced, a|
|
40
|
+
reduced << a if a.include?('--') || a.include?('-')
|
41
|
+
reduced
|
42
|
+
end
|
43
|
+
|
44
|
+
flags.each { |f| ARGV.delete f }
|
45
|
+
|
46
|
+
stream = ARGV.any? ? ARGV : ARGF
|
47
|
+
|
48
|
+
if stream == ARGF && $stdin.tty?
|
49
|
+
puts "Usage:\nget-story-info-from-jira-id STORY_ID\n"
|
50
|
+
puts " OR\n"
|
51
|
+
puts "echo STORY_ID | get-story-info-from-id"
|
52
|
+
puts " OR\n"
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
|
56
|
+
infos = stream.reduce([]) do |reduced, story_id|
|
57
|
+
next reduced unless story_id && story_id =~ /\d+/
|
58
|
+
reduced << get_story_info(story_id.strip, flags, subdomain)
|
59
|
+
end
|
60
|
+
|
61
|
+
puts infos.join("\n")
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
BASE_URL = ENV['JIRA_API_BASE_URL']
|
8
|
+
|
9
|
+
if BASE_URL.nil? || BASE_URL.empty?
|
10
|
+
puts "Please set JIRA_API_BASE_URL. It looks something like 'https://YOUR-COMPANY.atlassian.net/rest/api/2/issue/'"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
begin
|
15
|
+
subdomain = URI.parse(BASE_URL).host.split('.atlassian.net').first
|
16
|
+
rescue => e
|
17
|
+
puts "Error determining your Jira subdomain. Please check your JIRA_API_BASE_URL environment variable"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
environment_tag = ARGV[0]&.strip
|
22
|
+
if environment_tag.nil? || environment_tag.empty?
|
23
|
+
puts "Usage: stories-deployed ENVIRONMENT"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
flags = ARGV.select { |a| a.include?('--') || a.include?('-') }
|
28
|
+
|
29
|
+
include_owners = flags
|
30
|
+
.any? { |f| f == '--owners' || f == '-O' }
|
31
|
+
|
32
|
+
format_as_json = flags
|
33
|
+
.any? { |f| f == '--json' || f == '-j' }
|
34
|
+
|
35
|
+
deployed_story_infos = `jira-story-ids-deployed #{environment_tag} | get-story-info-from-jira-id #{flags.join(' ')}`
|
36
|
+
|
37
|
+
def as_json(story, include_owners, flags, subdomain)
|
38
|
+
if story.error
|
39
|
+
return {
|
40
|
+
title: story.error,
|
41
|
+
title_link: story.story_link
|
42
|
+
}.to_json
|
43
|
+
end
|
44
|
+
|
45
|
+
json = {
|
46
|
+
title: story.fields['summary']&.strip,
|
47
|
+
title_link: "https://#{subdomain}.atlassian.net/browse/#{story.key}",
|
48
|
+
mrkdwn_in: ["text", "pretext", "footer"]
|
49
|
+
}
|
50
|
+
|
51
|
+
if include_owners
|
52
|
+
if flags.include? '--owners-footer'
|
53
|
+
json.merge!(
|
54
|
+
footer: "\n\nBrought to you by: #{story_owner_names(story, flags)}"
|
55
|
+
)
|
56
|
+
else
|
57
|
+
json.merge!(
|
58
|
+
text: "\n\nBrought to you by: #{story_owner_names(story, flags)}"
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
json.to_json
|
64
|
+
end
|
65
|
+
|
66
|
+
def story_owner_names(story, flags)
|
67
|
+
owners = *(
|
68
|
+
story
|
69
|
+
.fields
|
70
|
+
.assignee
|
71
|
+
&.displayName
|
72
|
+
)
|
73
|
+
|
74
|
+
if flags.include? '--bold-owners'
|
75
|
+
return to_sentence(owners.map { |o| "*#{o}*" })
|
76
|
+
end
|
77
|
+
|
78
|
+
to_sentence(owners)
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_sentence(array)
|
82
|
+
array.size > 2 ?
|
83
|
+
"#{array[0..-2].join(', ')} and #{array.last}" :
|
84
|
+
array.join(' and ')
|
85
|
+
end
|
86
|
+
|
87
|
+
stories_deployed = deployed_story_infos
|
88
|
+
.split("\n")
|
89
|
+
.compact
|
90
|
+
.reduce([]) do |reduced, story_info|
|
91
|
+
story = JSON.parse(story_info, object_class: OpenStruct)
|
92
|
+
|
93
|
+
if format_as_json
|
94
|
+
reduced << as_json(story, include_owners, flags, subdomain)
|
95
|
+
next reduced
|
96
|
+
end
|
97
|
+
|
98
|
+
reduced << "#{story.error}"
|
99
|
+
next reduced if story.error
|
100
|
+
|
101
|
+
reduced << "#{story.name&.strip}:\n#{story.url}"
|
102
|
+
|
103
|
+
if include_owners
|
104
|
+
reduced << "\nBrought to you by: #{story_owner_names(story, flags)}"
|
105
|
+
end
|
106
|
+
|
107
|
+
reduced
|
108
|
+
end
|
109
|
+
|
110
|
+
puts stories_deployed
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
environment_tag = ARGV[0]&.strip
|
4
|
+
|
5
|
+
if environment_tag.nil? || environment_tag.empty?
|
6
|
+
puts "Usage: story-ids-deployed ENVIRONMENT"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
commit_range = `git tag -l #{environment_tag}* | tail -n 2 | tr '\n' ' ' | sed -e 's/ /../'`.strip
|
11
|
+
|
12
|
+
if commit_range.nil? || commit_range.empty?
|
13
|
+
puts "Empty commit range! Are there any commits tagged with #{environment_tag}?"
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
|
17
|
+
commit_message_bodies = `git log --pretty="%h %s" #{commit_range}`.strip
|
18
|
+
story_ids = commit_message_bodies.
|
19
|
+
# TODO: Make this configurable
|
20
|
+
scan(/#{ENV['STORY_ID_REGEX'] || '[[:alpha:]]+-\d+'}/).
|
21
|
+
flatten.
|
22
|
+
compact.
|
23
|
+
uniq
|
24
|
+
|
25
|
+
puts story_ids.join("\n")
|
data/lib/pivotoolz/version.rb
CHANGED
data/pivotoolz.gemspec
CHANGED
@@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ["lib"]
|
30
30
|
|
31
|
-
spec.add_dependency 'rest-client', "~> 2.
|
31
|
+
spec.add_dependency 'rest-client', "~> 2.1"
|
32
32
|
|
33
|
-
spec.add_development_dependency "bundler", "~>
|
34
|
-
spec.add_development_dependency "rake", "~>
|
35
|
-
spec.add_development_dependency "rspec", "~> 3.
|
33
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
34
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.10"
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pivotoolz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sufyan Adam
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: '2.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: '2.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '2.2'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '2.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3.
|
61
|
+
version: '3.10'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '3.
|
68
|
+
version: '3.10'
|
69
69
|
description: Auto-deliver your finished stories upon successful deployment, find out
|
70
70
|
which stories went out in the last deployment, get a list of pivotal tracker story
|
71
71
|
ids that went out in the last deployment.
|
@@ -75,6 +75,9 @@ executables:
|
|
75
75
|
- deliver-deployed-stories
|
76
76
|
- deliver-story
|
77
77
|
- get-story-info-from-id
|
78
|
+
- get-story-info-from-jira-id
|
79
|
+
- jira-stories-deployed
|
80
|
+
- jira-story-ids-deployed
|
78
81
|
- merge
|
79
82
|
- post-slack-message
|
80
83
|
- pv-git-branch
|
@@ -104,6 +107,9 @@ files:
|
|
104
107
|
- exe/deliver-deployed-stories
|
105
108
|
- exe/deliver-story
|
106
109
|
- exe/get-story-info-from-id
|
110
|
+
- exe/get-story-info-from-jira-id
|
111
|
+
- exe/jira-stories-deployed
|
112
|
+
- exe/jira-story-ids-deployed
|
107
113
|
- exe/merge
|
108
114
|
- exe/post-slack-message
|
109
115
|
- exe/pv-git-branch
|
@@ -120,7 +126,7 @@ licenses:
|
|
120
126
|
- MIT
|
121
127
|
metadata:
|
122
128
|
allowed_push_host: https://rubygems.org
|
123
|
-
post_install_message:
|
129
|
+
post_install_message:
|
124
130
|
rdoc_options: []
|
125
131
|
require_paths:
|
126
132
|
- lib
|
@@ -135,8 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
141
|
- !ruby/object:Gem::Version
|
136
142
|
version: '0'
|
137
143
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
139
|
-
signing_key:
|
144
|
+
rubygems_version: 3.2.22
|
145
|
+
signing_key:
|
140
146
|
specification_version: 4
|
141
147
|
summary: Tools to save you time when working with Pivotal Tracker stories
|
142
148
|
test_files: []
|