a2zdeploy 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,9 +14,10 @@ Inputs:
14
14
 
15
15
  require 'nokogiri'
16
16
  require 'json'
17
+ require 'azdeploy'
18
+
17
19
  require_relative 'github_api'
18
20
  require_relative 'globalconstants'
19
- require_relative 'version'
20
21
 
21
22
  class UpgradePackages
22
23
 
@@ -47,7 +48,7 @@ class UpgradePackages
47
48
  puts 'Environment variables not supplied. Cannot continue!'
48
49
  return false
49
50
  end
50
-
51
+
51
52
  # fail if metadata was not supplied
52
53
  if (!@config_map.has_key? 'metadata')
53
54
  puts 'Metadata variables not supplied. Cannot continue!'
@@ -64,10 +65,10 @@ class UpgradePackages
64
65
  puts 'Getting upgrade branch...'
65
66
  if (GithubApi.DoesBranchExist('origin', UPGRADE_BRANCH) != GlobalConstants::EMPTY)
66
67
  puts 'Checking out existing upgrade branch...'
67
- return false if !GithubApi.CheckoutExistingBranch UPGRADE_BRANCH == GlobalConstants::EMPTY
68
+ return false if !GithubApi.CheckoutExistingBranch(UPGRADE_BRANCH) == GlobalConstants::EMPTY
68
69
  else
69
70
  puts 'Checking out new upgrade branch...'
70
- return false if !GithubApi.CheckoutNewBranch UPGRADE_BRANCH == GlobalConstants::EMPTY
71
+ return false if !GithubApi.CheckoutNewBranch(UPGRADE_BRANCH) == GlobalConstants::EMPTY
71
72
  end
72
73
 
73
74
  return true
@@ -94,26 +95,29 @@ class UpgradePackages
94
95
  puts "Project version replacement failed."
95
96
  return false
96
97
  end
97
-
98
- # Check in manifest if project publish nuget? If yes, increment .semver
98
+
99
+ # Check in manifest if project publish nuget? If yes, increment .semver
100
+ # QUESTION: Should this method increment semver even if there is no nuget published?
99
101
  increment_semver_if_publish
100
-
102
+
101
103
  # do rake build to test for compilation errors. This needs ENV vars set, passed in via config
102
104
  set_project_env_vars @config_map['env_vars']
103
105
  output = system 'rake'
106
+
107
+ commit_msg = 'Versions updated'
104
108
  if output.to_s == 'false'
105
- puts '~~/\~~\/~~ Rake Error: There were errors during rake run. ~~\/~~/\~~'
106
- # save state
107
- GithubApi.CommitChanges( 'Versions updated, build failed')
108
-
109
- return false
109
+ puts '~~/\~~\/~~ Rake Error: There were errors during rake run. ~~\/~~/\~~'
110
+ # save state
111
+ commit_msg = 'Versions updated, build failed'
110
112
  end
111
113
 
112
114
  # see if any files changed and commit
113
115
  git_status = GithubApi.HaveLocalChanges
114
116
  if (git_status != nil || git_status != GlobalConstants::EMPTY)
115
- puts 'Local version changes have been committed'
116
- return false if !GithubApi.CommitChanges( 'Versions updated')
117
+ puts 'Local version changes have been committed'
118
+ return false if !GithubApi.CommitChanges commit_msg, git_status
119
+ else
120
+ puts 'No local changes exist. Nothing to commit'
117
121
  end
118
122
 
119
123
  # rebase and push the branch
@@ -232,23 +236,23 @@ class UpgradePackages
232
236
  ENV[key] = envs[key]
233
237
  }
234
238
  end
235
-
239
+
236
240
  def increment_semver_if_publish
237
241
  if !is_team_city_run
238
- # local run
239
- auto_update_local_semver
242
+ # local run
243
+ auto_update_local_semver
240
244
  else
241
- should_publish_nuget = @config_map['metadata']['ShouldPublishNuget'].downcase
242
- if should_publish_nuget.eql? 'y'
243
- semver_file = @config_map['metadata']['SemverFile']
244
- if (semver_file != nil && semver_file != GlobalConstants::EMPTY)
245
- semver_file.capitalize
246
- end
247
- semver_dimension = @config_map['metadata']['SemverDimension']
248
- auto_update_semver @config_map['project'], @config_map['metadata']['SemverLocation'], semver_file, semver_dimension
249
- else
250
- puts '******** Project does not publish nuget.**********'
245
+ should_publish_nuget = @config_map['metadata']['ShouldPublishNuget'].downcase
246
+ if should_publish_nuget.eql? 'y'
247
+ semver_file = @config_map['metadata']['SemverFile']
248
+ if (semver_file != nil && semver_file != GlobalConstants::EMPTY)
249
+ semver_file.capitalize
251
250
  end
251
+ semver_dimension = @config_map['metadata']['SemverDimension']
252
+ auto_update_semver @config_map['project'], @config_map['metadata']['SemverLocation'], semver_file, semver_dimension
253
+ else
254
+ puts '******** Project does not publish nuget.**********'
255
+ end
252
256
  end
253
257
  end
254
258
  end
@@ -5,17 +5,12 @@ code repository level framework upgrade and service deployments
5
5
 
6
6
  =end
7
7
 
8
- require_relative 'github_api'
9
- require 'json'
10
-
11
8
  class UpgradeAll
12
9
 
13
10
  VERSION_MAP_FILE = 'versionmap.json'
11
+ # todo: remove the up one level path
14
12
  MANIFEST_FILE = 'manifest.json'
15
13
 
16
- # JSON files converted to hash
17
- attr_accessor :version_map, :manifest
18
-
19
14
  # repo_url is where the last known version map and manifest are checked-in
20
15
  def initialize repo_url, branch
21
16
 
@@ -28,9 +23,11 @@ class UpgradeAll
28
23
 
29
24
  return if !GithubApi.CheckoutRepoAfresh @repo_url, @branch
30
25
 
26
+ # JSON files converted to hash
31
27
  if File.exist? VERSION_MAP_FILE
32
- @version_map = JSON.parse File.read(VERSION_MAP_FILE)
28
+ @remote_version_map = JSON.parse File.read(VERSION_MAP_FILE)
33
29
  end
30
+
34
31
  if File.exist? MANIFEST_FILE
35
32
  @manifest = JSON.parse File.read(MANIFEST_FILE)
36
33
  end
@@ -39,33 +36,56 @@ class UpgradeAll
39
36
 
40
37
  def Do
41
38
 
42
- return if @version_map.nil || @manifest.nil
43
-
44
39
  # retrieve version map and upgrade manifest
45
40
  retrieve_artifacts
46
41
 
47
- # if no changes exist, kick off deploy cycle only
42
+ return false if @remote_version_map.nil? || @manifest.nil?
43
+
44
+ #find version diff. If no changes exist, kick off deploy cycle only
45
+ puts 'Calculating version diff...'
46
+ versions_to_update = version_diff
48
47
 
49
48
  # if changes exist, cycle through dependency tree and kick off upgrades
49
+ projects = @manifest['projects']
50
+ projects.each { | proj |
51
+ p proj
52
+ if proj['ShouldUpgrade'].downcase != 'n'
53
+ p proj
54
+ puts "================="
55
+ end
56
+ }
50
57
 
51
58
  # either cycle was unterrupted, a step in upgrade failed or full cycle successfully completed
59
+
52
60
  # save the version map and manifest
53
61
 
62
+ true
54
63
  end
55
64
 
56
65
  def version_diff
57
66
 
58
67
  # create version map afresh to compare
59
68
  vm = VersionMap.new
60
- repo_url = @manifest['version_source']
61
- versions = vm.version_map repo_url, 'master'
69
+ version_repo_url = @manifest['version_source']['repo_url']
70
+ versions = vm.version_map version_repo_url, @manifest['version_source']['branch']
62
71
 
63
72
  # If remote version doesn't exist, save it
64
- if @version_map.nil
73
+ if @remote_version_map.nil?
74
+ File.write VERSIONMAPFILE, versions.to_json
75
+ GithubApi.PushBranch @repo_url, @branch
65
76
 
77
+ return hash
66
78
  end
67
79
 
80
+ #p @remote_version_map
81
+ #p versions
82
+
68
83
  # compare current and remote versions, obtain changeset
84
+ hash = Hash[*(versions.to_a - @remote_version_map.to_a).flatten]
85
+
86
+ # return changeset hash
87
+ hash
88
+
69
89
  end
70
90
 
71
91
  end
@@ -21,12 +21,6 @@
21
21
  3. Uniquefy list to a hash map and return
22
22
  =end
23
23
 
24
- require 'json'
25
- require 'nokogiri'
26
- require 'semver'
27
- require_relative 'github_api'
28
- require_relative 'version'
29
-
30
24
  class VersionMap
31
25
 
32
26
  VERSIONMAPFILE = 'versionmap.json'
@@ -52,13 +46,17 @@ class VersionMap
52
46
  nodes = doc.xpath "//*[@id]"
53
47
  nodes.each { |node|
54
48
  if (!versions[node['id']].nil? && node['version'] != versions[node['id']]['version'])
55
- puts "======Error: Package #{node['id']} with version #{node['version']} has a different pre-exisiting version: #{versions[node['id']]['version']} in #{versions[node['id']]['file']}"
49
+ puts "======Error: Package #{node['id']} with version #{node['version']} has a different pre-exisiting version: #{versions[node['id']]}"
56
50
  end
57
51
  versions[node['id']] = node['version']
58
52
  }
59
53
  }
60
-
61
- update_platform_package_versions versions
54
+
55
+ if Dir.exist?('versioning')
56
+ update_platform_multiple_semver_package_versions versions
57
+ else
58
+ update_platform_single_semver_package_versions versions
59
+ end
62
60
 
63
61
  Dir.chdir '..'
64
62
  File.write VERSIONMAPFILE, versions.to_json
@@ -67,8 +65,24 @@ class VersionMap
67
65
 
68
66
  end
69
67
 
70
- # these versions will need to be replaced with project specific semvers
71
- def update_platform_package_versions versions
68
+ def update_platform_single_semver_package_versions versions
69
+ ver = load_semver '.semver'
70
+ v = ver.to_s.sub 'v', '' # removes 'v' at start of string which isn't expected for version spec in .package and .csproj files
71
+ version = v
72
+ versions['RelayHealth.DataPlatform.Contracts'] = version
73
+ versions['RelayHealth.DataPlatform.Framework'] = version
74
+ versions['RelayHealth.DataPlatform.Framework.Messaging'] = version
75
+ versions['RelayHealth.DataPlatform.Framework.Web'] = version
76
+ versions['RelayHealth.DataPlatform.Identity'] = version
77
+ versions['RelayHealth.DataPlatform.Management'] = version
78
+ versions['RelayHealth.DataPlatform.Management.Tools'] = version
79
+ versions['RelayHealth.DataPlatform.Test'] = version
80
+ versions['RelayHealth.DataPlatform.Test.Messaging'] = version
81
+
82
+ versions
83
+ end
84
+
85
+ def update_platform_multiple_semver_package_versions versions
72
86
  versions['RelayHealth.DataPlatform.Contracts'] = get_semver 'Contracts.semver'
73
87
  versions['RelayHealth.DataPlatform.Framework'] = get_semver 'Framework.semver'
74
88
  versions['RelayHealth.DataPlatform.Framework.Messaging'] = get_semver 'Framework.Messaging.semver'
@@ -84,12 +98,19 @@ class VersionMap
84
98
 
85
99
  versions
86
100
  end
87
- end
88
101
 
89
- def get_semver semver
102
+ def load_semver path
103
+ v = SemVer.new
104
+ v.load path
105
+ v
106
+ end
107
+
108
+ def get_semver semver
90
109
  ver = load_semver File.join('versioning', semver)
91
110
  v = ver.to_s.sub 'v', '' # removes 'v' at start of string which isn't expected for version spec in .package and .csproj files
92
111
  v
112
+ end
113
+
93
114
  end
94
115
 
95
116
  #puts "test"
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.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Suresh Batta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-18 00:00:00.000000000 Z
11
+ date: 2015-12-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Automated Upgrades Gem. Provides version upgrades, build and deployment
14
14
  configuration management
@@ -17,6 +17,7 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - lib/a2zdeploy.rb
20
21
  - lib/dependency_tree.rb
21
22
  - lib/github_api.rb
22
23
  - lib/globalconstants.rb
@@ -24,17 +25,9 @@ files:
24
25
  - lib/teamcity_api.rb
25
26
  - lib/upgrade.rb
26
27
  - lib/upgradeall.rb
27
- - lib/version.rb
28
28
  - lib/version_map.rb
29
- - spec/dependency_tree_spec.rb
30
- - spec/github_api_spec.rb
31
- - spec/packages.config
32
- - spec/proj.csproj
33
- - spec/upgradeall_spec.rb
34
- - spec/upgrade_spec.rb
35
- - spec/version_map_spec.rb
36
29
  - a2zdeploy.gemspec
37
- - rakefile.rb
30
+ - ReadMe.md
38
31
  homepage: http://rubygems.org/gems/a2zdeploy
39
32
  licenses:
40
33
  - MIT
@@ -1,266 +0,0 @@
1
- require 'net/http'
2
- require 'pathname'
3
-
4
- # url template of file to check for version info with repo, branch and file path to replace
5
- URLTEMPLATE ||= "%s/raw/%s/%s"
6
-
7
- def get_file_list path, extension
8
- return Dir.glob("#{path}/*.#{extension}")
9
- end
10
-
11
- def get_repo_version semver
12
- remote_name = get_remote_name
13
- branch_name = get_branch_name
14
- url = URLTEMPLATE % [remote_name, branch_name, semver]
15
- page_content = open(url)
16
- repo_version = get_semver_version(page_content)
17
- return repo_version
18
- end
19
-
20
- def get_current_version path, semver
21
- location = File.join path, semver
22
- content = File.read(location)
23
- current_version = get_semver_version(content)
24
- return current_version
25
- end
26
-
27
- def open(url)
28
- Net::HTTP.get(URI.parse(url))
29
- end
30
-
31
- def get_semver_version(content)
32
- s = content.split("\n")
33
- val = ''
34
- s.each{ |i|
35
- if (i.start_with?(':'))
36
- x = i.split(': ')[1].strip
37
- x.gsub!("'", '')
38
- if (x.length != 0)
39
- val = val + x.to_s + '.'
40
- end
41
- end
42
- }
43
- val.chomp('.')
44
- end
45
-
46
- def same_versions version1, version2
47
- return version1 == version2
48
- end
49
-
50
- def is_team_city_run
51
- return ENV['BUILD_VCS_NUMBER'] != nil
52
- end
53
-
54
- #desc 'Check that Semver version bump task should not be invoked from teamcity'
55
- def get_branch_name
56
- current_branch = ENV['GIT_BRANCH_NAME']
57
- if current_branch.nil?
58
- raise '********GIT_BRANCH_NAME environment variable required for local rake run. Cannot continue with build. Exiting..............********'
59
- else
60
- return current_branch
61
- end
62
- end
63
-
64
- def get_remote_name
65
- remote_name = ENV['GIT_REMOTE_NAME']
66
- if remote_name.nil?
67
- raise '********GIT_REMOTE_NAME environment variable required for local rake run. Cannot continue with build. Exiting..............********'
68
- else
69
- @remote = `git remote -v`.split("\n")
70
- @remote.each { |val|
71
- if val =~ /#{remote_name}/
72
- return val.split(" ")[1]
73
- end
74
- }
75
- end
76
- end
77
-
78
- def fetch_updated_semver
79
-
80
- updated_semver = get_update_semver_file_with_versions
81
-
82
- #for local run user did not increment any semver
83
- if updated_semver[3] == 0
84
- puts '*********** No semver incremented detected. ***********'
85
- return nil
86
- end
87
-
88
- version_remote = updated_semver[1].split('.')
89
- version_local = updated_semver[2].split('.')
90
-
91
- incremented = is_semver_incremented version_remote, version_local
92
-
93
- [updated_semver[0].gsub("#{VERSIONING}/", ''), incremented]
94
- end
95
-
96
- def is_semver_incremented version_remote, version_local
97
- is_incremented = [version_local[0].to_i - version_remote[0].to_i > 0, version_local[1].to_i - version_remote[1].to_i > 0, version_local[2].to_i - version_remote[2].to_i > 0]
98
-
99
- if is_incremented[0]
100
- if (version_local[1] != 0 || version_local[2] != 0)
101
- raise 'Error - major version is incremented. Minor and Patch should be 0. Cannot continue build. Exiting....'
102
- end
103
- end
104
-
105
- if is_incremented[1]
106
- if is_incremented[0]
107
- raise 'Error - cannot increment both major and minor version. . Exiting....'
108
- end
109
- end
110
-
111
- if is_incremented[2]
112
- if(is_incremented[0] || is_incremented[1])
113
- raise 'Error - cannot increment major, minor and patch together. . Exiting....'
114
- end
115
- end
116
-
117
- if is_incremented[0]
118
- return 'major'
119
- elsif is_incremented[1]
120
- return 'minor'
121
- elsif is_incremented[2]
122
- return 'patch'
123
- end
124
- end
125
-
126
- def get_update_semver_file_with_versions
127
- count = 0
128
- semver_file = ''
129
- version_remote = ''
130
- version_local = ''
131
-
132
- semvers = get_file_list VERSIONING, 'semver'
133
- if(semvers.empty?)
134
- raise "************Error - no semver files found at #{VERSIONING}********"
135
- end
136
-
137
- semvers.each { |semver|
138
- v1 = get_repo_version semver
139
- v2 = get_current_version VERSIONING, semver.gsub("#{VERSIONING}/", '')
140
-
141
- if (!same_versions(v1, v2))
142
- puts "#{semver} version changed"
143
- semver_file = semver
144
- version_remote = v1
145
- version_local = v2
146
- count = count + 1
147
- end
148
- }
149
- if count > 1
150
- raise '*********** Error - Version increment is expected in a single semver file and can be only one of major|minor|patch ************'
151
- return
152
- end
153
-
154
- [semver_file, version_remote, version_local, count]
155
- end
156
-
157
-
158
- def get_project_dependencies csproj
159
- proj_files = Dir.glob '**/*.csproj'
160
- @unique_list = Array.new
161
- proj_files.each{ |file|
162
- doc = Nokogiri::XML File.read file
163
- nodes = doc.search 'ProjectReference'
164
- nodes.each { |node|
165
- ref_val = node['Include']
166
- id = ref_val.split('\\')[2]
167
- if id.eql? csproj
168
- @unique_list << file.split('/')[2]
169
- end
170
- }
171
- }
172
- @unique_list.uniq
173
- end
174
-
175
- def get_project_dependencies_semver_files projects_dependencies, semver_project_map
176
- project_semver_map = semver_project_map.invert
177
- @values = Array.new
178
- projects_dependencies.each { |dependency|
179
- if semver_project_map.value?(dependency)
180
- @values << project_semver_map[dependency]
181
- end
182
- }
183
- @values
184
- end
185
-
186
- def load_semver path
187
- v = SemVer.new
188
- v.load path
189
- return v
190
- end
191
-
192
- # Increment the major, minor, or patch of the .semver file.
193
- def increment_version semver_file, dimension
194
- if dimension.nil?
195
- raise 'The parameter dimension is required to be one of : major | minor | patch'
196
- end
197
- semver = load_semver semver_file
198
-
199
- case dimension
200
- when 'major'
201
- semver.major += 1
202
- semver.minor = 0
203
- semver.patch = 0
204
- when 'minor'
205
- semver.minor += 1
206
- semver.patch = 0
207
- when 'patch'
208
- semver.patch += 1
209
- else
210
- raise "The parameter #{dimension} is invalid: major | minor | patch"
211
- end
212
-
213
- hash = "---\n:major: %s\n:minor: %s\n:patch: %s\n:special: '%s'\n:metadata: '%s'"
214
- value = hash % [semver.major, semver.minor, semver.patch, semver.special, semver.metadata]
215
- File.write semver_file, value
216
- end
217
-
218
- def create_semver_project_map product, semver_location
219
- semver_project_map = Hash.new
220
-
221
- rake_list = get_file_list semver_location, 'semver'
222
- rake_list.each{ |rakefile|
223
- rake = rakefile.gsub("#{semver_location}/", '')
224
- project_name = rake.gsub('.semver', '')
225
- semver_project_map[rake] = "#{product}.#{project_name}.csproj"
226
- }
227
- semver_project_map
228
- end
229
-
230
- def display_local_changes_to_user
231
- git_status = `git status -s`
232
- if (git_status != nil || git_status != GlobalConstants::EMPTY)
233
- puts '********** Local semver/s updated. Please commit the change.'
234
- end
235
- end
236
-
237
- def update_dependent_semvers product, semver_location, semver_file, dimension
238
- semver_project_map = create_semver_project_map product, semver_location
239
- projects_dependencies = get_project_dependencies semver_project_map[semver_file]
240
- semver_files = get_project_dependencies_semver_files projects_dependencies, semver_project_map
241
- semver_files.each { |semver|
242
- increment_version File.join(semver_location, semver), dimension
243
- }
244
- end
245
-
246
- def auto_update_semver project_name, semver_location, semver_file, semver_dimension
247
- Dir.chdir project_name if File.basename(Dir.pwd) != project_name
248
- if(semver_file.nil? || semver_file.strip == '' || semver_file == '.semver')
249
- increment_version '.semver', semver_dimension
250
- else
251
- increment_version File.join(semver_location, semver_file), semver_dimension
252
- update_dependent_semvers project_name, semver_location, semver_file, semver_dimension
253
- end
254
- end
255
-
256
- def auto_update_local_semver
257
- if(!Dir.exist?(VERSIONING) || File.exist?('.semver'))
258
- raise 'Error - local upgrade process only applies to projects with multiple semvers. If you have one semver at root level, please update it manually if needed. Do not invoke auto_update_local_semver task.'
259
- end
260
- updated_semver_with_version_state = fetch_updated_semver
261
- if updated_semver_with_version_state != nil
262
- update_dependent_semvers PRODUCT, VERSIONING, updated_semver_with_version_state[0], updated_semver_with_version_state[1]
263
- end
264
-
265
- display_local_changes_to_user
266
- end