octopolo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +55 -0
- data/Rakefile +38 -0
- data/bash_completion.sh +13 -0
- data/bin/octopolo +21 -0
- data/bin/op +21 -0
- data/lib/octopolo.rb +15 -0
- data/lib/octopolo/changelog.rb +27 -0
- data/lib/octopolo/cli.rb +210 -0
- data/lib/octopolo/commands/accept_pull.rb +8 -0
- data/lib/octopolo/commands/compare_release.rb +9 -0
- data/lib/octopolo/commands/deployable.rb +8 -0
- data/lib/octopolo/commands/github_auth.rb +5 -0
- data/lib/octopolo/commands/new_branch.rb +9 -0
- data/lib/octopolo/commands/new_deployable.rb +8 -0
- data/lib/octopolo/commands/new_staging.rb +8 -0
- data/lib/octopolo/commands/octopolo_setup.rb +5 -0
- data/lib/octopolo/commands/pivotal_auth.rb +5 -0
- data/lib/octopolo/commands/pull_request.rb +13 -0
- data/lib/octopolo/commands/signoff.rb +10 -0
- data/lib/octopolo/commands/stage_up.rb +8 -0
- data/lib/octopolo/commands/stale_branches.rb +11 -0
- data/lib/octopolo/commands/sync_branch.rb +11 -0
- data/lib/octopolo/commands/tag_release.rb +13 -0
- data/lib/octopolo/config.rb +146 -0
- data/lib/octopolo/convenience_wrappers.rb +46 -0
- data/lib/octopolo/dated_branch_creator.rb +81 -0
- data/lib/octopolo/git.rb +262 -0
- data/lib/octopolo/github.rb +95 -0
- data/lib/octopolo/github/commit.rb +45 -0
- data/lib/octopolo/github/pull_request.rb +126 -0
- data/lib/octopolo/github/pull_request_creator.rb +127 -0
- data/lib/octopolo/github/user.rb +40 -0
- data/lib/octopolo/jira/story_commenter.rb +26 -0
- data/lib/octopolo/pivotal.rb +44 -0
- data/lib/octopolo/pivotal/story_commenter.rb +19 -0
- data/lib/octopolo/pull_request_merger.rb +99 -0
- data/lib/octopolo/renderer.rb +37 -0
- data/lib/octopolo/reports.rb +18 -0
- data/lib/octopolo/scripts.rb +23 -0
- data/lib/octopolo/scripts/accept_pull.rb +67 -0
- data/lib/octopolo/scripts/compare_release.rb +52 -0
- data/lib/octopolo/scripts/deployable.rb +27 -0
- data/lib/octopolo/scripts/github_auth.rb +87 -0
- data/lib/octopolo/scripts/new_branch.rb +34 -0
- data/lib/octopolo/scripts/new_deployable.rb +14 -0
- data/lib/octopolo/scripts/new_staging.rb +15 -0
- data/lib/octopolo/scripts/octopolo_setup.rb +55 -0
- data/lib/octopolo/scripts/pivotal_auth.rb +44 -0
- data/lib/octopolo/scripts/pull_request.rb +127 -0
- data/lib/octopolo/scripts/signoff.rb +85 -0
- data/lib/octopolo/scripts/stage_up.rb +26 -0
- data/lib/octopolo/scripts/stale_branches.rb +54 -0
- data/lib/octopolo/scripts/sync_branch.rb +37 -0
- data/lib/octopolo/scripts/tag_release.rb +70 -0
- data/lib/octopolo/templates/pull_request_body.erb +24 -0
- data/lib/octopolo/user_config.rb +112 -0
- data/lib/octopolo/version.rb +3 -0
- data/lib/octopolo/week.rb +130 -0
- data/octopolo.gemspec +31 -0
- data/spec/.DS_Store +0 -0
- data/spec/octopolo/cli_spec.rb +310 -0
- data/spec/octopolo/config_spec.rb +344 -0
- data/spec/octopolo/convenience_wrappers_spec.rb +80 -0
- data/spec/octopolo/dated_branch_creator_spec.rb +143 -0
- data/spec/octopolo/git_spec.rb +419 -0
- data/spec/octopolo/github/commit_spec.rb +59 -0
- data/spec/octopolo/github/pull_request_creator_spec.rb +174 -0
- data/spec/octopolo/github/pull_request_spec.rb +291 -0
- data/spec/octopolo/github/user_spec.rb +65 -0
- data/spec/octopolo/github_spec.rb +169 -0
- data/spec/octopolo/jira/stor_commenter_spec.rb +30 -0
- data/spec/octopolo/pivotal/story_commenter_spec.rb +34 -0
- data/spec/octopolo/pivotal_spec.rb +61 -0
- data/spec/octopolo/pull_request_merger_spec.rb +144 -0
- data/spec/octopolo/renderer_spec.rb +35 -0
- data/spec/octopolo/scripts/accept_pull_spec.rb +76 -0
- data/spec/octopolo/scripts/compare_release_spec.rb +115 -0
- data/spec/octopolo/scripts/deployable_spec.rb +52 -0
- data/spec/octopolo/scripts/github_auth_spec.rb +156 -0
- data/spec/octopolo/scripts/new_branch_spec.rb +41 -0
- data/spec/octopolo/scripts/new_deployable_spec.rb +18 -0
- data/spec/octopolo/scripts/new_staging_spec.rb +18 -0
- data/spec/octopolo/scripts/octopolo_setup_spec.rb +120 -0
- data/spec/octopolo/scripts/pivotal_auth_spec.rb +77 -0
- data/spec/octopolo/scripts/pull_request_spec.rb +217 -0
- data/spec/octopolo/scripts/signoff_spec.rb +139 -0
- data/spec/octopolo/scripts/stage_up_spec.rb +52 -0
- data/spec/octopolo/scripts/stale_branches_spec.rb +81 -0
- data/spec/octopolo/scripts/sync_branch_spec.rb +57 -0
- data/spec/octopolo/scripts/tag_release_spec.rb +108 -0
- data/spec/octopolo/user_config_spec.rb +167 -0
- data/spec/octopolo_spec.rb +7 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/engine_yard.cache +0 -0
- data/spec/support/sample_octopolo.yml +2 -0
- data/spec/support/sample_user.yml +2 -0
- data/templates/lib.erb +23 -0
- data/templates/script.erb +7 -0
- data/templates/spec.erb +29 -0
- metadata +344 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require "octokit"
|
2
|
+
# TODO this needs to get moved out of scripts and into its own new module
|
3
|
+
require_relative "scripts/github_auth"
|
4
|
+
|
5
|
+
module Octopolo
|
6
|
+
module GitHub
|
7
|
+
extend UserConfigWrapper
|
8
|
+
|
9
|
+
# Used as the name of a user if we can't find it on GitHub's API
|
10
|
+
UNKNOWN_USER = "Unknown User"
|
11
|
+
|
12
|
+
# Public: Perform the given block if the user has valid GitHub credentials
|
13
|
+
#
|
14
|
+
# When performing anything that connects to GitHub, wrap with
|
15
|
+
# GitHub.connect to ensure that the user's credentials are all set up
|
16
|
+
# before running anything.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# GitHub.connect do
|
21
|
+
# # PullRequest.create or whatever
|
22
|
+
# end
|
23
|
+
def self.connect &block
|
24
|
+
GitHub.check_connection
|
25
|
+
|
26
|
+
yield
|
27
|
+
rescue GitHub::BadCredentials, GitHub::TryAgain => error
|
28
|
+
CLI.say error.message
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public: A GitHub client object
|
32
|
+
def self.client(options = {})
|
33
|
+
Octokit::Client.new(options.merge(login: user_config.github_user, access_token: user_config.github_token))
|
34
|
+
rescue UserConfig::MissingGitHubAuth
|
35
|
+
raise TryAgain, "No GitHub API token stored. Please run `bundle exec github-auth` to generate your token."
|
36
|
+
end
|
37
|
+
|
38
|
+
# Public: A GitHub client configured to crawl through pages
|
39
|
+
def self.crawling_client
|
40
|
+
client(auto_traversal: true)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Check that GitHub credentials have been properly set up
|
44
|
+
def self.check_connection
|
45
|
+
# we don't care about the output, just try to hit the API
|
46
|
+
client.user && nil
|
47
|
+
rescue Octokit::Unauthorized
|
48
|
+
raise BadCredentials, "Your stored credentials were rejected by GitHub. Run `bundle exec github-auth` to generate a new token."
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.pull_request *args
|
52
|
+
client.pull_request *args
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.pull_request_commits *args
|
56
|
+
client.pull_request_commits *args
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.issue_comments *args
|
60
|
+
client.issue_comments *args
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.pull_requests *args
|
64
|
+
crawling_client.pull_requests *args
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.create_pull_request *args
|
68
|
+
client.create_pull_request *args
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.add_comment *args
|
72
|
+
client.add_comment *args
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.user username
|
76
|
+
client.user(username)
|
77
|
+
rescue
|
78
|
+
Hashie::Mash.new(name: UNKNOWN_USER)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.org_repos org_name="sportngin"
|
82
|
+
crawling_client.organization_repositories org_name
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.excluded_users
|
86
|
+
["tst-octopolo"]
|
87
|
+
end
|
88
|
+
|
89
|
+
# now that you've set up your credentials, try again
|
90
|
+
TryAgain = Class.new(StandardError)
|
91
|
+
# the credentials you've entered are bad
|
92
|
+
BadCredentials = Class.new(StandardError)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "../github"
|
2
|
+
require_relative "user"
|
3
|
+
|
4
|
+
module Octopolo
|
5
|
+
module GitHub
|
6
|
+
class Commit
|
7
|
+
attr_accessor :commit_data
|
8
|
+
|
9
|
+
# Public: Instantiate a new Commit wrapper object
|
10
|
+
#
|
11
|
+
# commit_data - The GitHub API data about the commit
|
12
|
+
def initialize commit_data
|
13
|
+
self.commit_data = commit_data
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: Find commits for a given pull request
|
17
|
+
#
|
18
|
+
# pull_request - A PullRequest or other object responding to #repo_name
|
19
|
+
# and #number
|
20
|
+
#
|
21
|
+
# Returns an Array of Commit objects
|
22
|
+
def self.for_pull_request pull_request
|
23
|
+
GitHub.pull_request_commits(pull_request.repo_name, pull_request.number).map do |c|
|
24
|
+
Commit.new c
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Public: GitHub User that is the author of the commit
|
29
|
+
#
|
30
|
+
# Returns a Hashie::Mash object of the GitHub User
|
31
|
+
def author
|
32
|
+
GitHub::User.new(commit_data.author.login)
|
33
|
+
rescue NoMethodError
|
34
|
+
GitHub::User.new(GitHub::UNKNOWN_USER)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: The name of the author of the commit
|
38
|
+
#
|
39
|
+
# Returns a String containing the author's name
|
40
|
+
def author_name
|
41
|
+
author.author_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative "../github"
|
2
|
+
require_relative "commit"
|
3
|
+
require_relative "pull_request_creator"
|
4
|
+
require_relative "user"
|
5
|
+
require_relative "../week"
|
6
|
+
require "octokit"
|
7
|
+
|
8
|
+
module Octopolo
|
9
|
+
module GitHub
|
10
|
+
class PullRequest
|
11
|
+
attr_accessor :pull_request_data
|
12
|
+
attr_accessor :repo_name
|
13
|
+
attr_accessor :number
|
14
|
+
|
15
|
+
def initialize repo_name, number, pull_request_data = nil
|
16
|
+
raise MissingParameter if repo_name.nil? or number.nil?
|
17
|
+
|
18
|
+
self.repo_name = repo_name
|
19
|
+
self.number = number
|
20
|
+
self.pull_request_data = pull_request_data
|
21
|
+
end
|
22
|
+
|
23
|
+
# Public: All closed pull requests for a given repo
|
24
|
+
#
|
25
|
+
# repo_name - Full name ("account/repo") of the repo in question
|
26
|
+
#
|
27
|
+
# Returns an Array of PullRequest objects
|
28
|
+
def self.closed repo_name
|
29
|
+
GitHub.pull_requests(repo_name, "closed").map do |data|
|
30
|
+
new repo_name, data.number, data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public: Create a pull request for the given repo
|
35
|
+
#
|
36
|
+
# repo_name - Full name ("account/repo") of the repo in question
|
37
|
+
# options - Hash of pull request information
|
38
|
+
# title: Title of the pull request
|
39
|
+
# description: Brief description of the pull request
|
40
|
+
# release: Boolean indicating if the pull request is for Release
|
41
|
+
# destination_branch: Which branch to merge into
|
42
|
+
# source_branch: Which branch to be merged
|
43
|
+
#
|
44
|
+
# Returns a PullRequest instance
|
45
|
+
def self.create repo_name, options
|
46
|
+
# create via the API
|
47
|
+
creator = PullRequestCreator.perform(repo_name, options)
|
48
|
+
# wrap in our class
|
49
|
+
new repo_name, creator.number, creator.pull_request_data
|
50
|
+
end
|
51
|
+
|
52
|
+
def pull_request_data
|
53
|
+
@pull_request_data ||= GitHub.pull_request(repo_name, number)
|
54
|
+
rescue Octokit::NotFound
|
55
|
+
raise NotFound
|
56
|
+
end
|
57
|
+
|
58
|
+
def title
|
59
|
+
pull_request_data.title
|
60
|
+
end
|
61
|
+
|
62
|
+
def url
|
63
|
+
pull_request_data.html_url
|
64
|
+
end
|
65
|
+
|
66
|
+
def branch
|
67
|
+
pull_request_data.head.ref
|
68
|
+
end
|
69
|
+
|
70
|
+
def mergeable?
|
71
|
+
pull_request_data.mergeable
|
72
|
+
end
|
73
|
+
|
74
|
+
def week
|
75
|
+
Week.parse pull_request_data.closed_at
|
76
|
+
end
|
77
|
+
|
78
|
+
def commenter_names
|
79
|
+
exlude_octopolo_user (comments.map{ |comment| GitHub::User.new(comment.user.login).author_name }.uniq - author_names)
|
80
|
+
end
|
81
|
+
|
82
|
+
def author_names
|
83
|
+
exlude_octopolo_user commits.map(&:author_name).uniq
|
84
|
+
end
|
85
|
+
|
86
|
+
def exlude_octopolo_user(user_list)
|
87
|
+
user_list.reject{|u| GitHub.excluded_users.include?(u) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def body
|
91
|
+
pull_request_data.body || ""
|
92
|
+
end
|
93
|
+
|
94
|
+
def external_urls
|
95
|
+
# extract http and https URLs from the body
|
96
|
+
URI.extract body, %w(http https)
|
97
|
+
end
|
98
|
+
|
99
|
+
def human_app_name
|
100
|
+
repo = repo_name.split("/").last
|
101
|
+
repo.split("_").map(&:capitalize).join(" ")
|
102
|
+
end
|
103
|
+
|
104
|
+
def commits
|
105
|
+
@commits ||= Commit.for_pull_request self
|
106
|
+
end
|
107
|
+
|
108
|
+
def comments
|
109
|
+
@comments ||= GitHub.issue_comments(repo_name, number)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Public: Add a comment to the pull request
|
113
|
+
#
|
114
|
+
# message - A String containing the desired comment body
|
115
|
+
def write_comment(message)
|
116
|
+
GitHub.add_comment repo_name, number, ":octocat: #{message}"
|
117
|
+
rescue Octokit::UnprocessableEntity => error
|
118
|
+
raise CommentFailed, "Unable to write the comment: '#{error.message}'"
|
119
|
+
end
|
120
|
+
|
121
|
+
MissingParameter = Class.new StandardError
|
122
|
+
NotFound = Class.new StandardError
|
123
|
+
CommentFailed = Class.new StandardError
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require_relative "../renderer"
|
2
|
+
|
3
|
+
module Octopolo
|
4
|
+
module GitHub
|
5
|
+
class PullRequestCreator
|
6
|
+
include ConfigWrapper
|
7
|
+
# for instantiating the pull request creator
|
8
|
+
attr_accessor :repo_name
|
9
|
+
attr_accessor :options
|
10
|
+
# for caputuring the created pull request information
|
11
|
+
attr_accessor :number
|
12
|
+
attr_accessor :pull_request_data
|
13
|
+
|
14
|
+
# Public: Create a pull request for the given repo with the given options
|
15
|
+
#
|
16
|
+
# repo_name - Full name ("account/repo") of the repo in question
|
17
|
+
# options - Hash of pull request information
|
18
|
+
# title: Title of the pull request
|
19
|
+
# destination_branch: Which branch to merge into
|
20
|
+
# source_branch: Which branch to be merged
|
21
|
+
def initialize repo_name, options
|
22
|
+
self.repo_name = repo_name
|
23
|
+
self.options = options
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Create a pull request for the given repo with the given options
|
27
|
+
#
|
28
|
+
# repo_name - Full name ("account/repo") of the repo in question
|
29
|
+
# options - Hash of pull request information
|
30
|
+
# title: Title of the pull request
|
31
|
+
# destination_branch: Which branch to merge into
|
32
|
+
# source_branch: Which branch to be merged
|
33
|
+
#
|
34
|
+
# Returns the PullRequestCreator instance
|
35
|
+
def self.perform repo_name, options
|
36
|
+
new(repo_name, options).tap do |creator|
|
37
|
+
creator.perform
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: Create the pull request
|
42
|
+
#
|
43
|
+
# Returns an array with the first element being the pull request's
|
44
|
+
# number, the second being a Mash of the response from GitHub's API
|
45
|
+
def perform
|
46
|
+
result = GitHub.create_pull_request(repo_name, destination_branch, source_branch, title, body)
|
47
|
+
# capture the information
|
48
|
+
self.number = result.number
|
49
|
+
self.pull_request_data = result
|
50
|
+
rescue => e
|
51
|
+
raise CannotCreate, e.message
|
52
|
+
end
|
53
|
+
|
54
|
+
# Public: The created pull request's details
|
55
|
+
def pull_request_data
|
56
|
+
@pull_request_data || raise(NotYetCreated)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Public: The created pull request's number
|
60
|
+
def number
|
61
|
+
@number || raise(NotYetCreated)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Branch to merge the pull request into
|
65
|
+
#
|
66
|
+
# Returns a String with the branch name
|
67
|
+
def destination_branch
|
68
|
+
options[:destination_branch] || raise(MissingAttribute)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Public: Branch to merge into the destination branch
|
72
|
+
#
|
73
|
+
# Returns a String with the branch name
|
74
|
+
def source_branch
|
75
|
+
options[:source_branch] || raise(MissingAttribute)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Public: Title of the pull request
|
79
|
+
#
|
80
|
+
# Returns a String with the title
|
81
|
+
def title
|
82
|
+
options[:title] || raise(MissingAttribute)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Public: The Pivotal Tracker story IDs associated with the pull request
|
86
|
+
#
|
87
|
+
# Returns an Array of Strings
|
88
|
+
def pivotal_ids
|
89
|
+
options[:pivotal_ids] || []
|
90
|
+
end
|
91
|
+
|
92
|
+
# Public: Jira Issue IDs associated with the pull request
|
93
|
+
#
|
94
|
+
# Returns an Array of Strings
|
95
|
+
def jira_ids
|
96
|
+
options[:jira_ids] || []
|
97
|
+
end
|
98
|
+
|
99
|
+
# Public: Jira Url associated with the pull request
|
100
|
+
#
|
101
|
+
# Returns Jira Url
|
102
|
+
def jira_url
|
103
|
+
config.jira_url
|
104
|
+
end
|
105
|
+
|
106
|
+
# Public: The body (primary copy) of the pull request
|
107
|
+
#
|
108
|
+
# Returns a String
|
109
|
+
def body
|
110
|
+
Renderer.render Renderer::PULL_REQUEST_BODY, body_locals
|
111
|
+
end
|
112
|
+
|
113
|
+
# Public: The local variables to pass into the template
|
114
|
+
def body_locals
|
115
|
+
{
|
116
|
+
pivotal_ids: pivotal_ids,
|
117
|
+
jira_ids: jira_ids,
|
118
|
+
jira_url: jira_url,
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
MissingAttribute = Class.new(StandardError)
|
123
|
+
NotYetCreated = Class.new(StandardError)
|
124
|
+
CannotCreate = Class.new(StandardError)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Octopolo
|
2
|
+
module GitHub
|
3
|
+
class User
|
4
|
+
@cache ||= {}
|
5
|
+
|
6
|
+
attr_accessor :login
|
7
|
+
|
8
|
+
# Public: Instantiate a new User
|
9
|
+
#
|
10
|
+
# login - The login (username) of the given user
|
11
|
+
def initialize login
|
12
|
+
self.login = login
|
13
|
+
end
|
14
|
+
|
15
|
+
# Public: The real name of the author
|
16
|
+
#
|
17
|
+
# If the user has a name in GitHub, #author_name returns this. Otherwise
|
18
|
+
# returns the given login.
|
19
|
+
#
|
20
|
+
# Returns a String containing the name
|
21
|
+
def author_name
|
22
|
+
user_data.name || login
|
23
|
+
end
|
24
|
+
|
25
|
+
# Private: The raw GitHub API data for the user
|
26
|
+
#
|
27
|
+
# Returns a Hashie::Mash containing the data
|
28
|
+
def user_data
|
29
|
+
User.user_data login
|
30
|
+
end
|
31
|
+
|
32
|
+
# Private: The raw GitHub API data for the given login
|
33
|
+
#
|
34
|
+
# Returns a Hashie::Mash containing the data
|
35
|
+
def self.user_data login
|
36
|
+
@cache[login] ||= GitHub.user login
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'jiralicious'
|
2
|
+
|
3
|
+
module Octopolo
|
4
|
+
module Jira
|
5
|
+
class StoryCommenter
|
6
|
+
include ConfigWrapper
|
7
|
+
|
8
|
+
attr_accessor :issue
|
9
|
+
attr_accessor :comment
|
10
|
+
|
11
|
+
def initialize(issue_id, comment)
|
12
|
+
Jiralicious.configure do |jira_config|
|
13
|
+
jira_config.username = config.jira_user
|
14
|
+
jira_config.password = config.jira_password
|
15
|
+
jira_config.uri = config.jira_url
|
16
|
+
end
|
17
|
+
self.issue = Jiralicious::Issue.find issue_id
|
18
|
+
self.comment = comment
|
19
|
+
end
|
20
|
+
|
21
|
+
def perform
|
22
|
+
issue.comments.add(comment)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|