Skip to content

Continuous Integration Features #1040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 21, 2015
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
python:
---
python:
- "2.7"
script: "python workspace_tools/build_travis.py"
install:
- "sudo $TRAVIS_BUILD_DIR/travis/install_dependencies.sh > /dev/null"
- sudo pip install colorama
- sudo pip install prettytable
- sudo pip install prettytable
- sudo pip install jinja2
19 changes: 19 additions & 0 deletions workspace_tools/build_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from workspace_tools.targets import TARGET_NAMES, TARGET_MAP
from workspace_tools.libraries import Library
from workspace_tools.toolchains import TOOLCHAIN_CLASSES
from jinja2 import FileSystemLoader
from jinja2.environment import Environment


def build_project(src_path, build_path, target, toolchain_name,
Expand Down Expand Up @@ -529,3 +531,20 @@ def print_build_results(result_list, build_name):
result += "\n".join([" * %s" % f for f in result_list])
result += "\n"
return result

def write_build_report(build_report, template_filename, filename):
build_report_failing = []
build_report_passing = []

for report in build_report:
if len(report["failing"]) > 0:
build_report_failing.append(report)
else:
build_report_passing.append(report)

env = Environment(extensions=['jinja2.ext.with_'])
env.loader = FileSystemLoader('ci_templates')
template = env.get_template(template_filename)

with open(filename, 'w+') as f:
f.write(template.render(failing_builds=build_report_failing, passing_builds=build_report_passing))
41 changes: 39 additions & 2 deletions workspace_tools/build_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
sys.path.insert(0, ROOT)

from workspace_tools.build_api import build_mbed_libs
from workspace_tools.build_api import write_build_report
from workspace_tools.targets import TARGET_MAP

OFFICIAL_MBED_LIBRARY_BUILD = (
Expand Down Expand Up @@ -98,31 +99,67 @@
default=1, help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
default=False, help="Verbose diagnostic output")
parser.add_option("-t", "--toolchains", dest="toolchains", help="Use toolchains names separated by comma")

parser.add_option("", "--report-build", dest="report_build_file_name", help="Output the build results to an html file")


options, args = parser.parse_args()
start = time()
failures = []
successes = []
skips = []
build_report = []
for target_name, toolchain_list in OFFICIAL_MBED_LIBRARY_BUILD:
if options.official_only:
toolchains = (getattr(TARGET_MAP[target_name], 'default_toolchain', 'ARM'),)
else:
toolchains = toolchain_list

if options.toolchains:
print "Only building using the following toolchains: %s" % (options.toolchains)
toolchainSet = set(toolchains)
toolchains = toolchainSet and set((options.toolchains).split(','))


cur_target_build_report = { "target": target_name, "passing": [], "failing": [], "skipped": []}

for toolchain in toolchains:
id = "%s::%s" % (target_name, toolchain)
try:
build_mbed_libs(TARGET_MAP[target_name], toolchain, verbose=options.verbose, jobs=options.jobs)
successes.append(id)
built_mbed_lib = build_mbed_libs(TARGET_MAP[target_name], toolchain, verbose=options.verbose, jobs=options.jobs)

if built_mbed_lib:
successes.append(id)
cur_target_build_report["passing"].append({ "toolchain": toolchain })
else:
skips.append(id)
cur_target_build_report["skipped"].append({ "toolchain": toolchain })


except Exception, e:
failures.append(id)
cur_target_build_report["failing"].append({ "toolchain": toolchain })
print e

if len(toolchains) > 0:
build_report.append(cur_target_build_report)

# Write summary of the builds

if options.report_build_file_name:
write_build_report(build_report, 'library_build/report.html', options.report_build_file_name)

print "\n\nCompleted in: (%.2f)s" % (time() - start)

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

if skips:
print "\n\nBuild skips:"
print "\n".join([" * %s" % s for s in skips])

if failures:
print "\n\nBuild failures:"
print "\n".join([" * %s" % f for f in failures])
Expand Down
31 changes: 31 additions & 0 deletions workspace_tools/ci_templates/library_build/build_report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="toggleshow{% if report.failing|length == 0 %} toggleshow-hide{% endif %}">
<h3>
<a href="#" class="toggleshow-title">
<span class="toggleshow-arrow"></span>
{% if report.failing|length > 0 %}
<span class="redbold">[FAIL]</span>
{% else %}
<span class="greenbold">[PASS]</span>
{% endif %}

{{report.target}} - Passing: {{report.passing|length}}, Failing: {{report.failing|length}}, Skipped: {{report.skipped|length}}
</a>
</h3>

<div class="toggleshow-body">
<h4 class="redbold">Failing</h4>
{% with build = report.failing %}
{% include 'library_build/build_report_table.html' %}
{% endwith %}

<h4 class="greenbold">Passing</h4>
{% with build = report.passing %}
{% include 'library_build/build_report_table.html' %}
{% endwith %}

<h4>Skipped</h4>
{% with build = report.skipped %}
{% include 'library_build/build_report_table.html' %}
{% endwith %}
</div>
</div>
10 changes: 10 additions & 0 deletions workspace_tools/ci_templates/library_build/build_report_table.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<table class="sortable pane bigtable stripped-odd">
<tr>
<th>Toolchain</th>
</tr>
{% for run in build %}
<tr>
<td>{{run.toolchain}}</td>
</tr>
{% endfor %}
</table>
11 changes: 11 additions & 0 deletions workspace_tools/ci_templates/library_build/report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<h2>{{failing_builds|length}} Failing Builds</h2>
{% for report in failing_builds %}
{% include 'library_build/build_report.html' %}
{% endfor %}

<h2>{{passing_builds|length}} Passing Builds</h2>
{% for report in passing_builds %}
{% include 'library_build/build_report.html' %}
{% endfor %}

{% include 'scripts.js' %}
53 changes: 53 additions & 0 deletions workspace_tools/ci_templates/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script>
var elements = document.querySelectorAll(".toggleshow"),
hideClass = 'toggleshow-hide';

for (var i = 0; i < elements.length; i++) {
var arrow = elements[i].querySelector(".toggleshow-arrow");
// Initial hide/show based on class
// Update arrow as well
if (containsClass(elements[i], 'toggleshow-hide')) {
toggleDisplay(elements[i]);
changeArrow(arrow, false);
} else {
changeArrow(arrow, true);
}

// Add click handler
addClick(elements[i], toggleDisplay);
}

function containsClass(element, className) {
var eleClassName = ' ' + elements[i].className + ' ';
return eleClassName.indexOf(' ' + className + ' ') > -1;
}

function toggleDisplay(parentElement) {
var body = parentElement.querySelector(".toggleshow-body"),
arrow = parentElement.querySelector(".toggleshow-arrow");

if (body.style.display == 'block' || body.style.display == '') {
body.style.display = 'none';
changeArrow(arrow, false);
} else {
body.style.display = 'block';
changeArrow(arrow, true);
}
}

function changeArrow(element, visible) {
if (visible) {
element.innerHTML = '&#9650';
} else {
element.innerHTML = '&#9660';
}
}

function addClick(parentElement, func) {
parentElement.querySelector(".toggleshow-title").addEventListener("click", function(e) {
func(parentElement);
e.preventDefault();
return false;
});
}
</script>
31 changes: 31 additions & 0 deletions workspace_tools/ci_templates/tests_build/build_report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="toggleshow{% if report.failing|length == 0 %} toggleshow-hide{% endif %}">
<h3>
<a href="#" class="toggleshow-title">
<span class="toggleshow-arrow"></span>
{% if report.failing|length > 0 %}
<span class="redbold">[FAIL]</span>
{% else %}
<span class="greenbold">[PASS]</span>
{% endif %}

{{report.target}} - Passing: {{report.passing|length}}, Failing: {{report.failing|length}}, Skipped: {{report.skipped|length}}
</a>
</h3>

<div class="toggleshow-body">
<h4 class="redbold">Failing</h4>
{% with build = report.failing %}
{% include 'tests_build/build_report_table.html' %}
{% endwith %}

<h4 class="greenbold">Passing</h4>
{% with build = report.passing %}
{% include 'tests_build/build_report_table.html' %}
{% endwith %}

<h4>Skipped</h4>
{% with build = report.skipped %}
{% include 'tests_build/build_report_table.html' %}
{% endwith %}
</div>
</div>
12 changes: 12 additions & 0 deletions workspace_tools/ci_templates/tests_build/build_report_table.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<table class="sortable pane bigtable stripped-odd">
<tr>
<th>Toolchain</th>
<th>Project</th>
</tr>
{% for run in build %}
<tr>
<td>{{run.toolchain}}</td>
<td>{{run.project}}</td>
</tr>
{% endfor %}
</table>
11 changes: 11 additions & 0 deletions workspace_tools/ci_templates/tests_build/report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<h2>{{failing_builds|length}} Failing Builds</h2>
{% for report in failing_builds %}
{% include 'tests_build/build_report.html' %}
{% endfor %}

<h2>{{passing_builds|length}} Passing Builds</h2>
{% for report in passing_builds %}
{% include 'tests_build/build_report.html' %}
{% endfor %}

{% include 'scripts.js' %}
1 change: 1 addition & 0 deletions workspace_tools/singletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def get_version():
_opts_log_file_name=opts.log_file_name,
_opts_report_html_file_name=opts.report_html_file_name,
_opts_report_junit_file_name=opts.report_junit_file_name,
_opts_report_build_file_name=opts.report_build_file_name,
_test_spec=test_spec,
_opts_goanna_for_mbed_sdk=opts.goanna_for_mbed_sdk,
_opts_goanna_for_tests=opts.goanna_for_tests,
Expand Down
Loading