Skip to content

Commit 289b806

Browse files
committed
Merge pull request #1040 from bridadan/ci
Continuous Integration Features
2 parents fe39f1a + 2f4d668 commit 289b806

File tree

12 files changed

+464
-138
lines changed

12 files changed

+464
-138
lines changed

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
---
2-
python:
1+
---
2+
python:
33
- "2.7"
44
script: "python workspace_tools/build_travis.py"
55
install:
66
- "sudo $TRAVIS_BUILD_DIR/travis/install_dependencies.sh > /dev/null"
77
- sudo pip install colorama
8-
- sudo pip install prettytable
8+
- sudo pip install prettytable
9+
- sudo pip install jinja2

workspace_tools/build_api.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
from workspace_tools.targets import TARGET_NAMES, TARGET_MAP
3030
from workspace_tools.libraries import Library
3131
from workspace_tools.toolchains import TOOLCHAIN_CLASSES
32+
from jinja2 import FileSystemLoader
33+
from jinja2.environment import Environment
3234

3335

3436
def build_project(src_path, build_path, target, toolchain_name,
@@ -529,3 +531,20 @@ def print_build_results(result_list, build_name):
529531
result += "\n".join([" * %s" % f for f in result_list])
530532
result += "\n"
531533
return result
534+
535+
def write_build_report(build_report, template_filename, filename):
536+
build_report_failing = []
537+
build_report_passing = []
538+
539+
for report in build_report:
540+
if len(report["failing"]) > 0:
541+
build_report_failing.append(report)
542+
else:
543+
build_report_passing.append(report)
544+
545+
env = Environment(extensions=['jinja2.ext.with_'])
546+
env.loader = FileSystemLoader('ci_templates')
547+
template = env.get_template(template_filename)
548+
549+
with open(filename, 'w+') as f:
550+
f.write(template.render(failing_builds=build_report_failing, passing_builds=build_report_passing))

workspace_tools/build_release.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
sys.path.insert(0, ROOT)
2525

2626
from workspace_tools.build_api import build_mbed_libs
27+
from workspace_tools.build_api import write_build_report
2728
from workspace_tools.targets import TARGET_MAP
2829

2930
OFFICIAL_MBED_LIBRARY_BUILD = (
@@ -98,31 +99,67 @@
9899
default=1, help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
99100
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
100101
default=False, help="Verbose diagnostic output")
102+
parser.add_option("-t", "--toolchains", dest="toolchains", help="Use toolchains names separated by comma")
103+
104+
parser.add_option("", "--report-build", dest="report_build_file_name", help="Output the build results to an html file")
105+
106+
101107
options, args = parser.parse_args()
102108
start = time()
103109
failures = []
104110
successes = []
111+
skips = []
112+
build_report = []
105113
for target_name, toolchain_list in OFFICIAL_MBED_LIBRARY_BUILD:
106114
if options.official_only:
107115
toolchains = (getattr(TARGET_MAP[target_name], 'default_toolchain', 'ARM'),)
108116
else:
109117
toolchains = toolchain_list
118+
119+
if options.toolchains:
120+
print "Only building using the following toolchains: %s" % (options.toolchains)
121+
toolchainSet = set(toolchains)
122+
toolchains = toolchainSet and set((options.toolchains).split(','))
123+
124+
125+
cur_target_build_report = { "target": target_name, "passing": [], "failing": [], "skipped": []}
126+
110127
for toolchain in toolchains:
111128
id = "%s::%s" % (target_name, toolchain)
112129
try:
113-
build_mbed_libs(TARGET_MAP[target_name], toolchain, verbose=options.verbose, jobs=options.jobs)
114-
successes.append(id)
130+
built_mbed_lib = build_mbed_libs(TARGET_MAP[target_name], toolchain, verbose=options.verbose, jobs=options.jobs)
131+
132+
if built_mbed_lib:
133+
successes.append(id)
134+
cur_target_build_report["passing"].append({ "toolchain": toolchain })
135+
else:
136+
skips.append(id)
137+
cur_target_build_report["skipped"].append({ "toolchain": toolchain })
138+
139+
115140
except Exception, e:
116141
failures.append(id)
142+
cur_target_build_report["failing"].append({ "toolchain": toolchain })
117143
print e
118144

145+
if len(toolchains) > 0:
146+
build_report.append(cur_target_build_report)
147+
119148
# Write summary of the builds
149+
150+
if options.report_build_file_name:
151+
write_build_report(build_report, 'library_build/report.html', options.report_build_file_name)
152+
120153
print "\n\nCompleted in: (%.2f)s" % (time() - start)
121154

122155
if successes:
123156
print "\n\nBuild successes:"
124157
print "\n".join([" * %s" % s for s in successes])
125158

159+
if skips:
160+
print "\n\nBuild skips:"
161+
print "\n".join([" * %s" % s for s in skips])
162+
126163
if failures:
127164
print "\n\nBuild failures:"
128165
print "\n".join([" * %s" % f for f in failures])
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<div class="toggleshow{% if report.failing|length == 0 %} toggleshow-hide{% endif %}">
2+
<h3>
3+
<a href="#" class="toggleshow-title">
4+
<span class="toggleshow-arrow"></span>
5+
{% if report.failing|length > 0 %}
6+
<span class="redbold">[FAIL]</span>
7+
{% else %}
8+
<span class="greenbold">[PASS]</span>
9+
{% endif %}
10+
11+
{{report.target}} - Passing: {{report.passing|length}}, Failing: {{report.failing|length}}, Skipped: {{report.skipped|length}}
12+
</a>
13+
</h3>
14+
15+
<div class="toggleshow-body">
16+
<h4 class="redbold">Failing</h4>
17+
{% with build = report.failing %}
18+
{% include 'library_build/build_report_table.html' %}
19+
{% endwith %}
20+
21+
<h4 class="greenbold">Passing</h4>
22+
{% with build = report.passing %}
23+
{% include 'library_build/build_report_table.html' %}
24+
{% endwith %}
25+
26+
<h4>Skipped</h4>
27+
{% with build = report.skipped %}
28+
{% include 'library_build/build_report_table.html' %}
29+
{% endwith %}
30+
</div>
31+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<table class="sortable pane bigtable stripped-odd">
2+
<tr>
3+
<th>Toolchain</th>
4+
</tr>
5+
{% for run in build %}
6+
<tr>
7+
<td>{{run.toolchain}}</td>
8+
</tr>
9+
{% endfor %}
10+
</table>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<h2>{{failing_builds|length}} Failing Builds</h2>
2+
{% for report in failing_builds %}
3+
{% include 'library_build/build_report.html' %}
4+
{% endfor %}
5+
6+
<h2>{{passing_builds|length}} Passing Builds</h2>
7+
{% for report in passing_builds %}
8+
{% include 'library_build/build_report.html' %}
9+
{% endfor %}
10+
11+
{% include 'scripts.js' %}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script>
2+
var elements = document.querySelectorAll(".toggleshow"),
3+
hideClass = 'toggleshow-hide';
4+
5+
for (var i = 0; i < elements.length; i++) {
6+
var arrow = elements[i].querySelector(".toggleshow-arrow");
7+
// Initial hide/show based on class
8+
// Update arrow as well
9+
if (containsClass(elements[i], 'toggleshow-hide')) {
10+
toggleDisplay(elements[i]);
11+
changeArrow(arrow, false);
12+
} else {
13+
changeArrow(arrow, true);
14+
}
15+
16+
// Add click handler
17+
addClick(elements[i], toggleDisplay);
18+
}
19+
20+
function containsClass(element, className) {
21+
var eleClassName = ' ' + elements[i].className + ' ';
22+
return eleClassName.indexOf(' ' + className + ' ') > -1;
23+
}
24+
25+
function toggleDisplay(parentElement) {
26+
var body = parentElement.querySelector(".toggleshow-body"),
27+
arrow = parentElement.querySelector(".toggleshow-arrow");
28+
29+
if (body.style.display == 'block' || body.style.display == '') {
30+
body.style.display = 'none';
31+
changeArrow(arrow, false);
32+
} else {
33+
body.style.display = 'block';
34+
changeArrow(arrow, true);
35+
}
36+
}
37+
38+
function changeArrow(element, visible) {
39+
if (visible) {
40+
element.innerHTML = '&#9650';
41+
} else {
42+
element.innerHTML = '&#9660';
43+
}
44+
}
45+
46+
function addClick(parentElement, func) {
47+
parentElement.querySelector(".toggleshow-title").addEventListener("click", function(e) {
48+
func(parentElement);
49+
e.preventDefault();
50+
return false;
51+
});
52+
}
53+
</script>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<div class="toggleshow{% if report.failing|length == 0 %} toggleshow-hide{% endif %}">
2+
<h3>
3+
<a href="#" class="toggleshow-title">
4+
<span class="toggleshow-arrow"></span>
5+
{% if report.failing|length > 0 %}
6+
<span class="redbold">[FAIL]</span>
7+
{% else %}
8+
<span class="greenbold">[PASS]</span>
9+
{% endif %}
10+
11+
{{report.target}} - Passing: {{report.passing|length}}, Failing: {{report.failing|length}}, Skipped: {{report.skipped|length}}
12+
</a>
13+
</h3>
14+
15+
<div class="toggleshow-body">
16+
<h4 class="redbold">Failing</h4>
17+
{% with build = report.failing %}
18+
{% include 'tests_build/build_report_table.html' %}
19+
{% endwith %}
20+
21+
<h4 class="greenbold">Passing</h4>
22+
{% with build = report.passing %}
23+
{% include 'tests_build/build_report_table.html' %}
24+
{% endwith %}
25+
26+
<h4>Skipped</h4>
27+
{% with build = report.skipped %}
28+
{% include 'tests_build/build_report_table.html' %}
29+
{% endwith %}
30+
</div>
31+
</div>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<table class="sortable pane bigtable stripped-odd">
2+
<tr>
3+
<th>Toolchain</th>
4+
<th>Project</th>
5+
</tr>
6+
{% for run in build %}
7+
<tr>
8+
<td>{{run.toolchain}}</td>
9+
<td>{{run.project}}</td>
10+
</tr>
11+
{% endfor %}
12+
</table>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<h2>{{failing_builds|length}} Failing Builds</h2>
2+
{% for report in failing_builds %}
3+
{% include 'tests_build/build_report.html' %}
4+
{% endfor %}
5+
6+
<h2>{{passing_builds|length}} Passing Builds</h2>
7+
{% for report in passing_builds %}
8+
{% include 'tests_build/build_report.html' %}
9+
{% endfor %}
10+
11+
{% include 'scripts.js' %}

workspace_tools/singletest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ def get_version():
209209
_opts_log_file_name=opts.log_file_name,
210210
_opts_report_html_file_name=opts.report_html_file_name,
211211
_opts_report_junit_file_name=opts.report_junit_file_name,
212+
_opts_report_build_file_name=opts.report_build_file_name,
212213
_test_spec=test_spec,
213214
_opts_goanna_for_mbed_sdk=opts.goanna_for_mbed_sdk,
214215
_opts_goanna_for_tests=opts.goanna_for_tests,

0 commit comments

Comments
 (0)