a2zdeploy 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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