Module: CapsuleCD::Source::Github

Defined in:
lib/capsulecd/base/source/github.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#source_clientObject

all of these instance variables are available for use within hooks



11
12
13
# File 'lib/capsulecd/base/source/github.rb', line 11

def source_client
  @source_client
end

#source_git_base_infoObject

Returns the value of attribute source_git_base_info.



12
13
14
# File 'lib/capsulecd/base/source/github.rb', line 12

def source_git_base_info
  @source_git_base_info
end

#source_git_head_infoObject

Returns the value of attribute source_git_head_info.



13
14
15
# File 'lib/capsulecd/base/source/github.rb', line 13

def source_git_head_info
  @source_git_head_info
end

#source_git_local_branchObject

Returns the value of attribute source_git_local_branch.



16
17
18
# File 'lib/capsulecd/base/source/github.rb', line 16

def source_git_local_branch
  @source_git_local_branch
end

#source_git_local_pathObject

Returns the value of attribute source_git_local_path.



15
16
17
# File 'lib/capsulecd/base/source/github.rb', line 15

def source_git_local_path
  @source_git_local_path
end

#source_git_parent_pathObject

Returns the value of attribute source_git_parent_path.



14
15
16
# File 'lib/capsulecd/base/source/github.rb', line 14

def source_git_parent_path
  @source_git_parent_path
end

#source_git_remoteObject

Returns the value of attribute source_git_remote.



17
18
19
# File 'lib/capsulecd/base/source/github.rb', line 17

def source_git_remote
  @source_git_remote
end

#source_release_artifactsObject

Returns the value of attribute source_release_artifacts.



19
20
21
# File 'lib/capsulecd/base/source/github.rb', line 19

def source_release_artifacts
  @source_release_artifacts
end

#source_release_commitObject

Returns the value of attribute source_release_commit.



18
19
20
# File 'lib/capsulecd/base/source/github.rb', line 18

def source_release_commit
  @source_release_commit
end

Instance Method Details

#source_configureObject

configure method will generate an authenticated client that can be used to comunicate with Github MUST set @source_git_parent_path MUST set @source_client



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/capsulecd/base/source/github.rb', line 26

def source_configure
  puts 'github source_configure'
  fail CapsuleCD::Error::SourceAuthenticationFailed, 'Missing github access token' unless @config.source_github_access_token

  @source_release_commit = nil
  @source_release_artifacts = []

  @source_git_parent_path = @config.source_git_parent_path || Dir.mktmpdir
  Octokit.auto_paginate = true
  Octokit.configure do |c|
    c.api_endpoint = @config.source_github_api_endpoint if @config.source_github_api_endpoint
    c.web_endpoint = @config.source_github_web_endpoint if @config.source_github_web_endpoint
  end
  @source_client = Octokit::Client.new(access_token: @config.source_github_access_token)
end

#source_notify(step, status = 'pending') ⇒ Object

requires @source_client requires @source_git_parent_path requires @source_git_base_info requires @source_git_head_info requires @config.engine_disable_cleanup



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/capsulecd/base/source/github.rb', line 163

def source_notify(step, status='pending')

  @source_client.create_status(@source_git_base_info['repo']['full_name'], @source_git_head_info['sha'], status,
    context: 'CapsuleCD',
    target_url: 'http://www.github.com/AnalogJ/capsulecd',
    description: "Started '#{step}' step. Pull request will be merged automatically when complete.")

  yield

rescue => ex
  puts 'github source_process_failure'
  FileUtils.remove_entry_secure @source_git_parent_path if (Dir.exists?(@source_git_parent_path) && !@config.engine_disable_cleanup)
  @source_client.create_status(@source_git_base_info['repo']['full_name'], @source_git_head_info['sha'], 'failure',
                               context: 'CapsuleCD',
                               target_url: 'http://www.github.com/AnalogJ/capsulecd',
                               description: ex.message.slice(0..135))
  raise
end

#source_process_pull_request_payload(payload) ⇒ Object

all capsule CD processing will be kicked off via a payload. In Github’s case, the payload is the pull request data. should check if the pull request opener even has permissions to create a release. all sources should process the payload by downloading a git repository that contains the master branch merged with the test branch MUST set source_git_local_path MUST set source_git_local_branch MUST set source_git_base_info MUST set source_git_head_info REQUIRES source_client REQUIRES source_git_parent_path



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/capsulecd/base/source/github.rb', line 75

def source_process_pull_request_payload(payload)
  puts 'github source_process_payload'

  # validate the github specific payload options
  unless (payload['state'] == 'open')
    fail CapsuleCD::Error::SourcePayloadUnsupported, 'Pull request has an invalid action'
  end
  unless (payload['base']['repo']['default_branch'] == payload['base']['ref'])
    fail CapsuleCD::Error::SourcePayloadUnsupported, 'Pull request is not being created against the default branch of this repository (usually master)'
  end
  # check the payload push user.

  # TODO: figure out how to do optional authenication. possible options, Source USER, token based auth, no auth when used with capsulecd.com.
  # unless @source_client.collaborator?(payload['base']['repo']['full_name'], payload['user']['login'])
  #
  #   @source_client.add_comment(payload['base']['repo']['full_name'], payload['number'], CapsuleCD::BotUtils.pull_request_comment)
  #   fail CapsuleCD::Error::SourceUnauthorizedUser, 'Pull request was opened by an unauthorized user'
  # end

  # set the processed base/head info,
  @source_git_base_info = payload['base']
  @source_git_head_info = payload['head']
  CapsuleCD::ValidationUtils.validate_repo_payload(@source_git_base_info)
  CapsuleCD::ValidationUtils.validate_repo_payload(@source_git_head_info)

  # set the remote url, with embedded token
  uri = URI.parse(payload['base']['repo']['clone_url'])
  uri.user = @config.source_github_access_token
  @source_git_remote = uri.to_s

  # clone the merged branch
  # https://sethvargo.com/checkout-a-github-pull-request/
  # https://coderwall.com/p/z5rkga/github-checkout-a-pull-request-as-a-branch
  @source_git_local_path = CapsuleCD::GitUtils.clone(@source_git_parent_path, @source_git_head_info['repo']['name'], @source_git_remote)
  @source_git_local_branch = "pr_#{payload['number']}"
  CapsuleCD::GitUtils.fetch(@source_git_local_path, "refs/pull/#{payload['number']}/merge", @source_git_local_branch)
  CapsuleCD::GitUtils.checkout(@source_git_local_path, @source_git_local_branch)

  # show a processing message on the github PR.
  @source_client.create_status(payload['base']['repo']['full_name'], @source_git_head_info['sha'], 'pending',
                               context: 'CapsuleCD',
                               target_url: 'http://www.github.com/AnalogJ/capsulecd',
                               description: 'Started processing package. Pull request will be merged automatically when complete.')
end

#source_process_push_payload(payload) ⇒ Object

all capsule CD processing will be kicked off via a payload. In Github’s case, the payload is the webhook data. should check if the pull request opener even has permissions to create a release. all sources should process the payload by downloading a git repository that contains the master branch merged with the test branch MUST set source_git_local_path MUST set source_git_local_branch MUST set source_git_head_info REQUIRES source_git_parent_path



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/capsulecd/base/source/github.rb', line 49

def source_process_push_payload(payload)
  # set the processed head info
  @source_git_head_info = payload['head']
  CapsuleCD::ValidationUtils.validate_repo_payload(@source_git_head_info)

  # set the remote url, with embedded token
  uri = URI.parse(@source_git_head_info['repo']['clone_url'])
  uri.user = @config.source_github_access_token
  @source_git_remote = uri.to_s
  @source_git_local_branch = @source_git_head_info['repo']['ref']
  # clone the merged branch
  # https://sethvargo.com/checkout-a-github-pull-request/
  # https://coderwall.com/p/z5rkga/github-checkout-a-pull-request-as-a-branch
  @source_git_local_path = CapsuleCD::GitUtils.clone(@source_git_parent_path, @source_git_head_info['repo']['name'], @source_git_remote)
  CapsuleCD::GitUtils.checkout(@source_git_local_path, @source_git_head_info['repo']['sha1'])
end

#source_releaseObject

REQUIRES source_client REQUIRES source_release_commit REQUIRES source_git_local_path REQUIRES source_git_local_branch REQUIRES source_git_base_info REQUIRES source_git_head_info REQUIRES source_release_artifacts REQUIRES source_git_parent_path



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/capsulecd/base/source/github.rb', line 128

def source_release
  puts 'github source_release'

  # push the version bumped metadata file + newly created files to
  CapsuleCD::GitUtils.push(@source_git_local_path, @source_git_local_branch, @source_git_base_info['ref'])
  # sleep because github needs time to process the new tag.
  sleep 5

  # calculate the release sha
  release_sha = ('0' * (40 - @source_release_commit.sha.strip.length)) + @source_release_commit.sha.strip

  # get the release changelog
  release_body = CapsuleCD::GitUtils.generate_changelog(@source_git_local_path, @source_git_base_info['sha'], @source_git_head_info['sha'], @source_git_base_info['repo']['full_name'])

  release = @source_client.create_release(@source_git_base_info['repo']['full_name'], @source_release_commit.name,       target_commitish: release_sha,
                                                                                                                         name: @source_release_commit.name,
                                                                                                                         body: release_body)

  @source_release_artifacts.each do |release_artifact|
    @source_client.upload_asset(release[:url], release_artifact[:path], name: release_artifact[:name])
  end

  FileUtils.remove_entry_secure @source_git_parent_path if Dir.exists?(@source_git_parent_path)
  # set the pull request status
  @source_client.create_status(@source_git_base_info['repo']['full_name'], @source_git_head_info['sha'], 'success',
                               context: 'CapsuleCD',
                               target_url: 'http://www.github.com/AnalogJ/capsulecd',
                               description: 'Pull-request was successfully merged, new release created.')
end