a2zdeploy 1.0.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ReadMe.md +198 -0
- data/a2zdeploy.gemspec +3 -3
- data/lib/a2zdeploy.rb +21 -0
- data/lib/dependency_tree.rb +0 -1
- data/lib/github_api.rb +14 -17
- data/lib/proget_api.rb +0 -2
- data/lib/teamcity_api.rb +233 -17
- data/lib/upgrade.rb +31 -27
- data/lib/upgradeall.rb +33 -13
- data/lib/version_map.rb +34 -13
- metadata +4 -11
- data/lib/version.rb +0 -266
- data/rakefile.rb +0 -7
- data/spec/dependency_tree_spec.rb +0 -93
- data/spec/github_api_spec.rb +0 -33
- data/spec/packages.config +0 -24
- data/spec/proj.csproj +0 -206
- data/spec/upgrade_spec.rb +0 -215
- data/spec/upgradeall_spec.rb +0 -37
- data/spec/version_map_spec.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d26ef64a5e56fba85aad32a6716bc11d04edd861
|
4
|
+
data.tar.gz: c846d6a9030f00ab41d8ba47cbf606a3c04bbec5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d5e93a79e70af4176b95434edfcc1fb5d83df3c9f8a8b6060a8f32065780f6461e79c551880f6b0a909aca305fb8a8616b1bc940c1e7acb2fecad1a487ed4fb
|
7
|
+
data.tar.gz: 3c95f5c78ed0915dbfe811b57f316d0a87dee466e2e197d810756edbfe9e5e2e7380c5e22a0052a1ed32a0d0d7cebbbff39a037debed93cd2f4c01fa256cacbb
|
data/ReadMe.md
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
# DataPlatform Automated Upgrade
|
2
|
+
|
3
|
+
Automated upgrades were introduced in DataPlatform Runtime Framework version > 24.5.1 in an effort to promote better usability, replace manual processes, stop/mitigate “breaking” changes in Framework releases and to streamline the update experience overall.
|
4
|
+
|
5
|
+
Anyone working with the DataPlatform knows that it is updated regularly. It’s a fact of modern life, everyday brings slack notifications that DataPlatform Framework Version 26.y.z is ready, Ontology 3.y.z wants to be installed and you need version 2.y.z of FHIRWalker RIGHT NOW.
|
6
|
+
|
7
|
+
_"In the world of software management there exists a dread place called "dependency hell." The bigger your system grows and the more packages you integrate into your software, the more likely you are to find yourself, one day, in this pit of despair.""_ – Tom Preston-Werner
|
8
|
+
|
9
|
+
|
10
|
+
### Breaking Changes
|
11
|
+
In the unlikely event, that there are breaking changes, [**we**<--who is this?] stop the script. The team whose build is broken gets the opportunity fix it, and then the upgrade is kicked off from where it had previously stopped. If the build breaks there is not an option to roll back. The procedure simply continues down the decision tree workflow. As things stand, it’s not clear if you can fall back to an older Framework installation by doing a new, from-scratch reinstall using your original repo.
|
12
|
+
|
13
|
+
[**QUESTION:** Lastly, I'm not sure how the automated upgrade gem will handle breaking changes - could use more detail (which may not have been worked out yet by plasma) about breaking changes and how these will be distributed to teams to change their code in accordance with these changes. This also goes for Team City configuration changes and settings/org-tenant changes that may need updating when a new framework is released.]
|
14
|
+
|
15
|
+
|
16
|
+
## Overview
|
17
|
+
|
18
|
+
Automated Upgrades brings all your upgrades together in one place. It's real-time upgrading based on the project or service dependency tree for DataPlatform teams. We're on a mission to make your working life simpler and more productive.
|
19
|
+
Automated Upgrades is a [ruby gem][2] that can be included within a ruby script. This gem enables developers to test a full end-to-end dependency tree upgrade locally as well as a partial-tree upgrade test. This same "gem in a script" can be used to run the upgrade cycle in TeamCity.
|
20
|
+
|
21
|
+
**Automated Upgrades encapsulates two processes:**
|
22
|
+
|
23
|
+
- A NuGet update
|
24
|
+
- A TeamCity deploy build for DataPlatform’s existing or dependent services
|
25
|
+
which both use a manifest file as their roadmap.
|
26
|
+
|
27
|
+
The manual NuGet update uses the manifest file to do this thing
|
28
|
+
|
29
|
+
The TeamCity build uses this same manifest file and is triggered by a successful DataPlatform Runtime build completion via the master branch in GitHub. The develop branch is used for pre-release NuGet packages.
|
30
|
+
|
31
|
+
[The above paragraph has this revision: **QUESTION:** I believe that the process will begin when DataPlatform Framework is checked into master, rather than develop since plasma releases are in the master branch and develop is used for prerelease packages. The same goes for other teams who release nuget packages.]
|
32
|
+
|
33
|
+
The process is considered complete when existing and dependent services finish deployment and automated User Acceptance Tests (UATs) are kicked-off.
|
34
|
+
|
35
|
+
Automated upgrades allows manual intervention for cases such as breaking code and configuration changes, and also allows interrupt and restart at any point in the process, so you are able to modify as necessary.
|
36
|
+
|
37
|
+
[**QUESTION:** Also, I'm unsure about the flow with upgrading locally vs upgrading in Team City and the nuget packages. Does this mean that whenever a project upgrades with lower dependencies, whoever has checked it will upgrade and build the other services before pushing to the develop or master branch? That can probably be answered by someone in plasma, since they're working on the flow. ]
|
38
|
+
|
39
|
+
Automated Upgrades encapsulates a manual Nuget update and TeamCity deploy kickoff for DataPlatform’s Existing or Dependent services based on a manifest file. It ends when dependent services finish deployment and automated UATs are kicked off.
|
40
|
+
|
41
|
+
Automated upgrades allows manual intervention for cases such as breaking code and configuration changes, and also allows interrupt and restart at any point in the process, so you are able to modify as necessary
|
42
|
+
|
43
|
+
## Projects & Components
|
44
|
+
|
45
|
+
This repository holds all artifacts: design, code and supporting files that go into creating a solution for automated upgrades and deployment of services against a chosen DataPlatform Framework [Runtime?] version.
|
46
|
+
|
47
|
+
## How does it work?
|
48
|
+
|
49
|
+
The automated upgrade project is dependent on DataPlatform teams first adding
|
50
|
+
`.semvers` files to each project. This allows for the automation process to kickoff the following workflow.
|
51
|
+
|
52
|
+
![automated_upgrade_flow][3]
|
53
|
+
|
54
|
+
Once the Runtime Build has successfully completed, the **upgrade project** is triggered in TeamCity and begins the following steps:
|
55
|
+
|
56
|
+
1. The gem extracts a version map (JSON file) of packages of DataPlatform Projects and nuget versions from the [.semvers][4] files.
|
57
|
+
2. Once the version map is extracted, it compares itself to a previous version map for changes. If there are changes, it walks the deployment project dependency tree to process the upgrade according to the dependency chain manifest.
|
58
|
+
- If there aren't changes, the gem triggers the _existing?_ TeamCity chain of deployments. **[Projects that build and deply nugets must be exempted(?).]** If the script runs to completion without errors, we assume success and consider it validated.
|
59
|
+
- Trigger acceptance tests
|
60
|
+
- Reset project completion status to unprocessed for all
|
61
|
+
- push updated manifest
|
62
|
+
- end
|
63
|
+
3. It next seeks what is the next project in the dependency tree in a failed or unprocessed state? [how does it choose, via alphabetical, numberical or our logical progression, of first this team, then that team, etc.?] If a project has indeed failed, or is in an unprocessed state:
|
64
|
+
- The gem looks for the Project's environment variables. If there are no environment variables or if they have incorrect file names, the process fails and exits [Does it provide any --verbose message?]:
|
65
|
+
|
66
|
+
**EXAMPLE:**
|
67
|
+
```
|
68
|
+
Failed, wah-wah: frameworkweb.semver), filename should be Framework.Web.semver
|
69
|
+
```
|
70
|
+
|
71
|
+
4. If your project has valid Environment vaiables, it first checks:
|
72
|
+
- Does the branch exist? If so, the gem checks out the source and specified branch.
|
73
|
+
- If not, service [<--what do you mean by Service here?] derives an upgrade branch from a specified branch. (automagically or manually?)
|
74
|
+
5. If your project's `semver` file matches special/nonspecial [<--what consitutes being *special?*]
|
75
|
+
- If no, dependency walk is complete, trigger acceptance tests.
|
76
|
+
6. Run nuget package version update for specific changed DataPlatform package.
|
77
|
+
[**QUESTION:** step 6 "execute nuget", references the deployment of nuget packages, which requires the TC build to run and execute unit and integration tests, as well as BVTs. This would happen in the middle of each upgrade for each service on TeamCity and before Acceptance Tests would build. So I think this step would be encapsulated in previous step]
|
78
|
+
7. Does project a. build and b. publish nuget? or does the built project publish the Nuget successfully? or is this a project that publishes NuGets?
|
79
|
+
- If yes, increment the [.semver] <--minor, major? [link to semver doc here]
|
80
|
+
- **If no, do the below, but no version update? why not? what's different? this scenario goes to fail message without .semver info**
|
81
|
+
- After the .semver file is updated, set [<--set where? why? ]the project environment variables.
|
82
|
+
8. Gem checks? TeamCity checks? DevOps checks to see if the build is successful or has test faillures.
|
83
|
+
- Success: Commit version updates and .semver changes with standard message or success message?
|
84
|
+
- Failure: Commit version updates and .semver changes with failure message.
|
85
|
+
9. Checkout and rebase specified branch with upgrade branch. (what if rebase fails?)
|
86
|
+
10. Push rebased branch, delete "upgrade branch" (both locally and remotely) if pushed. (what if delete local/remote fails? duplication?)
|
87
|
+
- **Push failed**? (commit history has diverged)
|
88
|
+
- Upon Push failure, pull rebase specified branch (automagically or manually?)
|
89
|
+
- Update manifest with project status marked as failed, allowing for manual intervention.
|
90
|
+
- Email stakeholders of failure notification (can we slackbot the build?). Who is the first-responder? Project Team? DevOps? PMs?
|
91
|
+
- Push updated manifest to where? Assume this is all failures and successes?
|
92
|
+
11. Gem checks to see if (what?--project or specific file (s)?) has a Configuration change.
|
93
|
+
- If a configuration has changed, it runs a settings/cloud service update for the Service. What file(s) are modified? JSON, `app.config`?
|
94
|
+
12. If configuration is successful it triggers a TeamCity build. If update of configuration fails...
|
95
|
+
- need failure scenario here.
|
96
|
+
13. Upon successful TeamCity Build, (again check to see)? if NuGet is published by project.
|
97
|
+
- Success: Save updated nuget information and walk deployment project dependency tree to process upgrade per newly updated manifest.
|
98
|
+
- Failure: TeamCity has failed, investigate cause and reinitiate from what point?
|
99
|
+
14. Now what? : ) Assumption, we have a manifest with success and failures...
|
100
|
+
|
101
|
+
##### Generate Version Map
|
102
|
+
The script first generates a version map, which lists all package version references from DataPlatform Runtime solution must be generated. This list can go into a shared repository that has other artifacts to be used for the upgrade cycle like dependency map, configuration manifest etc.
|
103
|
+
|
104
|
+
##### Upgrade Repo locally
|
105
|
+
A single repository is version upgraded. At this time, nugets are not published, and no branches are pushed. Should run partial tree?
|
106
|
+
|
107
|
+
##### Upgrade a repo on build server
|
108
|
+
Q: How does the process handle new services that are added?
|
109
|
+
A: New services can be added by updating the manifest.
|
110
|
+
When started from a Teamcity project, a single repo will be upgraded. Either the service or a NuGet publishing project.
|
111
|
+
Q: Does upgrade all only include EME services or will it impact Pop Manager and DDA Extract?
|
112
|
+
|
113
|
+
A: This will include any service currently being built on TeamCity and using the DataPlatform.
|
114
|
+
|
115
|
+
##### Upgrade all based on dependency tree
|
116
|
+
|
117
|
+
You can subscribe to any app's what?
|
118
|
+
|
119
|
+
## Scheduled upgrades?
|
120
|
+
|
121
|
+
Yes, upgrades can be scheduled in [TeamCity][5].
|
122
|
+
|
123
|
+
## Which apps?
|
124
|
+
|
125
|
+
Rake? (used for building data platform)
|
126
|
+
This repository holds all artifacts - design, code and supporting files that go into creating solution for automated upgrade and deployment of services against chosen framework version
|
127
|
+
- [Azure PowerShell 0.9.8.1](https://github.com/Azure/azure-PowerShell/releases)or just the script?
|
128
|
+
- [Ruby 2.0.0-p481 (32-bit)][6]
|
129
|
+
- [Access to the unsecured gem source](http://ndhaxpgit01.mckesson.com/Carnegie/Documentation/wiki/Versions-Script#step-1-add-the-unsecured-http-gem-source)
|
130
|
+
**Ruby Gems:** Can we add pessimistic version constraint syntax?
|
131
|
+
```
|
132
|
+
gem "cucumber", ">=0.8.5", "<0.9.0"
|
133
|
+
```
|
134
|
+
- [addressable][7] (2.4.0)
|
135
|
+
- [nokogiri ][8] (1.6.5)
|
136
|
+
- [semver2][9] (3.3.3)
|
137
|
+
|
138
|
+
## Relevant coding conventions
|
139
|
+
|
140
|
+
- Ensure that tab space in your text editor is set to 2, which is the default for Ruby.
|
141
|
+
- If using Sublime Text 3, use the [BeautifyRuby][10] package and setup settings to use 'Beautify on Save'. In the **Preferences** menu --> Package Settings --> BeautifyRuby --> Settings - Default, add the following:
|
142
|
+
PowerShell Scripts run by the Gem
|
143
|
+
- Put C sharp info here?
|
144
|
+
- Ruby based
|
145
|
+
|
146
|
+
|
147
|
+
### Developing with Ruby
|
148
|
+
|
149
|
+
- Ensure tab space in editor is set to 2
|
150
|
+
```
|
151
|
+
"translate_tabs_to_spaces": true,
|
152
|
+
"tab_size": 2
|
153
|
+
```
|
154
|
+
- If using Sublime Text 3, use [BeautifyRuby][5] package and setup settings to use 'Beautify on Save'. Go to Preferences menu --> Package Settings --> BeautifyRuby --> Settings - Default and add the following
|
155
|
+
- Avoid using return statements when returning values from methods. The last variable in method is returned
|
156
|
+
|
157
|
+
```
|
158
|
+
|
159
|
+
def test
|
160
|
+
s = "A String"
|
161
|
+
s # not return s
|
162
|
+
end
|
163
|
+
|
164
|
+
def comparer valA, valB
|
165
|
+
valA + 2 < valB # no need for return in front
|
166
|
+
end
|
167
|
+
|
168
|
+
```
|
169
|
+
|
170
|
+
- When catching exceptions use `puts $!` to display full exception
|
171
|
+
- Use `p [variable]` to display object and it's internals. `puts [variable]` only displays toString version
|
172
|
+
- Use double quotes for strings only if one or more variables are being interpolated
|
173
|
+
- Call methods with params, create methods with params without braces as much as possible
|
174
|
+
- To run all tests, change to src\ folder and run `rake test`
|
175
|
+
- To run tests individually: `ruby.exe .\spec\upgrade_spec.rb -n test_fail_on_missing_env_vars`
|
176
|
+
- Ruby gems required - addressable (2.4.0), nokogiri (1.6.5), semver2 (3.3.3)
|
177
|
+
|
178
|
+
## Development / testing environments
|
179
|
+
|
180
|
+
- To run all tests, change directories `cd` into src\ folder and run `rake test`
|
181
|
+
- To run tests individually: `ruby.exe .\spec\upgrade_spec.rb -n test_fail_on_missing_env_vars`
|
182
|
+
- Updated tests, begin update all
|
183
|
+
|
184
|
+
## Additional Resources
|
185
|
+
|
186
|
+
More information to come.
|
187
|
+
|
188
|
+
[1]: http://tom.preston-werner.com/
|
189
|
+
[2]: https://rubygems.org/
|
190
|
+
[3]: http://ndhaxpgit01.mckesson.com/SureshBatta/AutomatedUpgrade/raw/master/design/automated_upgrade_flow.png
|
191
|
+
[4]: http://semver.org/
|
192
|
+
[5]: https://packagecontrol.io/packages/BeautifyRuby
|
193
|
+
[6]: https://confluence.jetbrains.com/display/TCD8/Configuring+Schedule+Triggers
|
194
|
+
[7]: http://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.0.0-p481.exe
|
195
|
+
[8]: https://rubygems.org/gems/addressable/versions/2.4.0
|
196
|
+
[9]: https://rubygems.org/gems/nokogiri/versions/1.6.5
|
197
|
+
[10]: https://rubygems.org/gems/semver2/versions/3.3.3
|
198
|
+
[11]: https://packagecontrol.io/packages/BeautifyRuby
|
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.
|
4
|
-
s.date = '2015-12-
|
3
|
+
s.version = '1.0.2'
|
4
|
+
s.date = '2015-12-30'
|
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['{lib
|
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
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'dependency_tree'
|
2
|
+
require_relative 'globalconstants'
|
3
|
+
require_relative 'proget_api.rb'
|
4
|
+
require_relative 'teamcity_api.rb'
|
5
|
+
require_relative 'github_api.rb'
|
6
|
+
require_relative 'upgrade.rb'
|
7
|
+
require_relative 'upgradeall.rb'
|
8
|
+
require_relative 'github_api'
|
9
|
+
require_relative 'version_map'
|
10
|
+
|
11
|
+
require 'addressable/uri'
|
12
|
+
require 'pathname'
|
13
|
+
require 'fileutils'
|
14
|
+
require 'net/http'
|
15
|
+
|
16
|
+
require 'nokogiri'
|
17
|
+
require 'net/http'
|
18
|
+
require 'builder'
|
19
|
+
require 'json'
|
20
|
+
require 'azdeploy'
|
21
|
+
require 'semver'
|
data/lib/dependency_tree.rb
CHANGED
data/lib/github_api.rb
CHANGED
@@ -4,11 +4,6 @@
|
|
4
4
|
Unless otherwise returned specifically with a status,, commands that don't fail return an empty string - ''
|
5
5
|
=end
|
6
6
|
|
7
|
-
require 'addressable/uri'
|
8
|
-
require 'pathname'
|
9
|
-
require 'fileutils'
|
10
|
-
require_relative 'globalconstants'
|
11
|
-
|
12
7
|
module GithubApi
|
13
8
|
|
14
9
|
def GithubApi.CheckoutNewBranch branch
|
@@ -33,6 +28,7 @@ module GithubApi
|
|
33
28
|
|
34
29
|
def GithubApi.RebaseLocal branch
|
35
30
|
puts "Rebasing #{branch} with checked out branch..."
|
31
|
+
`git stash`
|
36
32
|
`git rebase #{branch}`
|
37
33
|
end
|
38
34
|
|
@@ -63,18 +59,19 @@ module GithubApi
|
|
63
59
|
`git pull --rebase #{@repo_url} #{@branch}`
|
64
60
|
end
|
65
61
|
|
66
|
-
def GithubApi.CommitChanges comment
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
62
|
+
def GithubApi.CommitChanges comment, git_status
|
63
|
+
val = git_status.split("\n")
|
64
|
+
val.each { |x|
|
65
|
+
value = x.split(' M ').last
|
66
|
+
if (/.csproj/.match(value) || /packages.config/.match(value))
|
67
|
+
status = `git add #{value}`
|
68
|
+
if status != GlobalConstants::EMPTY
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
status = `git commit -m "#{comment}"`
|
78
75
|
return status != GlobalConstants::EMPTY
|
79
76
|
end
|
80
77
|
|
data/lib/proget_api.rb
CHANGED
data/lib/teamcity_api.rb
CHANGED
@@ -5,25 +5,241 @@
|
|
5
5
|
require 'net/http'
|
6
6
|
require 'builder'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
module TeamCityApi
|
9
|
+
|
10
|
+
#Build trigger API
|
11
|
+
def TeamCityApi.trigger_build buildConfigurationId, username, password
|
12
|
+
configContent = create_build_trigger_config buildConfigurationId
|
13
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
14
|
+
http = Net::HTTP.new uri.host, uri.port
|
15
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildQueue"
|
16
|
+
request.body = configContent
|
17
|
+
request.content_type = 'application/xml'
|
18
|
+
request.basic_auth username, password
|
19
|
+
http.request request
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def TeamCityApi.create_build_trigger_config buildConfigurationId
|
24
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
25
|
+
xml.build{
|
26
|
+
xml.triggeringOptions "cleanSources" => "true", "rebuildAllDependencies" => "true", "queueAtTop" => "true"
|
27
|
+
xml.buildType "id" => "#{buildConfigurationId}"
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
#Project Get/Create API
|
32
|
+
def TeamCityApi.get_project_by_id projectId, username, password
|
33
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
34
|
+
http = Net::HTTP.new uri.host, uri.port
|
35
|
+
request = Net::HTTP::Get.new "/app/rest/projects/id:#{projectId}", {'Accept' => 'application/json'}
|
36
|
+
request.basic_auth username, password
|
37
|
+
response = http.request request
|
38
|
+
# File handling will be removed and instead use Tempfile for better security
|
39
|
+
target = open("../spec/ProjectConfigByProjectId", 'w')
|
40
|
+
target.truncate(0)
|
41
|
+
target.write(response.body)
|
42
|
+
target.close
|
43
|
+
end
|
44
|
+
|
45
|
+
def TeamCityApi.create_new_project inputFile, username, password
|
46
|
+
file = File.open("../spec/#{inputFile}", "r")
|
47
|
+
requestContent = file.read
|
48
|
+
uri = URI.parse "http://localhost:9999/"
|
49
|
+
http = Net::HTTP.new uri.host, uri.port
|
50
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/projects", {'Accept' => 'application/json'}
|
51
|
+
request.body = requestContent
|
52
|
+
request.content_type = 'application/json'
|
53
|
+
request.basic_auth username, password
|
54
|
+
response = http.request request
|
55
|
+
puts response.body
|
56
|
+
end
|
57
|
+
|
58
|
+
#VCS-Root Get/Create API
|
59
|
+
def TeamCityApi.get_vcs_roots_by_id vcsRootId, username, password
|
60
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
61
|
+
http = Net::HTTP.new uri.host, uri.port
|
62
|
+
request = Net::HTTP::Get.new "/httpAuth/app/rest/vcs-roots/id:#{vcsRootId}", {'Accept' => 'application/json'}
|
63
|
+
request.basic_auth username, password
|
64
|
+
response = http.request request
|
65
|
+
# File handling will be removed and instead use Tempfile for better security
|
66
|
+
target = open("../spec/VcsRootConfigByVcsRootId", 'w')
|
67
|
+
target.truncate(0)
|
68
|
+
target.write(response.body)
|
69
|
+
target.close
|
70
|
+
end
|
71
|
+
|
72
|
+
def TeamCityApi.create_new_vcs_root inputFile, username, password
|
73
|
+
file = File.open("../spec/#{inputFile}", "r")
|
74
|
+
requestContent = file.read
|
75
|
+
uri = URI.parse "http://localhost:9999/"
|
76
|
+
http = Net::HTTP.new uri.host, uri.port
|
77
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/vcs-roots", {'Accept' => 'application/json'}
|
78
|
+
request.body = requestContent
|
79
|
+
request.content_type = 'application/json'
|
80
|
+
request.basic_auth username, password
|
81
|
+
response = http.request request
|
82
|
+
puts response.body
|
83
|
+
end
|
84
|
+
|
85
|
+
#Build Config Get/Create API
|
86
|
+
def TeamCityApi.get_build_configs_by_projectId projectId, username, password
|
87
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
88
|
+
http = Net::HTTP.new uri.host, uri.port
|
89
|
+
request = Net::HTTP::Get.new "/app/rest/projects/id:#{projectId}/buildTypes", {'Accept' => 'application/json'}
|
90
|
+
request.basic_auth username, password
|
91
|
+
response = http.request request
|
92
|
+
# File handling will be removed and instead use Tempfile for better security
|
93
|
+
target = open("../spec/BuildConfigsByProjectId", 'w')
|
94
|
+
target.truncate(0)
|
95
|
+
target.write(response.body)
|
96
|
+
target.close
|
97
|
+
end
|
98
|
+
|
99
|
+
def TeamCityApi.get_build_configs_by_projectId_and_build_configurationId projectId, buildConfigurationId, username, password
|
100
|
+
uri = URI.parse "http://teamcity.relayhealth.com"
|
101
|
+
http = Net::HTTP.new uri.host, uri.port
|
102
|
+
request = Net::HTTP::Get.new "/app/rest/projects/id:#{projectId}/buildTypes/id:#{buildConfigurationId}", {'Accept' => 'application/json'}
|
103
|
+
request.basic_auth username, password
|
104
|
+
response = http.request request
|
105
|
+
# File handling will be removed and instead use Tempfile for better security
|
106
|
+
target = open("../spec/BuildConfigByProjectAndBuildConfigurationId", 'w')
|
107
|
+
target.truncate(0)
|
108
|
+
target.write(response.body)
|
109
|
+
target.close
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
def TeamCityApi.create_new_build_configuration projectId, inputFile, username, password
|
117
|
+
file = File.open("../spec/#{inputFile}", "r")
|
118
|
+
requestContent = file.read
|
119
|
+
uri = URI.parse "http://localhost:9999/"
|
120
|
+
http = Net::HTTP.new uri.host, uri.port
|
121
|
+
|
122
|
+
|
123
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/projects/id:#{projectId}/buildTypes", {'Accept' => 'application/json'}
|
124
|
+
request.body = requestContent
|
125
|
+
request.content_type = 'application/json'
|
126
|
+
request.basic_auth username, password
|
127
|
+
response = http.request request
|
128
|
+
# File handling will be removed and instead use Tempfile for better security
|
129
|
+
target = open("../spec/CreateNewBuildConfigurationResponse", 'w')
|
130
|
+
target.truncate(0)
|
131
|
+
target.write(response.body)
|
132
|
+
target.close
|
133
|
+
end
|
134
|
+
|
135
|
+
# Setup build configuration settings
|
136
|
+
def TeamCityApi.set_build_configuration_setting buildConfigurationId, settingName, settingValue, username, password
|
137
|
+
uri = URI.parse "http://localhost:9999/"
|
138
|
+
http = Net::HTTP.new uri.host, uri.port
|
139
|
+
request = Net::HTTP::Put.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/settings/#{settingName}"
|
140
|
+
request.body = settingValue
|
141
|
+
request.content_type = 'text/plain'
|
142
|
+
request.basic_auth username, password
|
143
|
+
response = http.request request
|
144
|
+
end
|
145
|
+
|
146
|
+
# Setup build configuration parameters
|
147
|
+
def TeamCityApi.set_build_configuration_parameter buildConfigurationId, parameterName, parameterValue, username, password
|
148
|
+
uri = URI.parse "http://localhost:9999/"
|
149
|
+
http = Net::HTTP.new uri.host, uri.port
|
150
|
+
request = Net::HTTP::Put.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/parameters/#{parameterName}"
|
151
|
+
request.body = parameterValue
|
152
|
+
request.content_type = 'text/plain'
|
153
|
+
request.basic_auth username, password
|
154
|
+
response = http.request request
|
155
|
+
end
|
156
|
+
|
157
|
+
# Setup build configuration Vcs-Root
|
158
|
+
def TeamCityApi.set_build_configuration_vcs_root buildConfigurationId, vcsRootId, username, password
|
159
|
+
uri = URI.parse "http://localhost:9999/"
|
160
|
+
http = Net::HTTP.new uri.host, uri.port
|
161
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/vcs-root-entries/"
|
162
|
+
request.body = create_build_config_vcs_root_config vcsRootId
|
163
|
+
request.content_type = 'application/xml'
|
164
|
+
request.basic_auth username, password
|
165
|
+
|
166
|
+
response = http.request request
|
167
|
+
end
|
18
168
|
|
19
169
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
xml
|
24
|
-
|
25
|
-
|
170
|
+
|
171
|
+
|
172
|
+
def TeamCityApi.create_build_config_vcs_root_config vcsRootId
|
173
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
xml.tag!("vcs-root-entry"){
|
178
|
+
xml.tag!("vcs-root", "id" => "#{vcsRootId}")
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
# Setup build configuration step
|
185
|
+
def TeamCityApi.set_build_configuration_build_step buildConfigurationId, inputFile, username, password
|
186
|
+
file = File.open("../spec/#{inputFile}", "r")
|
187
|
+
requestContent = file.read
|
188
|
+
uri = URI.parse "http://localhost:9999/"
|
189
|
+
http = Net::HTTP.new uri.host, uri.port
|
190
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/steps/"
|
191
|
+
request.body = requestContent
|
192
|
+
request.content_type = 'application/xml'
|
193
|
+
request.basic_auth username, password
|
194
|
+
response = http.request request
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
# Setup build feature step
|
199
|
+
def TeamCityApi.set_build_configuration_feature buildConfigurationId, inputFile, username, password
|
200
|
+
file = File.open("../spec/#{inputFile}", "r")
|
201
|
+
requestContent = file.read
|
202
|
+
uri = URI.parse "http://localhost:9999/"
|
203
|
+
http = Net::HTTP.new uri.host, uri.port
|
204
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/features/"
|
205
|
+
request.body = requestContent
|
206
|
+
request.content_type = 'application/xml'
|
207
|
+
request.basic_auth username, password
|
208
|
+
response = http.request request
|
209
|
+
end
|
210
|
+
|
211
|
+
# Setup build trigger step
|
212
|
+
def TeamCityApi.set_build_configuration_trigger buildConfigurationId, inputFile, username, password
|
213
|
+
file = File.open("../spec/#{inputFile}", "r")
|
214
|
+
requestContent = file.read
|
215
|
+
uri = URI.parse "http://localhost:9999/"
|
216
|
+
http = Net::HTTP.new uri.host, uri.port
|
217
|
+
request = Net::HTTP::Post.new "/httpAuth/app/rest/buildTypes/id:#{buildConfigurationId}/triggers/"
|
218
|
+
request.body = requestContent
|
219
|
+
request.content_type = 'application/xml'
|
220
|
+
request.basic_auth username, password
|
221
|
+
response = http.request request
|
222
|
+
end
|
223
|
+
|
26
224
|
end
|
27
225
|
|
226
|
+
|
28
227
|
# Sample Usage
|
29
|
-
#
|
228
|
+
#TeamCityApi.trigger_build("DataPlatform_DataPlatformOntology_ADevelopBuildDataPlatformOntology_2", "username", "password")
|
229
|
+
|
230
|
+
|
231
|
+
#TeamCityApi.get_build_configs_by_projectId "DataPlatform_DataPlatformOntology", "username", "password"
|
232
|
+
#TeamCityApi.get_build_configs_by_projectId_and_build_configurationId "DataPlatform_DataPlatformOntology", "DataPlatform_DataPlatformOntology_ADevelopBuildDataPlatformOntology_2", "username", "password"
|
233
|
+
|
234
|
+
#TeamCityApi.get_project_by_id "DataPlatform_DataPlatformOntology", "username", "password"
|
235
|
+
#TeamCityApi.create_new_project "CreateNewProjectJsonSample", "username", "password"
|
236
|
+
#TeamCityApi.get_vcs_roots_by_id "DataPlatform_DataPlatformOntology_HttpNdhaxpgit01mckessonComCarnegieRelayHealthD", "username", "password"
|
237
|
+
#TeamCityApi.create_new_vcs_root "CreateNewVcsRoot", "username", "password"
|
238
|
+
#TeamCityApi.create_new_build_configuration "DataPlatform_DataPlatformOntology", "CreateNewBuildConfiguration", "username", "username"
|
239
|
+
#TeamCityApi.set_build_configuration_setting "DataPlatform_DataPlatformOntology_DevelopBuild", "checkoutMode", "ON_AGENT", "username", "password"
|
240
|
+
#TeamCityApi.set_build_configuration_parameter "DataPlatform_DataPlatformOntology_DevelopBuild", "env.StorageAccount", "mccadpatsettings", "username", "password"
|
241
|
+
#TeamCityApi.set_build_configuration_vcs_root "DataPlatform_DataPlatformOntology_DevelopBuild", "DataPlatform_DataPlatformOntology_HttpNdhaxpgit01mckessonComPrajwalSainiRelayHea", "username", "password"
|
242
|
+
#TeamCityApi.set_build_configuration_build_step "DataPlatform_DataPlatformOntology_DevelopBuild", "RakeBuildStep", "username", "password"
|
243
|
+
#TeamCityApi.set_build_configuration_feature "DataPlatform_DataPlatformOntology_DevelopBuild", "BuildConfigurationFeature", "username", "password"
|
244
|
+
#TeamCityApi.set_build_configuration_feature "DataPlatform_DataPlatformOntology_DevelopBuild", "BuildConfigurationFeatureForFailureCondition", "username", "password"
|
245
|
+
#TeamCityApi.set_build_configuration_trigger "DataPlatform_DataPlatformOntology_DevelopBuild", "SetupTriggerForBuildStep", "username", "password"
|