capsulecd 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +95 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +9 -0
  7. data/Dockerfile +16 -0
  8. data/Dockerfile.chef +26 -0
  9. data/Dockerfile.javascript +7 -0
  10. data/Dockerfile.node +7 -0
  11. data/Dockerfile.python +7 -0
  12. data/Dockerfile.ruby +4 -0
  13. data/FEATURES.md +12 -0
  14. data/Gemfile +26 -0
  15. data/LICENSE.md +22 -0
  16. data/README.md +227 -0
  17. data/Rakefile +43 -0
  18. data/bin/capsulecd +4 -0
  19. data/capsulecd.gemspec +27 -0
  20. data/circle.yml +24 -0
  21. data/lib/capsulecd/base/common/git_utils.rb +90 -0
  22. data/lib/capsulecd/base/common/validation_utils.rb +22 -0
  23. data/lib/capsulecd/base/configuration.rb +151 -0
  24. data/lib/capsulecd/base/engine.rb +163 -0
  25. data/lib/capsulecd/base/runner/circleci.rb +37 -0
  26. data/lib/capsulecd/base/runner/default.rb +38 -0
  27. data/lib/capsulecd/base/source/github.rb +183 -0
  28. data/lib/capsulecd/base/transform_engine.rb +62 -0
  29. data/lib/capsulecd/chef/chef_engine.rb +172 -0
  30. data/lib/capsulecd/chef/chef_helper.rb +29 -0
  31. data/lib/capsulecd/cli.rb +64 -0
  32. data/lib/capsulecd/error.rb +51 -0
  33. data/lib/capsulecd/javascript/javascript_engine.rb +213 -0
  34. data/lib/capsulecd/node/node_engine.rb +141 -0
  35. data/lib/capsulecd/python/python_engine.rb +157 -0
  36. data/lib/capsulecd/ruby/ruby_engine.rb +191 -0
  37. data/lib/capsulecd/ruby/ruby_helper.rb +60 -0
  38. data/lib/capsulecd/version.rb +3 -0
  39. data/lib/capsulecd.rb +16 -0
  40. data/logo.svg +1 -0
  41. data/spec/fixtures/chef/cookbook_analogj_test/CHANGELOG.md +3 -0
  42. data/spec/fixtures/chef/cookbook_analogj_test/Gemfile +18 -0
  43. data/spec/fixtures/chef/cookbook_analogj_test/LICENSE +21 -0
  44. data/spec/fixtures/chef/cookbook_analogj_test/README.md +13 -0
  45. data/spec/fixtures/chef/cookbook_analogj_test/Rakefile +1 -0
  46. data/spec/fixtures/chef/cookbook_analogj_test/Thorfile +12 -0
  47. data/spec/fixtures/chef/cookbook_analogj_test/chefignore +94 -0
  48. data/spec/fixtures/chef/cookbook_analogj_test/metadata.rb +5 -0
  49. data/spec/fixtures/chef/cookbook_analogj_test/recipes/default.rb +6 -0
  50. data/spec/fixtures/incorrect_configuration.yml +4 -0
  51. data/spec/fixtures/javascript/javascript_analogj_test/LICENSE +21 -0
  52. data/spec/fixtures/javascript/javascript_analogj_test/README.md +2 -0
  53. data/spec/fixtures/javascript/javascript_analogj_test/package.json +19 -0
  54. data/spec/fixtures/node/npm_analogj_test/LICENSE +21 -0
  55. data/spec/fixtures/node/npm_analogj_test/README.md +2 -0
  56. data/spec/fixtures/node/npm_analogj_test/package.json +19 -0
  57. data/spec/fixtures/python/pip_analogj_test/LICENSE +21 -0
  58. data/spec/fixtures/python/pip_analogj_test/MANIFEST.in +1 -0
  59. data/spec/fixtures/python/pip_analogj_test/README.md +1 -0
  60. data/spec/fixtures/python/pip_analogj_test/VERSION +1 -0
  61. data/spec/fixtures/python/pip_analogj_test/setup.cfg +5 -0
  62. data/spec/fixtures/python/pip_analogj_test/setup.py +80 -0
  63. data/spec/fixtures/python/pip_analogj_test/tox.ini +14 -0
  64. data/spec/fixtures/ruby/gem_analogj_test/Gemfile +4 -0
  65. data/spec/fixtures/ruby/gem_analogj_test/LICENSE.txt +21 -0
  66. data/spec/fixtures/ruby/gem_analogj_test/README.md +41 -0
  67. data/spec/fixtures/ruby/gem_analogj_test/Rakefile +6 -0
  68. data/spec/fixtures/ruby/gem_analogj_test/bin/console +14 -0
  69. data/spec/fixtures/ruby/gem_analogj_test/bin/setup +8 -0
  70. data/spec/fixtures/ruby/gem_analogj_test/gem_analogj_test.gemspec +25 -0
  71. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test/version.rb +3 -0
  72. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test.rb +5 -0
  73. data/spec/fixtures/ruby/gem_analogj_test/spec/gem_analogj_test_spec.rb +7 -0
  74. data/spec/fixtures/ruby/gem_analogj_test/spec/spec_helper.rb +2 -0
  75. data/spec/fixtures/ruby/gem_analogj_test-0.1.4.gem +0 -0
  76. data/spec/fixtures/sample_chef_configuration.yml +8 -0
  77. data/spec/fixtures/sample_configuration.yml +7 -0
  78. data/spec/fixtures/sample_global_configuration.yml +23 -0
  79. data/spec/fixtures/sample_node_configuration.yml +7 -0
  80. data/spec/fixtures/sample_python_configuration.yml +8 -0
  81. data/spec/fixtures/sample_repo_configuration.yml +22 -0
  82. data/spec/fixtures/sample_ruby_configuration.yml +5 -0
  83. data/spec/fixtures/vcr_cassettes/chef_build_step.yml +636 -0
  84. data/spec/fixtures/vcr_cassettes/gem_build_step.yml +653 -0
  85. data/spec/fixtures/vcr_cassettes/gem_build_step_without_version_rb.yml +653 -0
  86. data/spec/fixtures/vcr_cassettes/integration_chef.yml +1399 -0
  87. data/spec/fixtures/vcr_cassettes/integration_node.yml +1388 -0
  88. data/spec/fixtures/vcr_cassettes/integration_python.yml +1388 -0
  89. data/spec/fixtures/vcr_cassettes/integration_ruby.yml +1377 -0
  90. data/spec/fixtures/vcr_cassettes/node_build_step.yml +647 -0
  91. data/spec/fixtures/vcr_cassettes/pip_build_step.yml +653 -0
  92. data/spec/lib/capsulecd/base/configuration_spec.rb +75 -0
  93. data/spec/lib/capsulecd/base/engine_spec.rb +51 -0
  94. data/spec/lib/capsulecd/base/source/github_spec.rb +253 -0
  95. data/spec/lib/capsulecd/base/transform_engine_spec.rb +55 -0
  96. data/spec/lib/capsulecd/chef/chef_engine_spec.rb +114 -0
  97. data/spec/lib/capsulecd/cli_spec.rb +57 -0
  98. data/spec/lib/capsulecd/node/node_engine_spec.rb +113 -0
  99. data/spec/lib/capsulecd/python/python_engine_spec.rb +118 -0
  100. data/spec/lib/capsulecd/ruby/ruby_engine_spec.rb +128 -0
  101. data/spec/spec_helper.rb +105 -0
  102. data/spec/support/file_system.rb +21 -0
  103. data/spec/support/package_types.rb +11 -0
  104. metadata +281 -0
@@ -0,0 +1,90 @@
1
+ require 'git'
2
+ require 'mkgitignore'
3
+
4
+ module CapsuleCD
5
+ class GitUtils
6
+ def self.clone(parent_path, repository_name, git_remote)
7
+ repo_path = File.expand_path("#{parent_path}/#{repository_name}/")
8
+ if !File.directory?(repo_path)
9
+ FileUtils.mkdir_p(repo_path)
10
+ else
11
+ fail 'the repository path already exists, this should never happen'
12
+ end
13
+
14
+ repo = Git.clone(git_remote, '', path: repo_path)
15
+ repo.config('user.name', 'CapsuleCD')
16
+ repo.config('user.email', 'CapsuleCD@users.noreply.github.com')
17
+ repo.dir.to_s
18
+ end
19
+
20
+ def self.fetch(repo_path, remote_ref, local_branch)
21
+ repo = Git.open(repo_path)
22
+ repo.fetch(['origin', "#{remote_ref}:#{local_branch}"])
23
+ end
24
+
25
+ def self.checkout(repo_path, branch)
26
+ repo = Git.open(repo_path)
27
+ repo.checkout(branch)
28
+ end
29
+
30
+ def self.commit(repo_path, message, _all = true)
31
+ repo = Git.open(repo_path)
32
+ repo.add(all: true)
33
+ repo.commit_all(message)
34
+ end
35
+
36
+ def self.tag(repo_path, version)
37
+ repo = Git.open(repo_path)
38
+ repo.add_tag(version)
39
+ end
40
+
41
+ def self.push(repo_path, local_branch, remote_branch)
42
+ repo = Git.open(repo_path)
43
+ repo.push('origin', "#{local_branch}:#{remote_branch}", tags: true)
44
+ end
45
+
46
+ def self.pull(repo_path)
47
+ repo = Git.open(repo_path)
48
+ repo.pull
49
+ end
50
+
51
+ # gets the commit of the latest tag on current branch
52
+ def self.get_latest_tag_commit(repo_path)
53
+ repo = Git.open(repo_path)
54
+ tag_name = repo.describe(nil,:abbrev => 0, :exact_match => true)
55
+
56
+ #we're dealing with annotated tags, which have thier own git commit, which causes issues with the github release api
57
+ # so we're manually creating a Git Object with the data we need (.sha and .name)
58
+ tag_sha = repo.tag(tag_name).log.first.sha
59
+
60
+ Git::Object::Tag.new(repo,tag_sha, tag_name)
61
+ end
62
+
63
+ def self.generate_changelog(repo_path, base_sha, head_sha, full_name)
64
+ repo = Git.open(repo_path)
65
+ markdown = "Timestamp | SHA | Message | Author \n"
66
+ markdown += "------------- | ------------- | ------------- | ------------- \n"
67
+ repo.log.between(base_sha, head_sha).each do |commit|
68
+ markdown += "#{commit.date.strftime('%Y-%m-%dT%H:%M:%SZ')} | [`#{commit.sha.slice 0..8}`](https://github.com/#{full_name}/commit/#{commit.sha}) | #{commit.message.gsub('|', '!').gsub(/[\n]+/,' ') || '--'} | #{commit.author.name} \n"
69
+ end
70
+ markdown
71
+ end
72
+
73
+ def self.create_gitignore(repo_path, ignore_types)
74
+ #store current working directory, and change to the cookbook
75
+ wd = Dir.getwd
76
+ Dir.chdir(repo_path)
77
+
78
+ begin
79
+ #download gitignore templates and write them
80
+ templates = Mkgitignore::searchForTemplatesWithNames(ignore_types)
81
+ gitignore = String.new
82
+ templates.each { |t| gitignore += Mkgitignore::downloadFromURL(t["url"], t["name"]) }
83
+ Mkgitignore::writeGitignore(gitignore, true)
84
+ ensure
85
+ #restore previous working dir
86
+ Dir.chdir(wd)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,22 @@
1
+ require 'capsulecd'
2
+ module CapsuleCD
3
+ class ValidationUtils
4
+ def self.validate_repo_payload(repo_payload)
5
+ unless repo_payload['sha']
6
+ fail CapsuleCD::Error::SourcePayloadFormatError, 'Incorrectly formatted payload, missing "sha1" key'
7
+ end
8
+ unless repo_payload['ref']
9
+ fail CapsuleCD::Error::SourcePayloadFormatError, 'Incorrectly formatted payload, missing "ref" key'
10
+ end
11
+ unless repo_payload['repo']
12
+ fail CapsuleCD::Error::SourcePayloadFormatError, 'Incorrectly formatted payload, missing "repo" key'
13
+ end
14
+ unless repo_payload['repo']['clone_url']
15
+ fail CapsuleCD::Error::SourcePayloadFormatError, 'Incorrectly formatted payload, missing "clone_url" key'
16
+ end
17
+ unless repo_payload['repo']['name']
18
+ fail CapsuleCD::Error::SourcePayloadFormatError, 'Incorrectly formatted payload, missing "name" key'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,151 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ require 'base64'
4
+ module CapsuleCD
5
+ class Configuration
6
+ # Order of inheritance: file <- environment <- cli options
7
+ # <- means 'overridden by', eg. file overridden by environment vars
8
+ # @param [String] config_path The path to the configuration file
9
+ def initialize(options={})
10
+ @options = options
11
+ @config_path = @options[:config_file]
12
+
13
+ populate_defaults
14
+ populate_system_config_file
15
+ populate_runner_overrides
16
+ populate_env_overrides
17
+ populate_cli_overrides
18
+ standardize_settings
19
+ end
20
+
21
+ # Cli config, shouldnt be set via environmental variables (will be overridden)
22
+ attr_reader :package_type
23
+ attr_reader :source
24
+ attr_reader :runner
25
+ attr_reader :dry_run
26
+
27
+ # General config
28
+ attr_reader :config_path
29
+ attr_reader :configuration
30
+
31
+ # Source config (any credentials added here should also be added to the spec_helper.rb VCR config)
32
+ attr_reader :source_git_parent_path
33
+ attr_reader :source_github_api_endpoint
34
+ attr_reader :source_github_web_endpoint
35
+ attr_reader :source_github_access_token
36
+
37
+ # Runner config
38
+ attr_reader :runner_pull_request
39
+ attr_reader :runner_sha
40
+ attr_reader :runner_branch
41
+ attr_reader :runner_clone_url
42
+ attr_reader :runner_repo_full_name
43
+ attr_reader :runner_repo_name
44
+
45
+ # Package auth/config (any credentials added here should also be added to the spec_helper.rb VCR config)
46
+ attr_reader :chef_supermarket_username
47
+ attr_reader :npm_auth_token
48
+ attr_reader :pypi_username
49
+ attr_reader :pypi_password
50
+ attr_reader :chef_supermarket_type
51
+ attr_reader :rubygems_api_key
52
+ def chef_supermarket_key
53
+ @chef_supermarket_key.to_s.empty? ? nil : Base64.strict_decode64(@chef_supermarket_key)
54
+ end
55
+
56
+ # Engine config
57
+ attr_reader :engine_disable_test
58
+ attr_reader :engine_disable_minification
59
+ attr_reader :engine_disable_lint
60
+ attr_reader :engine_disable_coverage
61
+ attr_reader :engine_cmd_test
62
+ attr_reader :engine_cmd_minification
63
+ attr_reader :engine_cmd_lint
64
+ attr_reader :engine_cmd_coverage
65
+ attr_reader :engine_version_bump_type
66
+
67
+ def populate_repo_config_file(repo_local_path)
68
+ repo_config_file_path = repo_local_path + '/capsule.yml'
69
+ load_config_file(repo_config_file_path)
70
+ populate_runner_overrides
71
+ populate_env_overrides
72
+ populate_cli_overrides
73
+ standardize_settings
74
+ end
75
+
76
+ # The raw parsed configuration file, system level, a repo level configuration file will override settings in this file.
77
+ def populate_system_config_file
78
+ load_config_file(@config_path)
79
+ end
80
+
81
+ private
82
+ # These are defaults for engine settings. They can be overridden via configuration files or env variables
83
+ def populate_defaults
84
+ @engine_version_bump_type = :patch # can be :major, :minor, :patch
85
+ @chef_supermarket_type = 'Other'
86
+ end
87
+
88
+ def load_config_file(path)
89
+ if !path || !File.exist?(path)
90
+ puts 'The configuration file could not be found. Using defaults'
91
+ return
92
+ end
93
+ file = File.open(path).read
94
+ unserialize(file)
95
+ end
96
+
97
+
98
+ def populate_runner_overrides
99
+ @runner = :circleci unless ENV['CIRCLECI'].to_s.empty?
100
+ populate_runner
101
+ end
102
+
103
+ def populate_runner
104
+ if (@runner == :circleci)
105
+ # parse the PR# from the environment variable, eg. https://github.com/AnalogJ/cookbook_analogj_test/pull/9
106
+ @runner_pull_request ||= File.basename(URI.parse(ENV['CI_PULL_REQUEST']).path).to_i # => baz
107
+ @runner_sha ||= ENV['CIRCLE_SHA1']
108
+ @runner_branch ||= ENV['CIRCLE_BRANCH']
109
+ @runner_clone_url ||= 'https://github.com/' + ENV['CIRCLE_PROJECT_USERNAME'] + '/' + ENV['CIRCLE_PROJECT_REPONAME'] + '.git'
110
+ @runner_repo_name ||= ENV['CIRCLE_PROJECT_REPONAME']
111
+ @runner_repo_full_name ||= ENV['CIRCLE_PROJECT_USERNAME'] + '/' + ENV['CIRCLE_PROJECT_REPONAME']
112
+ end
113
+ end
114
+
115
+ def populate_env_overrides
116
+ # override config file with env variables.
117
+ ENV.each do|key, value|
118
+ config_key = key.dup
119
+ if config_key.start_with?('CAPSULE_') && !value.to_s.empty?
120
+ config_key.slice!('CAPSULE_')
121
+ config_key.downcase!
122
+
123
+ # override instance variable
124
+ instance_variable_set('@' + config_key, value)
125
+ end
126
+ end
127
+ end
128
+
129
+ def populate_cli_overrides
130
+ # then override with cli options
131
+ @options.each do|key, value|
132
+ instance_variable_set('@' + key.to_s, value)
133
+ end
134
+ end
135
+
136
+ # certain settings are symbols, so make sure that any settings that are specified via a string are converted to the correct type.
137
+ def standardize_settings
138
+ # set types if missing
139
+ @engine_version_bump_type = @engine_version_bump_type.to_sym if @engine_version_bump_type.is_a? String
140
+ end
141
+
142
+ def unserialize(string)
143
+ obj = YAML.load(string)
144
+ obj.keys.each do |key|
145
+ next if %w(source_configure source_process_pull_request_payload source_process_push_payload runner_retrieve_payload build_step test_step package_step source_release release_step).include?(key)
146
+ instance_variable_set('@' + key, obj[key])
147
+ end
148
+ obj
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,163 @@
1
+ require_relative 'runner/default'
2
+ require_relative 'configuration'
3
+ require 'pp'
4
+ module CapsuleCD
5
+ class Engine
6
+ attr_reader :config
7
+
8
+ def initialize(options)
9
+ @config = CapsuleCD::Configuration.new(options)
10
+ if @config.source == :github
11
+ require_relative 'source/github'
12
+ self.class.send(:include, CapsuleCD::Source::Github)
13
+ else
14
+ fail CapsuleCD::Error::SourceUnspecifiedError, 'No source defined.'
15
+ end
16
+
17
+ if @config.runner == :circleci
18
+ require_relative 'runner/circleci'
19
+ self.class.send(:include, CapsuleCD::Runner::Circleci)
20
+ else
21
+ self.class.send(:include, CapsuleCD::Runner::Default)
22
+ end
23
+ end
24
+
25
+ def start
26
+ # start the source, and whatever work needs to be done there.
27
+ # MUST set @source_git_parent_path
28
+ # MUST set @source_client
29
+ pre_source_configure
30
+ source_configure
31
+ post_source_configure
32
+
33
+ # runner must determine if this is a pull request or a push.
34
+ # if it's a pull request the runner must retrieve the pull request payload and return it
35
+ # if its a push, the runner must retrieve the push payload and return it
36
+ # the variable @runner_is_pullrequest will be true if a pull request was created.
37
+ # MUST set runner_is_pullrequest
38
+ # REQUIRES source_client
39
+ pre_runner_retrieve_payload
40
+ payload = runner_retrieve_payload(@options)
41
+ post_runner_retrieve_payload
42
+
43
+ if @runner_is_pullrequest
44
+ # all capsule CD processing will be kicked off via a payload. In this case the payload is the pull request data.
45
+ # should check if the pull request opener even has permissions to create a release.
46
+ # all sources should process the payload by downloading a git repository that contains the master branch merged with the test branch
47
+ # MUST set source_git_local_path
48
+ # MUST set source_git_local_branch
49
+ # MUST set source_git_base_info
50
+ # MUST set source_git_head_info
51
+ # REQUIRES source_client
52
+ pre_source_process_pull_request_payload
53
+ source_process_pull_request_payload(payload)
54
+ post_source_process_pull_request_payload
55
+ else
56
+ # start processing the payload, which should result in a local git repository that we
57
+ # can begin to test. Since this is a push, no packaging is required
58
+ # MUST set source_git_local_path
59
+ # MUST set source_git_local_branch
60
+ # MUST set source_git_head_info
61
+ # REQUIRES source_client
62
+ pre_source_process_push_payload
63
+ source_process_push_payload(payload)
64
+ post_source_process_push_payload
65
+ end
66
+
67
+ # now that the payload has been processed we can begin by building the code.
68
+ # this may be creating missing files/default structure, compilation, version bumping, etc.
69
+
70
+ source_notify('build') do
71
+ pre_build_step
72
+ build_step
73
+ post_build_step
74
+ end
75
+
76
+ # this step should download dependencies, run the package test runner(s) (eg. npm test, rake test, kitchen test)
77
+ # REQUIRES @config.engine_cmd_test
78
+ # REQUIRES @config.engine_disable_test
79
+ source_notify('test') do
80
+ pre_test_step
81
+ test_step
82
+ post_test_step
83
+ end
84
+
85
+ # this step should commit any local changes and create a git tag. Nothing should be pushed to remote repository
86
+ source_notify('package') do
87
+ pre_package_step
88
+ package_step
89
+ post_package_step
90
+ end
91
+
92
+ if @runner_is_pullrequest
93
+ # this step should push the release to the package repository (ie. npm, chef supermarket, rubygems)
94
+ source_notify('release') do
95
+ pre_release_step
96
+ release_step
97
+ post_release_step
98
+ end
99
+
100
+ # this step should push the merged, tested and version updated code up to the source code repository
101
+ # this step should also do any source specific releases (github release, asset uploading, etc)
102
+ source_notify('source release') do
103
+ pre_source_release
104
+ source_release
105
+ post_source_release
106
+ end
107
+ end
108
+
109
+ # rescue => ex #TODO if you enable this rescue block, hooks stop working.
110
+ # TODO: it shouldnt be required anylonger because source_notify will handle rescueing the failures.
111
+ # puts ex
112
+ #
113
+ # self.run_hook :pre_source_process_failure, ex
114
+ # source_process_failure(ex)
115
+ # self.run_hook :post_source_process_failure, ex
116
+ end
117
+
118
+ # base methods
119
+ def pre_source_configure; puts 'pre_source_configure'; end
120
+ def post_source_configure; puts 'post_source_configure'; end
121
+ def pre_source_process_pull_request_payload; puts 'pre_source_process_pull_request_payload'; end
122
+ def post_source_process_pull_request_payload; puts 'post_source_process_pull_request_payload'; end
123
+ def pre_source_process_push_payload; puts 'pre_source_process_push_payload'; end
124
+ def post_source_process_push_payload; puts 'post_source_process_push_payload'; end
125
+ def pre_source_release; puts 'pre_source_release'; end
126
+ def post_source_release; puts 'post_source_release'; end
127
+
128
+ def pre_runner_retrieve_payload; puts 'pre_runner_retrieve_payload'; end
129
+ def post_runner_retrieve_payload; puts 'post_runner_retrieve_payload'; end
130
+
131
+ def pre_build_step; puts 'pre_build_step'; end
132
+ def build_step; puts 'build_step'; end
133
+ def post_build_step; puts 'post_build_step'; end
134
+ def pre_test_step; puts 'pre_test_step'; end
135
+ def test_step; puts 'test_step'; end
136
+ def post_test_step; puts 'post_test_step'; end
137
+ def pre_package_step; puts 'pre_package_step'; end
138
+ def package_step; puts 'package_step'; end
139
+ def post_package_step; puts 'post_package_step'; end
140
+ def pre_release_step; puts 'pre_release_step'; end
141
+ def release_step; puts 'release_step'; end
142
+ def post_release_step; puts 'post_release_step'; end
143
+
144
+ protected
145
+
146
+ # determine which segment of the semvar version to bump/increment. The default (as specified in CapsuleCD::Configuration is :patch)
147
+ def bump_version(current_version)
148
+ next_version = current_version
149
+
150
+ if @config.engine_version_bump_type == :major
151
+ next_version.major = next_version.major + 1
152
+ next_version.minor = 0
153
+ next_version.patch = 0
154
+ elsif @config.engine_version_bump_type == :minor
155
+ next_version.minor = next_version.minor + 1
156
+ next_version.patch = 0
157
+ else
158
+ next_version.patch = next_version.patch + 1
159
+ end
160
+ return next_version
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,37 @@
1
+ require 'uri'
2
+ module CapsuleCD
3
+ module Runner
4
+ module Circleci
5
+ def runner_retrieve_payload(_options)
6
+ puts 'circleci runner_retrieve_payload'
7
+
8
+ # circleci only works with github, no need to parse @options[:source]
9
+ # here are the environmental variables we need to handle:
10
+ # https://circleci.com/docs/environment-variables
11
+
12
+ if @config.runner_pull_request.to_s.empty?
13
+ puts 'This is not a pull request. No automatic continuous deployment processing required. Continuous Integration testing will continue.'
14
+ @runner_is_pullrequest = false
15
+ # make this as similar to the pull request payload as possible.
16
+ payload = {
17
+ 'head' => {
18
+ 'sha' => @config.runner_sha,
19
+ 'ref' => @config.runner_branch,
20
+ 'repo' => {
21
+ 'clone_url' => @config.runner_clone_url,
22
+ 'name' => @config.runner_repo_name,
23
+ 'full_name' => @config.runner_repo_full_name
24
+ }
25
+ }
26
+ }
27
+
28
+ payload
29
+ else
30
+ @runner_is_pullrequest = true
31
+ pull_request_number = @config.runner_pull_request.to_i
32
+ @source_client.pull_request(@config.runner_repo_full_name, pull_request_number)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ module CapsuleCD
2
+ module Runner
3
+ module Default
4
+ # TODO: this needs to be fleshed out/working. ie. Jenkins, Bamboo, GoCD, Drone, other self hosted services
5
+ def runner_retrieve_payload(_opts)
6
+ puts 'default runner_retrieve_payload'
7
+
8
+ # capsulecd only works with github, no need to parse @options[:source]
9
+ # since we're the default handler, we have to verify that the required configuration options are available
10
+
11
+
12
+
13
+ if @config.runner_pull_request.to_s.empty?
14
+ puts 'This is not a pull request. No automatic continuous deployment processing required. Continuous Integration testing will continue.'
15
+ @runner_is_pullrequest = false
16
+ # make this as similar to the pull request payload as possible.
17
+ payload = {
18
+ 'head' => {
19
+ 'sha' => @config.runner_sha,
20
+ 'ref' => @config.runner_branch,
21
+ 'repo' => {
22
+ 'clone_url' => @config.runner_clone_url,
23
+ 'name' => @config.runner_repo_name,
24
+ 'full_name' => @config.runner_repo_full_name
25
+ }
26
+ }
27
+ }
28
+
29
+ payload
30
+ else
31
+ @runner_is_pullrequest = true
32
+ pull_request_number = @config.runner_pull_request.to_i
33
+ @source_client.pull_request(@config.runner_repo_full_name, pull_request_number)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end