NG1BuildHelpers 0.1.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 +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +38 -0
- data/NG1BuildHelpers.gemspec +24 -0
- data/README.md +18 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/ng1build +57 -0
- data/lib/NG1BuildHelpers/version.rb +3 -0
- data/lib/NG1BuildHelpers.rb +6 -0
- data/lib/circleci/circleci.rb +142 -0
- data/lib/help.rb +25 -0
- data/lib/jira/jira.rb +160 -0
- data/lib/jira/jira_parser.rb +182 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f4c56f797871e61365a615a19ae7227db359dc5
|
4
|
+
data.tar.gz: 1bf8c107af1971e6c744432d2b67c6ea18a098a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f130441afd1f62bd4c75e84c94f37a11397e7c7d25ccf71ecd3c9f5a29ee740c677708dc194c0799743d09644ab61d71982c2c1165dba6bc09b4d6f170fd853e
|
7
|
+
data.tar.gz: 5db86c295715863eec1e700601006752c60a5872022e120a6af94bc119b20369c94b8e81ba40a6d716065f658ddf3d02c252b7c66c071d9a42c3883a1e2ee082
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
NG1BuildHelpers (0.1.0)
|
5
|
+
OptionParser (~> 0.5.1)
|
6
|
+
rest-client (~> 2.0.2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
OptionParser (0.5.1)
|
12
|
+
domain_name (0.5.20170404)
|
13
|
+
unf (>= 0.0.5, < 1.0.0)
|
14
|
+
http-cookie (1.0.3)
|
15
|
+
domain_name (~> 0.5)
|
16
|
+
mime-types (3.1)
|
17
|
+
mime-types-data (~> 3.2015)
|
18
|
+
mime-types-data (3.2016.0521)
|
19
|
+
netrc (0.11.0)
|
20
|
+
rake (10.5.0)
|
21
|
+
rest-client (2.0.2)
|
22
|
+
http-cookie (>= 1.0.2, < 2.0)
|
23
|
+
mime-types (>= 1.16, < 4.0)
|
24
|
+
netrc (~> 0.8)
|
25
|
+
unf (0.1.4)
|
26
|
+
unf_ext
|
27
|
+
unf_ext (0.0.7.5)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
NG1BuildHelpers!
|
34
|
+
bundler (~> 1.9)
|
35
|
+
rake (~> 10.0)
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
1.16.1
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'NG1BuildHelpers/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "NG1BuildHelpers"
|
8
|
+
spec.summary = "Helpers for performing build tasks and integrations"
|
9
|
+
spec.version = NG1BuildHelpers::VERSION
|
10
|
+
spec.authors = ["NG1"]
|
11
|
+
spec.email = ["kristen.morgan@natgeo.com"]
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
15
|
+
spec.bindir = "exe"
|
16
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_runtime_dependency 'OptionParser', '~> 0.5.1'
|
20
|
+
spec.add_runtime_dependency 'rest-client', '~> 2.0.2'
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# jira-automation-scripts
|
2
|
+
Scripts to aid in automating Jira actions and CI tasks.
|
3
|
+
|
4
|
+
|
5
|
+
# To use
|
6
|
+
|
7
|
+
The first build step is to run `ng1build circleci_fetch_git_range` while exporting the value returned in the environment variable `CIRCLECI_COMMIT_RANGE`. This will go through CircleCI to find the last successful build for a given [target_branch] and will use that as a range to feed the next step. You can pass the CircleCI token in as a paramter or set it as an environment variable `'CIRCLE_TOKEN'`
|
8
|
+
|
9
|
+
|
10
|
+
```
|
11
|
+
export CIRCLECI_COMMIT_RANGE=`ng1build circleci_fetch_git_range --url https://circleci.com/api/v1.1 --branch [target_branch] --project [your_project] --company [your_company] --token [your_token_here] --export`
|
12
|
+
```
|
13
|
+
|
14
|
+
The second step is to run `ng1build jira_update_fix_version` which will use the previously provided commit range to look through the Git history and find stories with a given [issue_matching_regex] that are in the 'Testing' status. Once it finds those, it will create a new Fix Version and set those tickets version and transition those to the 'In Acceptance' column.
|
15
|
+
|
16
|
+
```
|
17
|
+
ng1build jira_update_fix_version --site [jira_base_url] --username [jira_username] --password [jira_password] --build_number [build_number] --regex [issue_matching_regex] --version [version_number] --project [jira_project_name] --version_name [jira_version_name]
|
18
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "NG1BuildHelpers"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/ng1build
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'NG1BuildHelpers'
|
4
|
+
|
5
|
+
Command = Struct.new(:command, :description, :help_function, :run_function)
|
6
|
+
|
7
|
+
commands = [
|
8
|
+
|
9
|
+
# JIRA section
|
10
|
+
Command.new(
|
11
|
+
"jira_update_fix_version",
|
12
|
+
"Update JIRA by transitioning any mentioned issues and settting Fix Version",
|
13
|
+
Proc.new { NG1BuildHelpers::JIRA::print_help },
|
14
|
+
Proc.new { |args| NG1BuildHelpers::JIRA::Parser::commandline_jira_update(args) }),
|
15
|
+
|
16
|
+
# CircleCI section
|
17
|
+
Command.new(
|
18
|
+
"circleci_fetch_git_range",
|
19
|
+
"Get the git commit range for the last successful build on CircleCI to now",
|
20
|
+
Proc.new { NG1BuildHelpers::CircleCI::print_help },
|
21
|
+
Proc.new { |args| NG1BuildHelpers::CircleCI::commandline_fetch_commit_range(args) }),
|
22
|
+
]
|
23
|
+
|
24
|
+
commands.unshift(
|
25
|
+
# Help
|
26
|
+
Command.new(
|
27
|
+
"help",
|
28
|
+
"Get help for a specific command",
|
29
|
+
Proc.new { NG1BuildHelpers::Help::print_help },
|
30
|
+
Proc.new { |args| NG1BuildHelpers::Help::print_command_help(args, commands) }),
|
31
|
+
)
|
32
|
+
|
33
|
+
command_name = ARGV.shift
|
34
|
+
if command_name.nil?
|
35
|
+
puts " Usage: #{__FILE__} command [options]"
|
36
|
+
puts
|
37
|
+
printf " %-30s %s\n", "Command", "Command Description"
|
38
|
+
puts
|
39
|
+
commands.each do |command|
|
40
|
+
printf " %-30s %s\n", command.command, command.description
|
41
|
+
end
|
42
|
+
else
|
43
|
+
command = commands.find do |c|
|
44
|
+
c.command == command_name
|
45
|
+
end
|
46
|
+
|
47
|
+
if command
|
48
|
+
if ARGV[0] == "--help"
|
49
|
+
command.help_function.call()
|
50
|
+
else
|
51
|
+
command.run_function.call(ARGV)
|
52
|
+
end
|
53
|
+
else
|
54
|
+
puts "Unknown command: #{command_name}"
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'base64'
|
5
|
+
require 'json'
|
6
|
+
require 'rest_client'
|
7
|
+
require 'pp'
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module NG1BuildHelpers
|
11
|
+
end
|
12
|
+
|
13
|
+
module NG1BuildHelpers::CircleCI
|
14
|
+
Options = Struct.new(:url, :company, :project, :branch, :export, :token)
|
15
|
+
|
16
|
+
class OptionsParser
|
17
|
+
def self.parse(options)
|
18
|
+
args = Options.new()
|
19
|
+
args.export = false
|
20
|
+
|
21
|
+
opt_parser = OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: #{__FILE__} [options]"
|
23
|
+
|
24
|
+
opts.on("-u", "--url URL", "Specify the URL for CircleCI instance") do |url|
|
25
|
+
args.url = url
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-c", "--company COMPANY", "Specify the company for CircleCI") do |company|
|
29
|
+
args.company = company
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-p", "--project PROJECT", "Specify the project for CircleCI") do |project|
|
33
|
+
args.project = project
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("-b", "--branch BRANCH", "Specify the branch for CircleCI") do |branch|
|
37
|
+
args.branch = branch
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-t", "--token TOKEN", "Specify the token for CircleCI") do |token|
|
41
|
+
args.token = token
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-e", "--export", "Output range for use as a parameter to the 'export' bash command") do
|
45
|
+
args.export = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
49
|
+
puts opts
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
opt_parser.parse!(options)
|
55
|
+
return args
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# If run with the export option, this will set the environment variable
|
60
|
+
# that the JIRA scripts will use to determine which new stories were
|
61
|
+
# completed
|
62
|
+
def self.put_range(options, start_revision, end_revision)
|
63
|
+
value = ""
|
64
|
+
if end_revision
|
65
|
+
value = "#{end_revision}..#{start_revision}"
|
66
|
+
else
|
67
|
+
value = "#{start_revision}"
|
68
|
+
end
|
69
|
+
|
70
|
+
if options.export
|
71
|
+
puts value
|
72
|
+
else
|
73
|
+
puts "##circleci[setParameter name='env.CIRCLECI_COMMIT_RANGE' value='#{value}']"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Using CircleCI API go through to find the last
|
78
|
+
# successful build for a specified branch and grab the
|
79
|
+
# revision.
|
80
|
+
def self.get_last_successful_rev(options, branch)
|
81
|
+
headers = { "Accept" => "application/json" }
|
82
|
+
|
83
|
+
end_revision = nil
|
84
|
+
|
85
|
+
circle_token = options.token
|
86
|
+
if (!circle_token)
|
87
|
+
circle_token = ENV["CIRCLE_TOKEN"]
|
88
|
+
if (!circle_token)
|
89
|
+
puts("Problem getting last successful revision, make sure the CircleCI Token is set")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
full_url = "#{options.url}/project/github/#{options.company}/#{options.project}/tree/#{options.branch}?circle-token=#{circle_token}"
|
94
|
+
|
95
|
+
response = RestClient.get(full_url, headers=headers)
|
96
|
+
json_response = JSON.parse(response.body)
|
97
|
+
|
98
|
+
json_response.each do |build|
|
99
|
+
if build["status"] == "success"
|
100
|
+
end_revision = build["vcs_revision"]
|
101
|
+
break
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
return end_revision
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.fetch_commit_range(options)
|
109
|
+
start_revision = ENV["CIRCLE_SHA1"]
|
110
|
+
|
111
|
+
begin
|
112
|
+
end_revision = nil
|
113
|
+
while end_revision == nil && options.branch.length > 0 do
|
114
|
+
check_branch = options.branch
|
115
|
+
end_revision = get_last_successful_rev(options, check_branch)
|
116
|
+
end
|
117
|
+
|
118
|
+
put_range(options, start_revision, end_revision)
|
119
|
+
|
120
|
+
rescue RestClient::Exception => e
|
121
|
+
puts "ERROR getting last successful build from CircleCI"
|
122
|
+
exit 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.print_help()
|
127
|
+
OptionsParser.parse(["--help"])
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.commandline_fetch_commit_range(args = nil)
|
131
|
+
if !ENV["CIRCLECI"]
|
132
|
+
puts("Not running on CircleCI")
|
133
|
+
return
|
134
|
+
end
|
135
|
+
options = OptionsParser.parse(args)
|
136
|
+
fetch_commit_range(options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if __FILE__ == $0
|
141
|
+
NG1BuildHelpers::CircleCI.commandline_fetch_commit_range(ARGV)
|
142
|
+
end
|
data/lib/help.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
module NG1BuildHelpers
|
4
|
+
end
|
5
|
+
|
6
|
+
module NG1BuildHelpers::Help
|
7
|
+
|
8
|
+
def self.print_help()
|
9
|
+
puts "Usage: ng1build help command"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.print_command_help(args, commands)
|
13
|
+
command_name = args[0]
|
14
|
+
command = commands.find do |c|
|
15
|
+
c.command == command_name
|
16
|
+
end
|
17
|
+
|
18
|
+
if command
|
19
|
+
command.help_function.call()
|
20
|
+
else
|
21
|
+
puts "Unknown command: #{command_name}"
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/jira/jira.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'pp'
|
5
|
+
require 'set'
|
6
|
+
require 'rest_client'
|
7
|
+
require 'base64'
|
8
|
+
require 'date'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
|
12
|
+
module NG1BuildHelpers::JIRA
|
13
|
+
|
14
|
+
# This class will be used to create a Fix Version for a
|
15
|
+
# given release and build number and then assign any tickets
|
16
|
+
# to those fix versions.
|
17
|
+
class Jira
|
18
|
+
|
19
|
+
attr_reader :fixed_in_build_field_id
|
20
|
+
attr_reader :jira_transition_id
|
21
|
+
|
22
|
+
attr_reader :client
|
23
|
+
|
24
|
+
@@build
|
25
|
+
@@version
|
26
|
+
@@project
|
27
|
+
@@version_name
|
28
|
+
|
29
|
+
def initialize(options)
|
30
|
+
site = options.site
|
31
|
+
username = options.username
|
32
|
+
password = options.password
|
33
|
+
|
34
|
+
auth_token = Base64.strict_encode64("#{username}:#{password}")
|
35
|
+
base_url = File.join(site, '/rest/api/2')
|
36
|
+
headers = { "Authorization" => "Basic #{auth_token}",
|
37
|
+
"Content-Type" => "application/json", }
|
38
|
+
|
39
|
+
@client = RestClient::Resource.new(base_url, :headers => headers)
|
40
|
+
|
41
|
+
@@build = options.build
|
42
|
+
@@version = options.version
|
43
|
+
@@project = options.project
|
44
|
+
@@version_name = options.version_name
|
45
|
+
end
|
46
|
+
|
47
|
+
#Create a release version in JIRA
|
48
|
+
#and return it's ID
|
49
|
+
def create_release_version()
|
50
|
+
begin
|
51
|
+
params = {
|
52
|
+
"name" => "#{@@version_name} #{@@version}-#{@@build}",
|
53
|
+
"released" => false,
|
54
|
+
"project" => "#{@@project}",
|
55
|
+
"releaseDate" => DateTime.now
|
56
|
+
}
|
57
|
+
|
58
|
+
puts "Creating release version #{params["name"]}"
|
59
|
+
version_response = client["version"].post(JSON.generate(params))
|
60
|
+
fields = JSON.parse(version_response.body)
|
61
|
+
version_id = fields["id"]
|
62
|
+
|
63
|
+
rescue RestClient::Exception => e
|
64
|
+
puts "Error updating version : Error code #{e}"
|
65
|
+
end
|
66
|
+
|
67
|
+
version_id
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_testing_transition(issue_key)
|
71
|
+
begin
|
72
|
+
fields_resource = "issue/#{issue_key}/transitions"
|
73
|
+
|
74
|
+
response = client[fields_resource].get
|
75
|
+
|
76
|
+
response_json = JSON.parse(response.body)
|
77
|
+
transitions = response_json["transitions"]
|
78
|
+
testing_transition = transitions.find do |transition|
|
79
|
+
transition["name"] == "Testing"
|
80
|
+
end
|
81
|
+
|
82
|
+
if testing_transition
|
83
|
+
@jira_transition_id = testing_transition["id"]
|
84
|
+
end
|
85
|
+
rescue RestClient::Exception => e
|
86
|
+
puts "Error code #{e.response.code} attempting to find Build Complete transition"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def update_fix_version(issue_key, version_id)
|
92
|
+
params = {
|
93
|
+
update: {
|
94
|
+
# Set the fix version
|
95
|
+
"fixVersions" => [
|
96
|
+
{
|
97
|
+
"set" => [
|
98
|
+
{"id" => version_id}
|
99
|
+
]
|
100
|
+
}
|
101
|
+
],
|
102
|
+
# Peer Review Field
|
103
|
+
"customfield_19007" => [
|
104
|
+
{
|
105
|
+
"set" => [
|
106
|
+
{"value" => "Complete"}
|
107
|
+
]
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
puts "Setting #{issue_key} fix version to #{version_id}"
|
114
|
+
|
115
|
+
begin
|
116
|
+
issue_response = client["issue/#{issue_key}"].put(JSON.generate(params))
|
117
|
+
rescue RestClient::Exception => e
|
118
|
+
puts "Error updating issue #{issue_key}: Error code #{e}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def update_transition(issue_key)
|
123
|
+
#try to perform the transition
|
124
|
+
if !jira_transition_id
|
125
|
+
update_testing_transition(issue_key)
|
126
|
+
end
|
127
|
+
|
128
|
+
if jira_transition_id
|
129
|
+
|
130
|
+
begin
|
131
|
+
params = {
|
132
|
+
transition: {
|
133
|
+
id: jira_transition_id
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
puts "Transitioning #{issue_key} to Testing"
|
138
|
+
|
139
|
+
issue_response = client["issue/#{issue_key}/transitions"].post(JSON.generate(params))
|
140
|
+
rescue RestClient::Exception => e
|
141
|
+
puts "Error updating issue #{issue_key}: Error code #{e}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def jira_update(issues, options)
|
147
|
+
|
148
|
+
puts "Updating JIRA"
|
149
|
+
version_id = create_release_version()
|
150
|
+
|
151
|
+
#Set the fix version of all the issues that were built.
|
152
|
+
issues.each do |issue_key|
|
153
|
+
puts "Updating issue #{issue_key}"
|
154
|
+
update_fix_version(issue_key, version_id)
|
155
|
+
update_transition(issue_key)
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'pp'
|
5
|
+
require 'set'
|
6
|
+
require 'rest_client'
|
7
|
+
require 'base64'
|
8
|
+
require 'json'
|
9
|
+
require 'jira/jira'
|
10
|
+
|
11
|
+
module NG1BuildHelpers
|
12
|
+
end
|
13
|
+
|
14
|
+
module NG1BuildHelpers::JIRA
|
15
|
+
|
16
|
+
class Parser
|
17
|
+
|
18
|
+
Options = Struct.new(:commit_range, :site, :username, :password, :build, :regex, :version, :project, :version_name)
|
19
|
+
|
20
|
+
def self.parse(options)
|
21
|
+
args = Options.new()
|
22
|
+
|
23
|
+
opt_parser = OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: jira_update_fix_version [options]"
|
25
|
+
|
26
|
+
opts.on("-c", "--commits COMMIT_RANGE", "Specify a commit range") do |commit_range|
|
27
|
+
args.commit_range = commit_range
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-u", "--username USERNAME", "Specify the user to connecto to JIRA") do |username|
|
31
|
+
args.username = username
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("-p", "--password PASSWORD", "Specify the password to connect to JIRA") do |password|
|
35
|
+
args.password = password
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on("-s", "--site SITE", "Specify the base location of the JIRA instance") do |site|
|
39
|
+
site.slice!("http://")
|
40
|
+
site.insert(0, "https://") if not site.start_with?("https://")
|
41
|
+
args.site = site
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-b", "--build_number BUILD", "The build number for which this script is executing") do |build|
|
45
|
+
args.build = build
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-r", "--regex REGEX", "JIRA Story Regex [Optional]") do |regex|
|
49
|
+
args.regex = regex
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-v", "--version VERSION", "App Version") do |version|
|
53
|
+
args.version = version
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("-n", "--version_name VERSION NAME", "JIRA Version Name") do |version_name|
|
57
|
+
args.version_name = version_name
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on("-p", "--project PROJECT", "JIRA Project Name") do |project|
|
61
|
+
args.project = project
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
65
|
+
puts opts
|
66
|
+
exit
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
opt_parser.parse!(options)
|
71
|
+
return args
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.validate_options(options)
|
75
|
+
valid_options = true
|
76
|
+
if options.commit_range == nil || options.commit_range.empty?
|
77
|
+
puts "Commit range is required. None specified."
|
78
|
+
valid_options = false
|
79
|
+
end
|
80
|
+
if options.site == nil
|
81
|
+
puts "Site parameter is required, or use JIRA_URL environment variable on build servers"
|
82
|
+
valid_options = false
|
83
|
+
end
|
84
|
+
if options.username == nil
|
85
|
+
puts "No username for JIRA provided. Use JIRA_USERNAME environment variable on build servers"
|
86
|
+
valid_options = false
|
87
|
+
end
|
88
|
+
if options.password == nil
|
89
|
+
puts "No password for JIRA provided. Use JIRA_PASSWORD environment variable on build servers"
|
90
|
+
valid_options = false
|
91
|
+
end
|
92
|
+
if options.version == nil
|
93
|
+
puts "No version provided."
|
94
|
+
valid_options = false
|
95
|
+
end
|
96
|
+
if options.project == nil
|
97
|
+
puts "No project name provided."
|
98
|
+
valid_options = false
|
99
|
+
end
|
100
|
+
if options.version_name == nil
|
101
|
+
puts "No version name provided."
|
102
|
+
valid_options = false
|
103
|
+
end
|
104
|
+
valid_options
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.commandline_jira_update(args)
|
108
|
+
options = args ? parse(ARGV) : Options.new
|
109
|
+
|
110
|
+
pull_ci_options(options)
|
111
|
+
pull_common_options(options)
|
112
|
+
|
113
|
+
if validate_options(options)
|
114
|
+
logs = get_git_history(options.commit_range)
|
115
|
+
issue_set = find_jira_issues(logs, options.regex)
|
116
|
+
|
117
|
+
if issue_set.size > 0
|
118
|
+
puts "Updating #{issue_set.size} issues"
|
119
|
+
jira_info = NG1BuildHelpers::JIRA::Jira.new options
|
120
|
+
jira_info.jira_update(issue_set, options)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.find_jira_issues(logs, regex)
|
126
|
+
issue_set = Set.new
|
127
|
+
logs.each do |log|
|
128
|
+
#If provided a JIRA Regex to find issues
|
129
|
+
if regex
|
130
|
+
issues = log.scan(/#{regex}/)
|
131
|
+
elsif
|
132
|
+
issues = log.scan(/[A-Za-z][A-Za-z]+-[1-9][0-9]*/)
|
133
|
+
end
|
134
|
+
|
135
|
+
issue_set.merge(issues)
|
136
|
+
end
|
137
|
+
|
138
|
+
return issue_set
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.get_git_history(commit_range)
|
142
|
+
puts "Getting git history for #{commit_range}"
|
143
|
+
happyface = "\u263A".encode('utf-8')
|
144
|
+
extra_params = commit_range.index('..') == nil ? "-n 1" : ""
|
145
|
+
git_log = `git --no-pager log --format="%B#{happyface}" #{commit_range} #{extra_params}`
|
146
|
+
puts(git_log)
|
147
|
+
|
148
|
+
#parse out the log
|
149
|
+
logs = git_log.split(happyface)
|
150
|
+
|
151
|
+
return logs
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.pull_ci_options(options)
|
155
|
+
if ENV["CIRCLECI"]
|
156
|
+
pull_circleci_options(options)
|
157
|
+
else
|
158
|
+
puts("Not running on CircleCI")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.pull_common_options(options)
|
163
|
+
options.site = ENV["JIRA_URL"] if options.site == nil
|
164
|
+
options.username = ENV["JIRA_USERNAME"] if options.username == nil
|
165
|
+
options.password = ENV["JIRA_PASSWORD"] if options.password == nil
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.pull_circleci_options(options)
|
169
|
+
puts "Pulling parameters from CircleCI environment variables where needed...."
|
170
|
+
options.commit_range = ENV["CIRCLECI_COMMIT_RANGE"] if options.commit_range == nil
|
171
|
+
options.build = ENV["CIRCLE_BUILD_NUM"] if options.build == nil
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.print_help()
|
175
|
+
Parser.parse(["--help"])
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
if __FILE__ == $0
|
181
|
+
NG1BuildHelpers::JIRA::commandline_jira_update(ARGV)
|
182
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: NG1BuildHelpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- NG1
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: OptionParser
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.5.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rest-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.9'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- kristen.morgan@natgeo.com
|
72
|
+
executables:
|
73
|
+
- ng1build
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- Gemfile
|
78
|
+
- Gemfile.lock
|
79
|
+
- NG1BuildHelpers.gemspec
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- exe/ng1build
|
85
|
+
- lib/NG1BuildHelpers.rb
|
86
|
+
- lib/NG1BuildHelpers/version.rb
|
87
|
+
- lib/circleci/circleci.rb
|
88
|
+
- lib/help.rb
|
89
|
+
- lib/jira/jira.rb
|
90
|
+
- lib/jira/jira_parser.rb
|
91
|
+
homepage:
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.6.14
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Helpers for performing build tasks and integrations
|
115
|
+
test_files: []
|