a2zdeploy 1.0.0
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 +7 -0
- data/a2zdeploy.gemspec +12 -0
- data/lib/dependency_tree.rb +67 -0
- data/lib/github_api.rb +140 -0
- data/lib/globalconstants.rb +9 -0
- data/lib/proget_api.rb +32 -0
- data/lib/teamcity_api.rb +29 -0
- data/lib/upgrade.rb +254 -0
- data/lib/upgradeall.rb +71 -0
- data/lib/version.rb +266 -0
- data/lib/version_map.rb +98 -0
- data/rakefile.rb +7 -0
- data/spec/dependency_tree_spec.rb +93 -0
- data/spec/github_api_spec.rb +33 -0
- data/spec/packages.config +24 -0
- data/spec/proj.csproj +206 -0
- data/spec/upgrade_spec.rb +215 -0
- data/spec/upgradeall_spec.rb +37 -0
- data/spec/version_map_spec.rb +47 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8017e6d8f0f0c6438495ba272799199501f109f
|
4
|
+
data.tar.gz: 4f0c0454bb8994e30a189a281b7ba8d14f7512e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2e31bd3a670188f9648f35d469e5439171a3371a56bfb5f79564396d55363c87ee1d41e94254cd55540ed60b67b64ca051c74f0b550dcc0f9886853dbbefe104
|
7
|
+
data.tar.gz: c24aa5b993777be8b6e2556ca0ac816c73f4f0217899bcb98a077f682c9de527d8652d31d29e2bbd7a37c274c77ef7df1be31773fa3d09651ffcb6e82854ffbd
|
data/a2zdeploy.gemspec
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'a2zdeploy'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.date = '2015-12-18'
|
5
|
+
s.summary = 'Given a project dependency chain, updates versions, builds, tests, manages service and cloud settings as well as build environment configuration'
|
6
|
+
s.description = 'Automated Upgrades Gem. Provides version upgrades, build and deployment configuration management'
|
7
|
+
s.authors = ['Suresh Batta']
|
8
|
+
s.email = 'subatta@hotmail.com'
|
9
|
+
s.files = Dir['{lib,spec}/**/*'] + ['a2zdeploy.gemspec', 'rakefile.rb']
|
10
|
+
s.homepage = 'http://rubygems.org/gems/a2zdeploy'
|
11
|
+
s.license = 'MIT'
|
12
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
=begin
|
2
|
+
Defines a simple dependency tree in a has map and allows accessing top and GlobalConstants::NEXT item in the tree.
|
3
|
+
- The keys 'GlobalConstants::ROOT, GlobalConstants::NEXT, GlobalConstants::PREVIOUS and GlobalConstants::PROJECT' are self-descriptive and symbols
|
4
|
+
- GlobalConstants::ROOT's GlobalConstants::PREVIOUS is always nil, so are all leaf node GlobalConstants::NEXT
|
5
|
+
{
|
6
|
+
"GlobalConstants::ROOT" => {
|
7
|
+
"GlobalConstants::PROJECT" => "Ontology",
|
8
|
+
"GlobalConstants::NEXT" => "FhirWalker",
|
9
|
+
"GlobalConstants::PREVIOUS" => nil,
|
10
|
+
"metadata" => "[json or another hash]"
|
11
|
+
},
|
12
|
+
"FhirWalker" => {
|
13
|
+
"GlobalConstants::PROJECT" => "Portal",
|
14
|
+
"GlobalConstants::NEXT" => "EventTracking",
|
15
|
+
"GlobalConstants::PREVIOUS" => "Ontology",
|
16
|
+
"metadata" => "[json or another hash]"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
=end
|
20
|
+
|
21
|
+
require_relative 'globalconstants'
|
22
|
+
|
23
|
+
class DependencyTree
|
24
|
+
|
25
|
+
def initialize dependency_map
|
26
|
+
@dependency_map = dependency_map
|
27
|
+
end
|
28
|
+
|
29
|
+
def root
|
30
|
+
return nil if (@dependency_map.nil? || @dependency_map.class.to_s != GlobalConstants::HASH)
|
31
|
+
|
32
|
+
if @dependency_map.has_key?(GlobalConstants::ROOT)
|
33
|
+
if @dependency_map[GlobalConstants::ROOT].has_key? GlobalConstants::PROJECT
|
34
|
+
@dependency_map[GlobalConstants::ROOT][GlobalConstants::PROJECT]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def next_node current
|
40
|
+
return nil if current.to_s.strip.length == 0
|
41
|
+
return nil if @dependency_map.nil? || @dependency_map.class.to_s != GlobalConstants::HASH
|
42
|
+
return nil if @dependency_map[current] == nil
|
43
|
+
|
44
|
+
if @dependency_map[current].has_key? GlobalConstants::NEXT
|
45
|
+
@dependency_map[current][GlobalConstants::NEXT]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def previous_node current
|
50
|
+
return nil if current.to_s.strip.length == 0
|
51
|
+
return nil if (@dependency_map.nil? || @dependency_map.class.to_s != GlobalConstants::HASH)
|
52
|
+
|
53
|
+
if @dependency_map[current].has_key? GlobalConstants::PREVIOUS
|
54
|
+
@dependency_map[current][GlobalConstants::PREVIOUS]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def traverse
|
59
|
+
current = GlobalConstants::ROOT
|
60
|
+
yield @dependency_map[current][GlobalConstants::PROJECT] if @dependency_map.has_key?(current) && @dependency_map[current].has_key?(GlobalConstants::PROJECT)
|
61
|
+
while current != nil
|
62
|
+
current = next_node(current)
|
63
|
+
yield @dependency_map[current][GlobalConstants::PROJECT] if @dependency_map.has_key?(current) && @dependency_map[current].has_key?(GlobalConstants::PROJECT)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/lib/github_api.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
=begin
|
2
|
+
Provides API accessors for operations over github repos
|
3
|
+
This module has several methods that interface with Git and github
|
4
|
+
Unless otherwise returned specifically with a status,, commands that don't fail return an empty string - ''
|
5
|
+
=end
|
6
|
+
|
7
|
+
require 'addressable/uri'
|
8
|
+
require 'pathname'
|
9
|
+
require 'fileutils'
|
10
|
+
require_relative 'globalconstants'
|
11
|
+
|
12
|
+
module GithubApi
|
13
|
+
|
14
|
+
def GithubApi.CheckoutNewBranch branch
|
15
|
+
puts "Checking out new branch #{branch}..."
|
16
|
+
`git checkout -b #{branch}`
|
17
|
+
end
|
18
|
+
|
19
|
+
def GithubApi.CheckoutExistingBranch branch
|
20
|
+
puts "Checking out existing branch #{branch}..."
|
21
|
+
`git checkout #{branch}`
|
22
|
+
|
23
|
+
# check if checkout succeeded
|
24
|
+
actual_branch = `git rev-parse --abbrev-ref HEAD`
|
25
|
+
|
26
|
+
return actual_branch.chomp! == branch
|
27
|
+
end
|
28
|
+
|
29
|
+
def GithubApi.DoesBranchExist remote, branch
|
30
|
+
puts "Checking if branch #{branch} existing at #{remote}..."
|
31
|
+
`git ls-remote --heads #{remote} #{branch}`
|
32
|
+
end
|
33
|
+
|
34
|
+
def GithubApi.RebaseLocal branch
|
35
|
+
puts "Rebasing #{branch} with checked out branch..."
|
36
|
+
`git rebase #{branch}`
|
37
|
+
end
|
38
|
+
|
39
|
+
def GithubApi.CheckoutLocal branch
|
40
|
+
puts "Checking out local branch: #{branch}..."
|
41
|
+
`git checkout #{branch}`
|
42
|
+
end
|
43
|
+
|
44
|
+
def GithubApi.PushBranch remote, branch
|
45
|
+
puts "Pushing #{branch} to #{remote}..."
|
46
|
+
`git push #{remote} #{branch}`
|
47
|
+
end
|
48
|
+
|
49
|
+
def GithubApi.HaveLocalChanges
|
50
|
+
`git status -s`
|
51
|
+
end
|
52
|
+
|
53
|
+
def GithubApi.DeleteLocalBranch branch
|
54
|
+
`git branch -D #{branch}`
|
55
|
+
end
|
56
|
+
|
57
|
+
def GithubApi.DeleteRemoteBranch remote, branch
|
58
|
+
status = GithubApi.DoesBranchExist remote, branch
|
59
|
+
`git push #{remote} :#{branch}` if status.chomp! == GlobalConstants::EMPTY
|
60
|
+
end
|
61
|
+
|
62
|
+
def GithubApi.PullWithRebase remote, branch
|
63
|
+
`git pull --rebase #{@repo_url} #{@branch}`
|
64
|
+
end
|
65
|
+
|
66
|
+
def GithubApi.CommitChanges comment
|
67
|
+
status = `git add .`
|
68
|
+
if status == GlobalConstants::EMPTY
|
69
|
+
status = `git add -u`
|
70
|
+
else
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
if status == GlobalConstants::EMPTY
|
74
|
+
status = `git commit -m "#{comment}"`
|
75
|
+
else
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
return status != GlobalConstants::EMPTY
|
79
|
+
end
|
80
|
+
|
81
|
+
# we do NOT want to switch to parent folder but stay in current repo dir when we exit this method
|
82
|
+
def GithubApi.CheckoutRepoAfresh repo_url, branch
|
83
|
+
repo = GithubApi.ProjectNameFromRepo repo_url
|
84
|
+
return false if repo == GlobalConstants::EMPTY
|
85
|
+
|
86
|
+
# clear repo folder if it already exists
|
87
|
+
if File.directory? repo
|
88
|
+
puts 'Repository already exists! Cleaning...'
|
89
|
+
FileUtils.rm_rf repo
|
90
|
+
end
|
91
|
+
|
92
|
+
# clone to local
|
93
|
+
puts 'Cloning repo to local...'
|
94
|
+
begin
|
95
|
+
# also tests for valid repo, this will cout if cmd fails, no need for additional message
|
96
|
+
cmd_out = system "git clone #{repo_url}"
|
97
|
+
return false if cmd_out.to_s == 'false'
|
98
|
+
rescue
|
99
|
+
puts "Clone repo for #{repo_url} failed"
|
100
|
+
puts $!
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
|
104
|
+
# checkout requested branch if it's not the default branch checked out when cloned
|
105
|
+
Dir.chdir repo
|
106
|
+
puts "Checking out requested branch: #{branch}"
|
107
|
+
`git fetch`
|
108
|
+
|
109
|
+
cmd_out = GithubApi.CheckoutExistingBranch branch
|
110
|
+
|
111
|
+
return cmd_out
|
112
|
+
end
|
113
|
+
|
114
|
+
def GithubApi.ProjectNameFromRepo repo_url
|
115
|
+
puts "Repo Url provided: #{repo_url}. Parsing..."
|
116
|
+
repo = GlobalConstants::EMPTY
|
117
|
+
begin
|
118
|
+
uri = Addressable::URI.parse repo_url
|
119
|
+
rescue
|
120
|
+
puts "repo_url: #{repo_url} parse failed"
|
121
|
+
return repo
|
122
|
+
end
|
123
|
+
|
124
|
+
if uri.nil?
|
125
|
+
puts 'Invalid repo_url provided'
|
126
|
+
return repo
|
127
|
+
end
|
128
|
+
|
129
|
+
directory = Pathname.new(uri.path).basename
|
130
|
+
if directory.nil?
|
131
|
+
puts 'No directory provided in repo_url'
|
132
|
+
return repo
|
133
|
+
end
|
134
|
+
|
135
|
+
repo = directory.to_s.gsub uri.extname, repo
|
136
|
+
puts "Repository name parsed: #{repo}"
|
137
|
+
|
138
|
+
repo
|
139
|
+
end
|
140
|
+
end
|
data/lib/proget_api.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
def is_package_published packageName, packageVersion, timeout
|
5
|
+
packageLocationUri = "http://nuget2.relayhealth.com/nuget/Carnegie/Packages(Id='#{packageName}',Version='#{packageVersion}')"
|
6
|
+
counter = timeout
|
7
|
+
i = 0
|
8
|
+
found = false;
|
9
|
+
|
10
|
+
while i < counter
|
11
|
+
response = Net::HTTP.get_response(URI packageLocationUri)
|
12
|
+
xmldoc = Nokogiri::XML response.body
|
13
|
+
entry = xmldoc.css "entry id"
|
14
|
+
if entry.to_s.include? packageLocationUri
|
15
|
+
puts "Found #{packageName}-#{packageVersion}"
|
16
|
+
found = true
|
17
|
+
break
|
18
|
+
end
|
19
|
+
sleep 1
|
20
|
+
i += 1
|
21
|
+
end
|
22
|
+
|
23
|
+
if found == false
|
24
|
+
puts "Not found #{packageName}-#{packageVersion}"
|
25
|
+
end
|
26
|
+
|
27
|
+
return found
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sample Usage
|
31
|
+
# a = is_package_published("RelayHealth.DataPlatform.Framework", "24.5.12", 60)
|
32
|
+
# puts a
|
data/lib/teamcity_api.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
=begin
|
2
|
+
Provides API accessors for TeamCity
|
3
|
+
=end
|
4
|
+
|
5
|
+
require 'net/http'
|
6
|
+
require 'builder'
|
7
|
+
|
8
|
+
def trigger_build buildConfigurationId, username, password
|
9
|
+
configContent = create_build_trigger_config buildConfigurationId
|
10
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
11
|
+
http = Net::HTTP.new uri.host, uri.port
|
12
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildQueue"
|
13
|
+
request.body = configContent
|
14
|
+
request.content_type = 'application/xml'
|
15
|
+
request.basic_auth username, password
|
16
|
+
response = http.request request
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def create_build_trigger_config buildConfigurationId
|
21
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
22
|
+
xml.build{
|
23
|
+
xml.triggeringOptions "cleanSources" => "true", "rebuildAllDependencies" => "true", "queueAtTop" => "true"
|
24
|
+
xml.buildType "id" => "#{buildConfigurationId}"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sample Usage
|
29
|
+
# trigger_build("DataPlatform_DataPlatformOntology_ADevelopBuildDataPlatformOntology_2", "username", "password")
|
data/lib/upgrade.rb
ADDED
@@ -0,0 +1,254 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Processes upgrade for a repository that is deployed as a cloud service.
|
4
|
+
|
5
|
+
Inputs:
|
6
|
+
1. Project Manifest that describes repo/project to be processed
|
7
|
+
a. repo name, repo url, branch name
|
8
|
+
b.
|
9
|
+
2. Change Manifest that describes what references have been upgraded due to framework upgrade.
|
10
|
+
Can be as simple as dictionary<string, string> of 'Package:[new version]'
|
11
|
+
example: When TestService is upgraded, we'll know what references have changed.
|
12
|
+
These can be used to replace packages.config and project references
|
13
|
+
=end
|
14
|
+
|
15
|
+
require 'nokogiri'
|
16
|
+
require 'json'
|
17
|
+
require_relative 'github_api'
|
18
|
+
require_relative 'globalconstants'
|
19
|
+
require_relative 'version'
|
20
|
+
|
21
|
+
class UpgradePackages
|
22
|
+
|
23
|
+
UPGRADE_BRANCH = 'upgrade'
|
24
|
+
|
25
|
+
# versions need to be passed in as they are based on a repo_url and branch that's source, likely DP solution
|
26
|
+
def initialize repo_url, branch, versions, config_map
|
27
|
+
@repo_url = repo_url
|
28
|
+
@branch = branch
|
29
|
+
@versions = versions
|
30
|
+
@config_map = config_map
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_inputs
|
34
|
+
return false if @repo_url.to_s.strip.length == 0
|
35
|
+
return false if @branch.to_s.strip.length == 0
|
36
|
+
if (@versions.nil? || @versions.class.to_s != GlobalConstants::HASH)
|
37
|
+
puts 'Version map must be a ' + GlobalConstants::HASH
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
if (@config_map.nil? || @config_map.class.to_s != GlobalConstants::HASH)
|
41
|
+
puts 'Config map must be a ' + GlobalConstants::HASH
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
45
|
+
# fail if env vars were not supplied
|
46
|
+
if (!@config_map.has_key? 'env_vars')
|
47
|
+
puts 'Environment variables not supplied. Cannot continue!'
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
|
51
|
+
# fail if metadata was not supplied
|
52
|
+
if (!@config_map.has_key? 'metadata')
|
53
|
+
puts 'Metadata variables not supplied. Cannot continue!'
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
# We should do more specific test of which environment variables are we expecting or which metatdata are we expecting
|
58
|
+
#if project publishes nuget we need to check if major /minor/patch incrmeented but not all 3
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
|
62
|
+
def checkout_upgrade_branch
|
63
|
+
# obtain an upgrade branch
|
64
|
+
puts 'Getting upgrade branch...'
|
65
|
+
if (GithubApi.DoesBranchExist('origin', UPGRADE_BRANCH) != GlobalConstants::EMPTY)
|
66
|
+
puts 'Checking out existing upgrade branch...'
|
67
|
+
return false if !GithubApi.CheckoutExistingBranch UPGRADE_BRANCH == GlobalConstants::EMPTY
|
68
|
+
else
|
69
|
+
puts 'Checking out new upgrade branch...'
|
70
|
+
return false if !GithubApi.CheckoutNewBranch UPGRADE_BRANCH == GlobalConstants::EMPTY
|
71
|
+
end
|
72
|
+
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
def Do
|
77
|
+
return false if !validate_inputs
|
78
|
+
|
79
|
+
# checkout repo and branch
|
80
|
+
return false if !GithubApi.CheckoutRepoAfresh @repo_url, @branch
|
81
|
+
|
82
|
+
return false if !checkout_upgrade_branch
|
83
|
+
|
84
|
+
# replace versions in package config files
|
85
|
+
pkg_files = Dir.glob '**/packages.config'
|
86
|
+
if (replace_package_versions(pkg_files) == false)
|
87
|
+
puts "Package version replacement failed."
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
|
91
|
+
# replace versions in project references
|
92
|
+
proj_files = Dir.glob '**/*.csproj'
|
93
|
+
if (replace_project_versions(proj_files) == false)
|
94
|
+
puts "Project version replacement failed."
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
|
98
|
+
# Check in manifest if project publish nuget? If yes, increment .semver
|
99
|
+
increment_semver_if_publish
|
100
|
+
|
101
|
+
# do rake build to test for compilation errors. This needs ENV vars set, passed in via config
|
102
|
+
set_project_env_vars @config_map['env_vars']
|
103
|
+
output = system 'rake'
|
104
|
+
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
|
110
|
+
end
|
111
|
+
|
112
|
+
# see if any files changed and commit
|
113
|
+
git_status = GithubApi.HaveLocalChanges
|
114
|
+
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
|
+
end
|
118
|
+
|
119
|
+
# rebase and push the branch
|
120
|
+
puts 'Rebasing and pushing...'
|
121
|
+
GithubApi.CheckoutLocal @branch
|
122
|
+
GithubApi.RebaseLocal UPGRADE_BRANCH
|
123
|
+
|
124
|
+
# if push fails, do a pull --rebase of the branch and fail the upgrade.
|
125
|
+
# Upstream commits need to accounted for and full upgrade cycle must be triggered
|
126
|
+
# Build failure email will inform concerned team
|
127
|
+
git_status = GithubApi.PushBranch(@repo_url, @branch) == GlobalConstants::EMPTY
|
128
|
+
if git_status
|
129
|
+
puts "Version upgrade changes have been rebased with #{@repo_url}/#{@branch} and pushed"
|
130
|
+
else
|
131
|
+
GithubApi.PullWithRebase @repo_url, @branch
|
132
|
+
GithubApi.PushBranch @repo_url, @branch
|
133
|
+
puts "Push after version upgrade failed for #{@repo_url}/#{@branch}. Pull with rebase done and pushed"
|
134
|
+
return false
|
135
|
+
end
|
136
|
+
|
137
|
+
# delete upgrade branch both local and remote
|
138
|
+
GithubApi.DeleteLocalBranch UPGRADE_BRANCH
|
139
|
+
GithubApi.DeleteRemoteBranch @repo_url, UPGRADE_BRANCH
|
140
|
+
|
141
|
+
# handle configuration changes. The settings file, update hash or TeamCity Params list is passed in through Ctor
|
142
|
+
|
143
|
+
true
|
144
|
+
end
|
145
|
+
|
146
|
+
def replace_package_versions pkg_files
|
147
|
+
begin
|
148
|
+
# iterate each package file, replace version numbers and save
|
149
|
+
pkg_files.each{ |file|
|
150
|
+
puts "Finding packages in: #{Dir.pwd}/#{file}..."
|
151
|
+
doc = Nokogiri::XML File.read(file)
|
152
|
+
nodes = doc.xpath "//*[@id]"
|
153
|
+
nodes.each { |node|
|
154
|
+
if (@versions.has_key?(node['id']))
|
155
|
+
node['version'] = @versions[node['id']]
|
156
|
+
#puts "#{node['id']} #{node['version']} -- #{@versions[node['id']]}"
|
157
|
+
end
|
158
|
+
}
|
159
|
+
|
160
|
+
File.write file, doc.to_xml
|
161
|
+
}
|
162
|
+
rescue
|
163
|
+
puts $!
|
164
|
+
return false
|
165
|
+
end
|
166
|
+
return true
|
167
|
+
end
|
168
|
+
|
169
|
+
=begin
|
170
|
+
Typical block of reference node change looks like:
|
171
|
+
Before:
|
172
|
+
<Reference Include="MassTransit, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b8e0e9f2f1e657fa, processorArchitecture=MSIL">
|
173
|
+
<HintPath>..\packages\MassTransit.3.0.14\lib\net45\MassTransit.dll</HintPath>
|
174
|
+
<Private>True</Private>
|
175
|
+
</Reference>
|
176
|
+
After: (file version removed, hint path version number updated)
|
177
|
+
<Reference Include="MassTransit">
|
178
|
+
<HintPath>..\packages\MassTransit.3.0.15\lib\net45\MassTransit.dll</HintPath>
|
179
|
+
<Private>True</Private>
|
180
|
+
</Reference>
|
181
|
+
=end
|
182
|
+
def replace_project_versions proj_files
|
183
|
+
begin
|
184
|
+
# iterate each package file, replace version numbers and save
|
185
|
+
proj_files.each{ |file|
|
186
|
+
puts "Updating references in: #{file}..."
|
187
|
+
doc = Nokogiri::XML File.read file
|
188
|
+
nodes = doc.search 'Reference'
|
189
|
+
nodes.each { |node|
|
190
|
+
ref_val = node['Include']
|
191
|
+
# grab the identifier
|
192
|
+
id = ref_val.split(',')[0]
|
193
|
+
# clean out file version
|
194
|
+
node['Include'] = id
|
195
|
+
|
196
|
+
# replace version in hint path
|
197
|
+
hint_path = node.search 'HintPath'
|
198
|
+
if hint_path && hint_path[0] != nil
|
199
|
+
hint_path_value = hint_path[0].children.to_s
|
200
|
+
# this identifier is not the same as the node['Include'] one.
|
201
|
+
# For ex., Runtime, Core and Storage assemblies will be referred to from within other packages like Management, Test etc
|
202
|
+
hint_path_id = id_from_hint_path hint_path_value
|
203
|
+
if @versions.has_key? hint_path_id
|
204
|
+
hint_path_parts = hint_path_value.split '\\'
|
205
|
+
hint_path_parts[2] = hint_path_id + '.' + @versions[hint_path_id]
|
206
|
+
hint_path[0].children = hint_path_parts.join '\\'
|
207
|
+
end
|
208
|
+
end
|
209
|
+
}
|
210
|
+
File.write file, doc.to_xml
|
211
|
+
}
|
212
|
+
rescue
|
213
|
+
puts $!
|
214
|
+
return false
|
215
|
+
end
|
216
|
+
return true
|
217
|
+
end
|
218
|
+
|
219
|
+
def id_from_hint_path path
|
220
|
+
name = path.split('\\')[2].split '.'
|
221
|
+
name_without_ver = GlobalConstants::EMPTY
|
222
|
+
name.all? {|i|
|
223
|
+
if i.to_i == 0
|
224
|
+
name_without_ver += i.to_s + '.'
|
225
|
+
end
|
226
|
+
}
|
227
|
+
name_without_ver.chomp '.'
|
228
|
+
end
|
229
|
+
|
230
|
+
def set_project_env_vars envs
|
231
|
+
envs.keys.each { | key |
|
232
|
+
ENV[key] = envs[key]
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
def increment_semver_if_publish
|
237
|
+
if !is_team_city_run
|
238
|
+
# local run
|
239
|
+
auto_update_local_semver
|
240
|
+
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.**********'
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|