This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TeamCity 7 Builds with dependencies #25732377
- Loading branch information
Dirk Kelly & Matt Parker
committed
Mar 28, 2012
1 parent
a5b673a
commit 0eba94d
Showing
13 changed files
with
951 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
class TeamCityBuild < TeamCityRestProject | ||
|
||
attr_writer :build_status_fetcher, :build_type_fetcher | ||
|
||
def build_id | ||
feed_url.match(/id:([^)]*)/)[1] | ||
end | ||
|
||
def online? | ||
status.online? && children.all?(&:online?) | ||
end | ||
|
||
def success? | ||
green? && children.all?(&:green?) | ||
end | ||
|
||
def red? | ||
!green? || children.any?(&:red?) | ||
end | ||
|
||
def green? | ||
super && children.all?(&:green?) | ||
end | ||
|
||
def building? | ||
build_status.building? || children.any?(&:building?) | ||
end | ||
|
||
def status | ||
latest_status || live_status | ||
end | ||
|
||
def live_status | ||
ProjectStatus.new.tap do |s| | ||
s.online = build_status.online? | ||
s.success = build_status.green? | ||
s.published_at = publish_date | ||
end | ||
end | ||
|
||
def parse_project_status(*) | ||
live_status | ||
end | ||
|
||
def parse_building_status(*) | ||
build_status | ||
end | ||
|
||
def publish_date | ||
date = build_status.publish_date | ||
children.each do |child| | ||
if child.publish_date > date | ||
date = child.publish_date | ||
end | ||
end | ||
date | ||
end | ||
|
||
def children | ||
TeamCityChildBuilder.parse(self, build_type_fetcher.call) | ||
rescue Net::HTTPError | ||
[] | ||
end | ||
|
||
private | ||
|
||
def build_status | ||
@build_status ||= build_status_fetcher.call | ||
end | ||
|
||
def build_status_fetcher | ||
@build_status_fetcher ||= proc { TeamCityBuildStatus.new self } | ||
end | ||
|
||
def build_type_fetcher | ||
@build_type_fetcher ||= proc { | ||
UrlRetriever.retrieve_content_at(build_type_url, auth_username, auth_password) | ||
} | ||
end | ||
|
||
def build_type_url | ||
uri = URI(feed_url) | ||
"#{uri.scheme}://#{uri.host}:#{uri.port}/httpAuth/app/rest/buildTypes/id:#{build_id}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
class TeamCityBuildStatus | ||
attr_reader :build | ||
|
||
def initialize(build) | ||
@build = build | ||
end | ||
|
||
def online? | ||
fetch | ||
@online | ||
end | ||
|
||
def publish_date | ||
if online? | ||
Time.parse build_response['startDate'] | ||
else | ||
nil | ||
end | ||
end | ||
|
||
def green? | ||
online? && @green | ||
end | ||
|
||
def red? | ||
online? && !green? && !building? | ||
end | ||
|
||
def building? | ||
online? && @building | ||
end | ||
|
||
private | ||
def fetch | ||
if build_response | ||
@building = build_response["running"] == "true" | ||
@green = build_response["status"] == "SUCCESS" | ||
@online = true | ||
else | ||
@online = false | ||
end | ||
rescue Net::HTTPError | ||
@online = false | ||
end | ||
|
||
def build_response | ||
@build_response || fetch_build_response | ||
end | ||
|
||
def fetch_build_response | ||
response = UrlRetriever.retrieve_content_at(build.feed_url, build.auth_username, build.auth_password) | ||
response = Hash.from_xml response | ||
|
||
@build_response = response['builds']['build'] | ||
@build_response = @build_response.first if @build_response.kind_of? Array | ||
@build_response | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
class TeamCityChildBuilder | ||
|
||
def self.parse(parent, content) | ||
new(parent, content).build | ||
end | ||
|
||
def initialize(parent, content) | ||
@parent = parent | ||
@content = content | ||
end | ||
|
||
def build | ||
dependencies | ||
end | ||
|
||
private | ||
|
||
def build_project(build_id) | ||
TeamCityBuild.new( | ||
:feed_url => @parent.feed_url.gsub(@parent.build_id, build_id), | ||
:auth_username => @parent.auth_username, | ||
:auth_password => @parent.auth_password | ||
) | ||
end | ||
|
||
def dependencies | ||
parsed_content.xpath("//snapshot-dependency").collect {|d| d.attributes["id"].to_s }.map do |id| | ||
build_project id | ||
end | ||
end | ||
|
||
def parsed_content | ||
@parsed_content ||= Nokogiri::XML(@content) | ||
end | ||
|
||
def base_url | ||
@base_url ||= "#{root_url.scheme}://#{root_url.host}:#{root_url.port}" | ||
end | ||
|
||
def root_url | ||
@root_url ||= URI(parsed_content.xpath("//buildType").first.attributes["webUrl"].to_s) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
require 'spec_helper' | ||
|
||
describe TeamCityChildBuilder do | ||
let(:feed_url) { "http://localhost:8111/app/rest/builds?locator=running:all,buildType:(id:bt2)" } | ||
let(:parent) { TeamCityBuild.new(:feed_url => feed_url, :auth_username => "john", :auth_password => "secret") } | ||
let(:parsed) { TeamCityChildBuilder.parse(parent, content) } | ||
let(:content) do | ||
<<-XML | ||
<buildType id="bt2" webUrl="http://localhost:8111/viewType.html?buildTypeId=bt2"> | ||
<snapshot-dependencies> | ||
<snapshot-dependency id="bt3" type="snapshot_dependency" /> | ||
<snapshot-dependency id="bt5" type="snapshot_dependency" /> | ||
<snapshot-dependency id="bt9" type="snapshot_dependency" /> | ||
</snapshot-dependencies> | ||
</buildType> | ||
XML | ||
end | ||
|
||
it "assigns the correct feed_url to all children builds" do | ||
[3,5,9].each do |i| | ||
parsed.collect(&:feed_url).should( | ||
include("http://localhost:8111/app/rest/builds?locator=running:all,buildType:(id:bt#{i})") | ||
) | ||
end | ||
end | ||
|
||
it "assigns the correct auth_username to all children builds" do | ||
[3,5,9].each do |i| | ||
parsed.collect(&:auth_username).should( | ||
include("john") | ||
) | ||
end | ||
end | ||
|
||
it "assigns the correct auth_username to all children builds" do | ||
[3,5,9].each do |i| | ||
parsed.collect(&:auth_password).should( | ||
include("secret") | ||
) | ||
end | ||
end | ||
end |
Oops, something went wrong.