Skip to content

Commit

Permalink
Merge pull request #16 from xebialabs-community/projectSummaryTile
Browse files Browse the repository at this point in the history
Project summary tile
  • Loading branch information
jdewinne authored Apr 10, 2019
2 parents 86918dc + 354eef2 commit 9b99251
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 5 deletions.
27 changes: 27 additions & 0 deletions src/main/resources/synthetic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,31 @@

</type>

<type type="teamcity.ProjectStatusTile" label="TeamCity Project Status" extends="xlrelease.Tile" description="Display the status for a project.">
<property name="scriptLocation" default="teamcity/BuildConfigurationsStatusTile.py" hidden="true" />

<!-- Path to the HTML template of the dashboard view of the tile -->
<property name="uri" hidden="true" default="teamcity/ProjectStatusTile/project-status-tile-summary-view.html" />
<property name="detailsUri" hidden="true" default="teamcity/BuildConfigurationsStatusTile/build-configurations-status-tile-summary-view.html" />
<!-- Title of the tile, this property is predefined in the parent type, but here you override its default value -->
<property name="title" description="Display name of the tile" default="Project Status"/>

<property name="supportedScopes" kind="list_of_string" default="global,folder,release" hidden="true"/>
<property name="expirationTime" kind="integer" hidden="true" default="10" description="Expiration time for a tile cache (in seconds)."/>

<!-- Tile configuration properties -->
<property category="input" name="teamcityServer" referenced-type="teamcity.Server" kind="ci" label="Server" description="TeamCity server id to connect to."/>
<property category="input" name="username" required="false" description="Overrides the username used to connect to the server."/>
<property category="input" name="password" password="true" required="false" description="Overrides the password used to connect to the server."/>
<property category="input" name="project" required="true" default="" description="Project id to fetch all the build configurations from."/>
<property category="input" name="filter" required="true" kind="enum" description="Specify which statuses to see in details (Success|Failed|All).">
<enum-values>
<value>Failed</value>
<value>Success</value>
<value>All</value>
</enum-values>
</property>

</type>

</synthetic>
22 changes: 18 additions & 4 deletions src/main/resources/teamcity/BuildConfigurationsStatusTile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

import logging

from dateutil.parser import parse
from org.slf4j import LoggerFactory
from teamcity import TeamCityClient

logger = logging.getLogger("TeamCity")
logger = LoggerFactory.getLogger("com.xebialabs")
logger.info("Executing BuildConfigurationsStatusTile")
data = {}
status_count = []
status_options = []
status_colors = {'SUCCESS':'green','UNKNOWN':'orange','FAILURE':'red','No Info':'gray'}

def increment_status_count(status):
if status not in status_options:
status_options.append(status)
if not any(d['name'] == status for d in status_count):
status_count.append({'name':status,'value':0, 'itemStyle':{'color':status_colors[status] if status in status_colors else 'red'}})
d = next(d for i,d in enumerate(status_count) if d['name'] == status)
d['value'] += 1
logger.info("status_count [%s]" % status_count)

if teamcityServer:
teamcity_client = TeamCityClient(
teamcityServer, username=None, password=None, logger=logger)
Expand Down Expand Up @@ -43,6 +55,7 @@
"statusText": "No builds to display", "problemOccurrences": {},
"testOccurrences": {}, "finishDate": "N/A",
"statusUrl": "%s/app/rest/builds/buildType:(id:%s)/statusIcon" % (teamcityServer["url"], build_configuration['id'])})
increment_status_count("No Info")
else:
build_problem_occurrences = teamcity_client.get_build_problem_occurrences(
build_configuration['builds']['build'][0]['id'])
Expand All @@ -67,4 +80,5 @@
"buildLog": processed_build_log,
"statusUrl": "%s/app/rest/builds/buildType:(id:%s)/statusIcon" % (teamcityServer["url"], build_configuration['id']),
"buildLogUrl": "%s/downloadBuildLog.html?buildId=%s" % (teamcityServer["url"], build_configuration['builds']['build'][0]['id'])})
data = {"projectStatuses": project_statuses}
increment_status_count(build_configuration['builds']['build'][0]['status'])
data = {"projectStatuses": project_statuses, "statusCount": status_count, "statusOptions": status_options}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@



})
});

</script>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!--
Copyright 2019 XEBIALABS
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- including ECharts file -->
<script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
</head>

<body>
<!-- prepare a DOM container with width and height -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
window.addEventListener("xlrelease.load", function () {
window.xlrelease.queryTileData(function (response) {
var statusCount = response.data.data.statusCount;
var statusOptions = response.data.data.statusOptions;
// based on prepared DOM, initialize echarts instance
var myChart = echarts.init(document.getElementById('main'));

// specify chart configuration item and data
var option = {
title: {
text: 'TeamCity Project Overview',
x: 'center'
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'horizontal',
bottom: 'bottom',
data: statusOptions
},
series: [
{
name: 'Statuses',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: statusCount,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};

// use configuration item and data specified to show chart
myChart.setOption(option);
});
});
</script>
</body>

</html>

0 comments on commit 9b99251

Please sign in to comment.