a2zdeploy 1.0.3 → 1.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ed53192adb1971f268124fc20fb11510ee31e06
4
- data.tar.gz: b49b25d81f158ae3ad8420761aa5559fd6d2c2bf
3
+ metadata.gz: 71b4475b48254171a7f88017f9dd1a66631c77c2
4
+ data.tar.gz: 5c2a54aabb1f19b8fc3c1f8ac9b06b58b38a83e8
5
5
  SHA512:
6
- metadata.gz: cc2e1fdf5f6d4681709a6c9b6c3d34b4e137708acd381b4317ba168609379c5ad41a1379a0604060644924d73491503258aafe29ef487c56bf804088712550a1
7
- data.tar.gz: f83acdd75516f2c3c373b8c5bb26c8cd74bb51a8f2ffdb903c84bb2a55de864d87c97a4a081fe8af86c373796f85634aa7ef6964f4884d5fb5fb90223cfa3adb
6
+ metadata.gz: a1976a841d9bab7db8db8e0d686bf168bcdce832f42e7f8d3e5588188cd7985e80d02aaa44a62295c249e128af12be442ad51f10f5eab6895ce60756b8691bb5
7
+ data.tar.gz: d743465fd4489912e8448244b7182475fd369374c3de8007ee7d810f530d970550bcfb56d0e1d1690160341069aa821a37a65a768a8aa1e46e8f74cd7c3eb38d
data/a2zdeploy.gemspec CHANGED
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'a2zdeploy'
3
- s.version = '1.0.3'
4
- s.date = '2016-01-19'
3
+ s.version = '1.0.4'
4
+ s.date = '2016-02-08'
5
5
  s.summary = 'Given a project dependency chain, updates versions, builds, tests, manages service and cloud settings as well as build environment configuration'
6
6
  s.description = 'Automated Upgrades Gem. Provides version upgrades, build and deployment configuration management'
7
7
  s.authors = ['Suresh Batta']
8
8
  s.email = 'subatta@hotmail.com'
9
- s.files = Dir['{test,lib,rakefile.rb}/**/*'] + ['a2zdeploy.gemspec', 'ReadMe.md']
9
+ s.files = Dir['{lib}/**/*'] + ['a2zdeploy.gemspec', 'ReadMe.md']
10
10
  s.homepage = 'http://rubygems.org/gems/a2zdeploy'
11
11
  s.license = 'MIT'
12
12
  end
data/lib/a2zdeploy.rb CHANGED
@@ -9,7 +9,9 @@ require_relative 'github_api'
9
9
  require_relative 'version_map'
10
10
  require_relative 'hash_extensions'
11
11
  require_relative 'input_validator'
12
+ require_relative 'rollback'
12
13
 
14
+ require 'rake'
13
15
  require 'addressable/uri'
14
16
  require 'azdeploy'
15
17
  require 'builder'
@@ -44,9 +44,7 @@ class DependencyTree
44
44
  if @dependency_map[current].has_key? GlobalConstants::NEXT
45
45
  next_node = @dependency_map[current][GlobalConstants::NEXT]
46
46
  next_node = @dependency_map[next_node]
47
- if !next_node.nil?
48
- next_node = Hashit.new next_node
49
- end
47
+ next_node = Hashit.new next_node if !next_node.nil?
50
48
  end
51
49
  end
52
50
 
data/lib/github_api.rb CHANGED
@@ -6,6 +6,11 @@
6
6
 
7
7
  module GithubApi
8
8
 
9
+ def GithubApi.CreateNewBranch new_branch, branch
10
+ puts "Creating new branch #{new_branch} from #{branch}..."
11
+ `git branch #{new_branch} #{branch}`
12
+ end
13
+
9
14
  def GithubApi.CheckoutNewBranch branch
10
15
  puts "Checking out new branch #{branch}..."
11
16
  `git checkout -b #{branch}`
@@ -37,7 +42,49 @@ module GithubApi
37
42
  `git checkout #{branch}`
38
43
  end
39
44
 
45
+ # Reverts commits from commit_hashes, expected order is newest to oldest
46
+ def GithubApi.RevertLocal branch, commit_hashes
47
+ puts "Reverting commits on local branch: #{branch}..."
48
+ `git checkout #{branch}`
49
+ recent_hash = commit_hashes[0]
50
+ past_hash = commit_hashes[-1]
51
+ `git --no-edit revert #{past_hash}^..#{recent_hash}`
52
+ end
53
+
54
+ def GithubApi.TagLocal commit_hash, tag_name, message
55
+ puts "Tagging commit hash: #{commit_hash} with #{tag_name}..."
56
+ `git tag -a #{tag_name} #{commit_hash} -m #{message}`
57
+ end
58
+
59
+ def GithubApi.GetRecentCommitHash branch
60
+ git_log_raw = `git log -1 #{branch}`
61
+ return GithubApi.GetCommitHashesFromLog(git_log_raw).first
62
+ end
63
+
64
+ def GithubApi.ShowCommitInfoLocal commit_hash
65
+ `git show --name-only #{commit_hash}`
66
+ end
67
+
68
+ def GithubApi.ForcePushBranch remote, branch
69
+ # use url substituted with un/pwd
70
+ #remote_url = GithubApi.InsertCredsInRemote remote
71
+ puts "Force Pushing #{branch} to #{remote}..."
72
+ `git push #{remote} #{branch} -f`
73
+ end
74
+
75
+ def GithubApi.InsertCredsInRemote remote_name
76
+ url = `git config --get remote.#{remote_name}.url`
77
+ url = GithubApi.InsertCredsInUrl(url) if !url.include? '@'
78
+ url
79
+ end
80
+
81
+ def GithubApi.InsertCredsInUrl url
82
+ url = url.sub('http://', "http://#{ENV['un']}:#{ENV['pwd']}@")
83
+ url
84
+ end
85
+
40
86
  def GithubApi.PushBranch remote, branch
87
+ #remote_url = GithubApi.InsertCredsInRemote remote
41
88
  puts "Pushing #{branch} to #{remote}..."
42
89
  `git push #{remote} #{branch}`
43
90
  end
@@ -59,8 +106,22 @@ module GithubApi
59
106
  `git pull --rebase #{@repo_url} #{@branch}`
60
107
  end
61
108
 
109
+ def GithubApi.CommitAllLocalAndPush comment
110
+
111
+ `git add .`
112
+
113
+ status = `git commit -m "#{comment}"`
114
+ return false if status != GlobalConstants::EMPTY
115
+
116
+ #todo: ensure push defaults are set up
117
+ status = `git push`
118
+ return status != GlobalConstants::EMPTY
119
+
120
+ end
121
+
62
122
  def GithubApi.CommitChanges comment, git_status = ''
63
123
  if git_status != GlobalConstants::EMPTY
124
+ #gotcha: line breaks need to be in double-quotes
64
125
  val = git_status.split("\n")
65
126
  val.each { |x|
66
127
  value = x.split(' M ').last || x.split('?? ').last
@@ -77,8 +138,27 @@ module GithubApi
77
138
  return status != GlobalConstants::EMPTY
78
139
  end
79
140
 
141
+ # Returns commits in order of newest to oldest
142
+ def GithubApi.BranchCommitDiff base_branch, derived_branch
143
+ puts "Getting commit diff from #{base_branch} to #{derived_branch}"
144
+ commit_diff_raw = `git log #{base_branch}..#{derived_branch}`
145
+ puts commit_diff_raw
146
+
147
+ return GithubApi.GetCommitHashesFromLog commit_diff_raw
148
+ end
149
+
150
+ # Returns commits in order of newest to oldest
151
+ def GithubApi.GetCommitHashesFromLog git_log
152
+ matches = git_log.scan /^commit [a-zA-Z0-9]*$/
153
+ commit_len = 'commit '.length
154
+ commit_hashes = matches.map { |v| v[commit_len, v.length-1] }
155
+ return commit_hashes
156
+ end
157
+
158
+
80
159
  # we do NOT want to switch to parent folder but stay in current repo dir when we exit this method
81
160
  def GithubApi.CheckoutRepoAfresh repo_url, branch
161
+
82
162
  repo = GithubApi.ProjectNameFromRepo repo_url
83
163
  return false if repo == GlobalConstants::EMPTY
84
164
 
@@ -88,6 +168,7 @@ module GithubApi
88
168
  FileUtils.rm_rf repo
89
169
  end
90
170
 
171
+ #repo_url = GithubApi.InsertCredsInUrl repo_url
91
172
  # clone to local
92
173
  puts 'Cloning repo to local...'
93
174
  begin
@@ -137,4 +218,8 @@ module GithubApi
137
218
 
138
219
  repo
139
220
  end
221
+
222
+ def GithubApi.SetPushDefaultSimple
223
+ `git config --global push.default simple`
224
+ end
140
225
  end
@@ -2,7 +2,7 @@ module GlobalConstants
2
2
 
3
3
  HASH = 'Hash'
4
4
 
5
- SPEC = 'spec'
5
+ SPEC = Dir.pwd + '\src\spec'
6
6
 
7
7
  ROOT = 'root'
8
8
  PREVIOUS = 'previous'
data/lib/rollback.rb ADDED
@@ -0,0 +1,63 @@
1
+ =begin
2
+ rollback flow:
3
+
4
+ check rollback command
5
+ avoid replacing backup branch
6
+
7
+ commit diff on backup vs current
8
+ at least one commit should be version upgrade
9
+ create revert commits on commit diff
10
+
11
+ tag commit with nuget version if it publishes nuget
12
+ tag commit with timestamp if it is a service
13
+
14
+ replace backup branch
15
+ =end
16
+
17
+
18
+
19
+ class RollbackUpgrade
20
+
21
+ DATE_FORMAT = 'date_%m-%d-%Y_time_%H.%M.%S'
22
+
23
+ def initialize repo_url, remote, current_branch, rollback_branch, metadata
24
+ @repo_url = repo_url
25
+ @remote = remote
26
+ @current_branch = current_branch
27
+ @rollback_branch = rollback_branch
28
+ @metadata = metadata
29
+ end
30
+
31
+ def create_rollback_tag
32
+ versioning = SemverVersioning.new
33
+ semver_file = @config_map.metadata.semver.file
34
+ if @config_map.metadata.should_publish_nuget.downcase == 'y' && semver_file != nil && semver_file != GlobalConstants::EMPTY
35
+ semver_file.capitalize
36
+ ver_tag = versioning.get_current_version @config_map.metadata.semver.location, semver_file
37
+ return "rollback-#{ver_tag}"
38
+ else
39
+ utc_now = DateTime.now.utc
40
+ date_tag = utc_now.strftime(DATE_FORMAT)
41
+ return "rollback-#{date_tag}"
42
+ end
43
+ end
44
+
45
+ def Do
46
+ commit_hashes = GithubApi.BranchCommitDiff(@rollback_branch, @current_branch)
47
+ if commit_hashes.length == 0
48
+ puts `No difference between branches #{current_branch} and #{rollback_branch}, aborting rollback.`
49
+ return false
50
+ end
51
+
52
+ # check hashes for version upgrade commit message
53
+ if !commit_hashes.any?{ |c_hash| GithubApi.ShowCommitInfoLocal(c_hash).include? UpgradePackages::VERSION_UPGRADE_COMMIT }
54
+ puts `No version upgrade commit detected to roll back, aborting rollback.`
55
+ return false
56
+ end
57
+
58
+ GithubApi.RevertLocal(@current_branch, commit_hashes)
59
+
60
+ puts `@<--- Rollback branch revert completed. @<---`
61
+ return true
62
+ end
63
+ end
@@ -0,0 +1,163 @@
1
+ =begin
2
+
3
+ Uses project dependency map and configuration to process a DataPlatform Service's
4
+ code repository level framework upgrade and service deployments
5
+
6
+ =end
7
+
8
+ class RollbackAll
9
+
10
+ VERSION_MAP_FILE = 'versionmap.json'
11
+ # todo: remove the up one level path
12
+ MANIFEST_FILE = 'manifest.json'
13
+
14
+ # repo_url is where the last known version map and manifest are checked-in
15
+ def initialize repo_url, branch, manifest_path = MANIFEST_FILE
16
+
17
+ @repo_url = repo_url
18
+ @branch = branch
19
+ @manifest_path = manifest_path
20
+
21
+ @manifest = JSON.parse File.read(@manifest_path) if File.exist? @manifest_path
22
+ end
23
+
24
+ def manifest
25
+ @manifest
26
+ end
27
+
28
+ def version_map
29
+ @remote_version_map
30
+ end
31
+
32
+ def retrieve_artifacts
33
+
34
+ return if !GithubApi.CheckoutRepoAfresh @repo_url, @branch
35
+
36
+ # JSON files converted to hash
37
+ @remote_version_map = JSON.parse File.read(VERSION_MAP_FILE) if File.exist? VERSION_MAP_FILE
38
+ @manifest = JSON.parse File.read(@manifest_path) if File.exist? @manifest_path
39
+
40
+ Dir.chdir GlobalConstants::PARENTDIR
41
+ end
42
+
43
+ def version_exists
44
+
45
+ # create version map afresh to compare
46
+ vm = VersionMap.new
47
+ version_repo_url = @manifest['version_source']['repo_url']
48
+ versions = vm.version_map version_repo_url, @manifest['version_source']['branch']
49
+
50
+ # If remote version doesn't exist, save it
51
+ if @remote_version_map.nil?
52
+ File.write VERSIONMAPFILE, versions.to_json
53
+ GithubApi.PushBranch @repo_url, @branch
54
+
55
+ return hash
56
+ end
57
+ end
58
+
59
+ def Do input_validator, is_local_run=false
60
+
61
+ puts "\n"
62
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Rollback All has begun..'
63
+
64
+ # retrieve version map and upgrade manifest
65
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Retrieving artifacts...'
66
+ retrieve_artifacts
67
+
68
+ return false if @remote_version_map.nil? || @manifest.nil?
69
+
70
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Ensuring version map exists...'
71
+ version_exists
72
+
73
+
74
+ # validate manifest
75
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Validating manifest...'
76
+ validation_errors = []
77
+ input_validator.validate_manifest(@manifest) do |error|
78
+ validation_errors << error if !error.nil?
79
+ end
80
+ raise StandardError, validation_error_message(validation_errors) if validation_errors.length > 0
81
+
82
+ nuget_targets = []
83
+
84
+ # TODO: This validation could probably go in an input validator specifically for rollback
85
+ rollback_config = @manifest['projects']['root']['metadata'].IsRollback
86
+ rollback = !rollback_config.nil? and rollback_config.downcase == 'y'
87
+ if !rollback
88
+ puts 'IsRollback not set in manifest, aborting rollback.'
89
+ return false
90
+ end
91
+ upgrader = UpgradePackages.new versions_to_update, rollback
92
+
93
+ # if changes exist, cycle through dependency tree and kick off upgrades
94
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Navigating projects...'
95
+ dep_tree = DependencyTree.new(@manifest['projects'])
96
+ dep_tree.traverse do |node|
97
+
98
+ if node.metadata.should_upgrade.downcase == 'y'
99
+ puts "#{GlobalConstants::UPGRADE_PROGRESS} Processing project #{node.project_name}..."
100
+
101
+ # validate project node
102
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Validating project node...'
103
+ input_validator.validate_project_node(node) do |error|
104
+ validation_errors << error if !error.nil?
105
+ end
106
+ raise StandardError, validation_error_message(validation_errors) if validation_errors.length > 0
107
+
108
+ # the upgrade
109
+ puts "#{GlobalConstants::UPGRADE_PROGRESS} Rolling back project #{node.project_name}..."
110
+ upgrade_status = upgrader.Do node, nuget_targets, is_local_run
111
+
112
+ # save node name to use for status update
113
+ node_name = node.project_name
114
+ if (node.respond_to?('is_root') && node.is_root == 'true')
115
+ node_name = GlobalConstants::ROOT
116
+ end
117
+
118
+ # project status set in json
119
+ if upgrade_status
120
+ puts "#{GlobalConstants::UPGRADE_PROGRESS} Rollback of #{node.project_name} succeeded"
121
+ @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::SUCCESS
122
+ Dir.chdir GlobalConstants::PARENTDIR
123
+ else
124
+ # either cycle was unterrupted, a step in upgrade failed or full cycle successfully completed
125
+ # save the version map and manifest
126
+ puts "#{GlobalConstants::UPGRADE_PROGRESS} Rollback of #{node.project_name} failed"
127
+ @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::FAILED
128
+ # no more processing after failure
129
+ return false
130
+ end
131
+
132
+ else
133
+ puts "#{GlobalConstants::UPGRADE_PROGRESS} Skipping Rollback for project #{node.project_name}..."
134
+ end
135
+ end
136
+
137
+ # upgrade completed successfully, set rollback to 'n' state, update status as unprocessed and save version map and manifest, push
138
+ @manifest['projects']['root']['metadata'].IsRollback = 'n'
139
+ reset_status_unprocessed
140
+
141
+
142
+ true
143
+ end
144
+
145
+ def save version_manifest
146
+
147
+ end
148
+
149
+
150
+ def reset_status_unprocessed
151
+ @manifest['projects'].each { |proj|
152
+ proj.each { |item|
153
+ item['metadata']['status'] = GlobalConstants::UNPROCESSED if item.class.to_s != 'String'
154
+ }
155
+ }
156
+ @manifest
157
+ end
158
+
159
+ def validation_error_message validation_errors
160
+ "One or more validation errors have occurred: #{validation_errors.join(' ')}"
161
+ end
162
+
163
+ end
data/lib/teamcity_api.rb CHANGED
@@ -7,23 +7,37 @@ require 'builder'
7
7
 
8
8
  module TeamCityApi
9
9
 
10
+ def TeamCityApi.get_teamcity_creds
11
+ file = File.open(Dir.pwd + '/spec/p.txt', 'r')
12
+ content = file.read
13
+ content.gsub!(/\r\n?/, "\n")
14
+ line_num = 0
15
+ creds = []
16
+ content.each_line do |line|
17
+ creds << line
18
+ end
19
+ creds
20
+ end
21
+
10
22
  #Build trigger API
11
- def TeamCityApi.trigger_build buildConfigurationId, username, password
23
+ def TeamCityApi.trigger_build buildConfigurationId
24
+
12
25
  configContent = create_build_trigger_config buildConfigurationId
13
- uri = URI.parse "http://teamcity.relayhealth.com"
26
+ uri = URI.parse 'http://teamcity.relayhealth.com'
14
27
  http = Net::HTTP.new uri.host, uri.port
15
- request = Net::HTTP::Post.new "/httpAuth/app/rest/buildQueue"
28
+ request = Net::HTTP::Post.new '/httpAuth/app/rest/buildQueue'
16
29
  request.body = configContent
17
30
  request.content_type = 'application/xml'
18
31
  request.basic_auth username, password
19
- http.request request
32
+ response = http.request request
33
+ p response
20
34
  end
21
35
 
22
36
  def TeamCityApi.create_build_trigger_config buildConfigurationId
23
37
  xml = Builder::XmlMarkup.new :indent => 2
24
38
  xml.build{
25
- xml.triggeringOptions "cleanSources" => "true", "rebuildAllDependencies" => "true", "queueAtTop" => "true"
26
- xml.buildType "id" => "#{buildConfigurationId}"
39
+ xml.triggeringOptions 'cleanSources' => 'true', 'rebuildAllDependencies' => 'true', 'queueAtTop' => 'true'
40
+ xml.buildType 'id' => "#{buildConfigurationId}"
27
41
  }
28
42
  end
29
43
 
@@ -207,9 +221,31 @@ module TeamCityApi
207
221
  response = http.request request
208
222
  end
209
223
 
210
- end
224
+ def TeamCityApi.get_build_status projectId
225
+ # list queued builds per project
226
+ uri = URI.parse 'http://teamcity.relayhealth.com'
227
+ http = Net::HTTP.new uri.host, uri.port
228
+ request = Net::HTTP::Get.new "/app/rest/buildQueue?locator=project:#{projectId}", {'Accept' => 'application/json'}
229
+ creds = TeamCityApi.get_teamcity_creds
230
+ request.basic_auth creds[0].delete("\n"), creds[1].delete("\n")
231
+ response = http.request request
232
+ end
211
233
 
234
+ end
212
235
 
236
+ =begin
237
+ creds = TeamCityApi.get_teamcity_creds
238
+ configContent = create_build_trigger_config buildConfigurationId
239
+ uri = URI.parse 'http://teamcity.relayhealth.com'
240
+ http = Net::HTTP.new uri.host, uri.port
241
+ request = Net::HTTP::Post.new '/httpAuth/app/rest/buildQueue'
242
+ request.body = configContent
243
+ request.content_type = 'application/xml'
244
+ request.basic_auth creds[0].delete("\n"), creds[1].delete("\n")
245
+ response = http.request request
246
+ p response.body
247
+ end
248
+ =end
213
249
  # Sample Usage
214
250
  #TeamCityApi.trigger_build("DataPlatform_DataPlatformOntology_ADevelopBuildDataPlatformOntology_2", "username", "password")
215
251
 
data/lib/upgrade.rb CHANGED
@@ -7,9 +7,13 @@ Processes upgrade for a C# code repositoryy
7
7
  class UpgradePackages
8
8
 
9
9
  UPGRADE_BRANCH = 'upgrade'
10
+ BACKUP_BRANCH = 'upgradeBackupDoNotDelete'
11
+ VERSION_UPGRADE_COMMIT = 'Versions updated'
12
+ VERSION_UPGRADE_FAIL_BUILD_COMMIT = 'Versions updated, build failed'
10
13
 
11
- def initialize versions
14
+ def initialize versions, rollback=false
12
15
  @versions = versions
16
+ @rollback = rollback
13
17
  end
14
18
 
15
19
  def checkout_upgrade_branch
@@ -26,6 +30,20 @@ class UpgradePackages
26
30
  return true
27
31
  end
28
32
 
33
+ def create_upgrade_tag
34
+ versioning = SemverVersioning.new
35
+ semver_file = @config_map.metadata.semver.file
36
+ if @config_map.metadata.should_publish_nuget.downcase == 'y' && semver_file != nil && semver_file != GlobalConstants::EMPTY
37
+ semver_file.capitalize
38
+ ver_tag = versioning.get_current_version @config_map.metadata.semver.location, semver_file
39
+ return "upgrade-#{ver_tag}"
40
+ else
41
+ utc_now = DateTime.now.utc
42
+ date_tag = utc_now.strftime(DATE_FORMAT)
43
+ return "upgrade-#{date_tag}"
44
+ end
45
+ end
46
+
29
47
  def Do config_map, nuget_targets, is_local_run=false
30
48
 
31
49
  @config_map = config_map
@@ -35,6 +53,22 @@ class UpgradePackages
35
53
  # checkout repo and branch
36
54
  return false if !GithubApi.CheckoutRepoAfresh @repo_url, @branch
37
55
 
56
+ tag_creator = method(:create_upgrade_tag)
57
+
58
+ # TODO: Need to check if node has failed before invoking rollback
59
+ if @rollback
60
+ puts "Starting Rollback."
61
+ rollback = new Rollback @repo_url, 'origin', @branch, BACKUP_BRANCH, @config_map.metadata
62
+ tag_creator = rollback.method(:create_rollback_tag)
63
+ return false if !rollback.Do
64
+ end
65
+
66
+ # When upgrade branch exists we are coming from some failure state and dont need to backup the branch again
67
+ if (GithubApi.DoesBranchExist('origin', UPGRADE_BRANCH) == GlobalConstants::EMPTY)
68
+ GithubApi.CreateNewBranch(BACKUP_BRANCH, @branch)
69
+ GithubApi.ForcePushBranch('origin', BACKUP_BRANCH)
70
+ end
71
+
38
72
  # make upgrade branch
39
73
  return false if !checkout_upgrade_branch
40
74
 
@@ -61,9 +95,13 @@ class UpgradePackages
61
95
  # QUESTION: Should this method increment semver even if there is no nuget published?
62
96
  puts GlobalConstants::UPGRADE_PROGRESS + 'Upgrading semver...'
63
97
  semver_inc_done = increment_semver_if_publish is_local_run
64
- if @config_map.metadata.should_publish_nuget.downcase == 'y'
65
- nuget_targets << Dir.pwd + '/build_artifacts'
66
- end
98
+ nuget_targets << Dir.pwd + '/build_artifacts' if @config_map.metadata.should_publish_nuget.downcase == 'y'
99
+
100
+ # Tag commit
101
+ recent_commit_hash = GithubApi.GetRecentCommitHash(@branch)
102
+ #rollback_tag = tag_creator.call()
103
+
104
+ #GithubApi.TagLocal(recent_commit_hash, rollback_tag, "Autoupgrade Tag")
67
105
 
68
106
  # do rake build to test for compilation errors. This needs ENV vars set, passed in via config
69
107
  set_project_env_vars @config_map.metadata.env_vars
@@ -71,7 +109,7 @@ class UpgradePackages
71
109
  if output.to_s == 'false'
72
110
  puts GlobalConstants::UPGRADE_PROGRESS + ' Rake Error: There were errors during rake run.'
73
111
  # save state
74
- GithubApi.CommitChanges( 'Versions updated, build failed')
112
+ GithubApi.CommitChanges( VERSION_UPGRADE_FAIL_BUILD_COMMIT)
75
113
 
76
114
  return false
77
115
  end
@@ -87,7 +125,7 @@ class UpgradePackages
87
125
  else
88
126
  return false if !update_branch
89
127
  # kick off teamcity build
90
- TeamCityApi.trigger_build @config_map.build_configuration_id, @config_map.tc_un, @config_map.tc_pwd
128
+ TeamCityApi.trigger_build @config_map.build_configuration_id, ENV['tc_un'], ENV['tc_pwd']
91
129
  end
92
130
 
93
131
  true
data/lib/upgradeall.rb CHANGED
@@ -10,6 +10,7 @@ class UpgradeAll
10
10
  VERSION_MAP_FILE = 'versionmap.json'
11
11
  # todo: remove the up one level path
12
12
  MANIFEST_FILE = 'manifest.json'
13
+ MAX_CHECKS = 12
13
14
 
14
15
  # repo_url is where the last known version map and manifest are checked-in
15
16
  def initialize repo_url, branch, manifest_path = MANIFEST_FILE
@@ -17,8 +18,8 @@ class UpgradeAll
17
18
  @repo_url = repo_url
18
19
  @branch = branch
19
20
  @manifest_path = manifest_path
20
-
21
21
  @manifest = JSON.parse File.read(@manifest_path) if File.exist? @manifest_path
22
+
22
23
  end
23
24
 
24
25
  def manifest
@@ -26,15 +27,14 @@ class UpgradeAll
26
27
  end
27
28
 
28
29
  def version_map
29
- @remote_version_map
30
+ @version_map
30
31
  end
31
32
 
32
33
  def retrieve_artifacts
33
-
34
34
  return if !GithubApi.CheckoutRepoAfresh @repo_url, @branch
35
35
 
36
36
  # JSON files converted to hash
37
- @remote_version_map = JSON.parse File.read(VERSION_MAP_FILE) if File.exist? VERSION_MAP_FILE
37
+ @version_map = JSON.parse File.read(VERSION_MAP_FILE) if File.exist? VERSION_MAP_FILE
38
38
  @manifest = JSON.parse File.read(@manifest_path) if File.exist? @manifest_path
39
39
 
40
40
  Dir.chdir GlobalConstants::PARENTDIR
@@ -42,6 +42,8 @@ class UpgradeAll
42
42
 
43
43
  def Do input_validator, is_local_run=false
44
44
 
45
+ GithubApi.SetPushDefaultSimple
46
+
45
47
  puts "\n"
46
48
  puts GlobalConstants::UPGRADE_PROGRESS + 'Upgrade All has begun..'
47
49
 
@@ -49,7 +51,7 @@ class UpgradeAll
49
51
  puts GlobalConstants::UPGRADE_PROGRESS + 'Retrieving artifacts...'
50
52
  retrieve_artifacts
51
53
 
52
- return false if @remote_version_map.nil? || @manifest.nil?
54
+ return false if @version_map.nil? || @manifest.nil?
53
55
 
54
56
  #find version diff. If no changes exist, kick off deploy cycle only
55
57
  puts GlobalConstants::UPGRADE_PROGRESS + 'Calculating version diff...'
@@ -77,53 +79,84 @@ class UpgradeAll
77
79
  dep_tree = DependencyTree.new(@manifest['projects'])
78
80
  dep_tree.traverse do |node|
79
81
 
80
- if node.metadata.should_upgrade.downcase == 'y'
81
- puts "#{GlobalConstants::UPGRADE_PROGRESS} Processing project #{node.project_name}..."
82
-
83
- # validate project node
84
- puts GlobalConstants::UPGRADE_PROGRESS + 'Validating project node...'
85
- input_validator.validate_project_node(node) do |error|
86
- validation_errors << error if !error.nil?
87
- end
88
- raise StandardError, validation_error_message(validation_errors) if validation_errors.length > 0
89
-
90
- # the upgrade
91
- puts "#{GlobalConstants::UPGRADE_PROGRESS} Upgrading project #{node.project_name}..."
92
- upgrade_status = upgrader.Do node, nuget_targets, is_local_run
93
-
94
- # save node name to use for status update
95
- node_name = node.project_name
96
- if (node.respond_to?('is_root') && node.is_root == 'true')
97
- node_name = GlobalConstants::ROOT
98
- end
99
-
100
- # project status set in json
101
- if upgrade_status
102
- puts "#{GlobalConstants::UPGRADE_PROGRESS} Upgrade of #{node.project_name} succeeded"
103
- @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::SUCCESS
104
- Dir.chdir GlobalConstants::PARENTDIR
105
- else
106
- # either cycle was unterrupted, a step in upgrade failed or full cycle successfully completed
107
- # save the version map and manifest
108
- puts "#{GlobalConstants::UPGRADE_PROGRESS} Upgrade of #{node.project_name} failed"
109
- @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::FAILED
110
- # no more processing after failure
111
- return false
112
- end
82
+ next if !check_should_upgrade node
83
+ next if check_success_state node
84
+
85
+ puts GlobalConstants::UPGRADE_PROGRESS + " Processing project #{node.project_name}..."
86
+
87
+ # validate project node
88
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Validating project node...'
89
+ input_validator.validate_project_node(node) do |error|
90
+ validation_errors << error if !error.nil?
91
+ end
92
+ raise StandardError, validation_error_message(validation_errors) if validation_errors.length > 0
113
93
 
94
+ # the upgrade
95
+ puts GlobalConstants::UPGRADE_PROGRESS + " Upgrading project #{node.project_name}..."
96
+ upgrade_status = upgrader.Do node, nuget_targets, is_local_run
97
+
98
+ # save node name to use for status update
99
+ node_name = node.project_name
100
+ node_name = GlobalConstants::ROOT if (node.respond_to?('is_root') && node.is_root == 'true')
101
+
102
+ # project status set in json
103
+ if upgrade_status
104
+ puts GlobalConstants::UPGRADE_PROGRESS + " Upgrade of #{node.project_name} succeeded"
105
+ @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::SUCCESS
106
+ Dir.chdir GlobalConstants::PARENTDIR
107
+
108
+ # if publishing nuget package, wait for a minute for publish to finish
109
+ waitfor if node.should_publish_nuget
114
110
  else
115
- puts "#{GlobalConstants::UPGRADE_PROGRESS} Skipping upgrade for project #{node.project_name}..."
111
+ # either cycle was unterrupted, a step in upgrade failed or full cycle successfully completed
112
+ # save the version map and manifest
113
+ puts GlobalConstants::UPGRADE_PROGRESS + " Upgrade of #{node.project_name} failed"
114
+ @manifest['projects'][node_name]['metadata']['status'] = GlobalConstants::FAILED
115
+ # no more processing after failure
116
+ return false
116
117
  end
118
+
117
119
  end
118
120
 
119
121
  # upgrade completed successfully, update status as unprocessed and save version map and manifest, push
120
122
  reset_status_unprocessed
121
123
 
124
+ save_version_manifest versions_to_update if !is_local_run
122
125
 
123
126
  true
124
127
  end
125
128
 
126
- def save version_manifest
129
+ def check_should_upgrade node
130
+ status = node.metadata.should_upgrade.downcase == 'y'
131
+ puts GlobalConstants::UPGRADE_PROGRESS + " Skipping upgrade for project #{node.project_name}..." if !status
132
+ status
133
+ end
134
+
135
+ def check_success_state node
136
+ status = node.metadata.status == GlobalConstants::SUCCESS
137
+ puts GlobalConstants::UPGRADE_PROGRESS + " Project #{node.project_name} already in #{GlobalConstants::SUCCESS} state. Skipping upgrade..." if status
138
+ status
139
+ end
140
+
141
+ def save_version_manifest versions_to_update
142
+
143
+ # cd to directory where versions/manifest is present
144
+ repo_folder = GithubApi.ProjectNameFromRepo @repo_url
145
+ Dir.chdir repo_folder
146
+
147
+ # update files
148
+ File.open(MANIFEST_FILE, 'w') do |f|
149
+ f.write @manifest.to_json
150
+ end
151
+
152
+ # merge updated versions with known version map
153
+ @version_map = @version_map.merge versions_to_update
154
+ File.open(VERSION_MAP_FILE, 'w') do |f|
155
+ f.write @version_map.to_json
156
+ end
157
+
158
+ # save branch
159
+ GithubApi.CommitAllLocalAndPush 'Updated manifest and version map'
127
160
 
128
161
  end
129
162
 
@@ -135,15 +168,15 @@ class UpgradeAll
135
168
  versions = vm.version_map version_repo_url, @manifest['version_source']['branch']
136
169
 
137
170
  # If remote version doesn't exist, save it
138
- if @remote_version_map.nil?
139
- File.write VERSIONMAPFILE, versions.to_json
171
+ if @version_map.nil?
172
+ File.write VERSION_MAP_FILE, versions.to_json
140
173
  GithubApi.PushBranch @repo_url, @branch
141
174
 
142
175
  return hash
143
176
  end
144
177
 
145
178
  # compare current and remote versions, obtain changeset
146
- hash = Hash[*(versions.to_a - @remote_version_map.to_a).flatten]
179
+ hash = Hash[*(versions.to_a - @version_map.to_a).flatten]
147
180
 
148
181
  # return changeset hash
149
182
  hash
@@ -162,4 +195,16 @@ class UpgradeAll
162
195
  "One or more validation errors have occurred: #{validation_errors.join(' ')}"
163
196
  end
164
197
 
198
+ def waitfor
199
+ checks = 0
200
+
201
+ until checks > MAX_CHECKS
202
+ sleep 5
203
+ checks += 1
204
+ puts GlobalConstants::UPGRADE_PROGRESS + 'Waiting for 5 seconds...'
205
+ end
206
+
207
+ raise 'Waitfor timeout expired. Make sure that you aren\'t running something from the build output folders, or that you have browsed to it through Explorer.' if checks > MAX_CHECKS
208
+ end
209
+
165
210
  end
data/lib/version_map.rb CHANGED
@@ -45,10 +45,7 @@ class VersionMap
45
45
  doc = Nokogiri::XML File.read(file)
46
46
  nodes = doc.xpath "//*[@id]"
47
47
  nodes.each { |node|
48
-
49
- if (!versions[node['id']].nil? && node['version'] != versions[node['id']])
50
- puts "======Error: Package #{node['id']} with version #{node['version']} has a different pre-exisiting version: #{versions[node['id']]}"
51
- end
48
+ puts "======Error: Package #{node['id']} with version #{node['version']} has a different pre-exisiting version: #{versions[node['id']]}" if (!versions[node['id']].nil? && node['version'] != versions[node['id']])
52
49
  versions[node['id']] = node['version']
53
50
  }
54
51
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: a2zdeploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Suresh Batta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-19 00:00:00.000000000 Z
11
+ date: 2016-02-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Automated Upgrades Gem. Provides version upgrades, build and deployment
14
14
  configuration management
@@ -24,6 +24,8 @@ files:
24
24
  - lib/hash_extensions.rb
25
25
  - lib/input_validator.rb
26
26
  - lib/proget_api.rb
27
+ - lib/rollback.rb
28
+ - lib/rollbackall.rb
27
29
  - lib/teamcity_api.rb
28
30
  - lib/upgrade.rb
29
31
  - lib/upgradeall.rb