|
| 1 | +""" |
| 2 | +Runs the release checklist. |
| 3 | +""" |
| 4 | + |
| 5 | +import html |
| 6 | +import os |
| 7 | +from datetime import datetime |
| 8 | +from string import Template |
| 9 | +import wx |
| 10 | +from src.app_data import AppData |
| 11 | +import tests |
| 12 | +from tests.unit_tests.test_checklist import view_checklist |
| 13 | +from tests.unit_tests.test_checklist.view_checklist import ViewCheckList |
| 14 | + |
| 15 | + |
| 16 | +ITEMS = [ |
| 17 | + {"label": "All issues in GitHub fixed", "type": bool, "pass_if": True, "result": None}, |
| 18 | + {"label": "No Pylint issues", "type": bool, "pass_if": True, "result": None}, |
| 19 | + {"label": "All unit tests passed", "type": bool, "pass_if": True, "result": None}, |
| 20 | + {"label": "All test configuration runs passed", "type": bool, "pass_if": True, "result": None}, |
| 21 | + {"label": "Duration test passed", "type": bool, "pass_if": True, "result": None}, |
| 22 | + {"label": "Correct version in AppData", "type": bool, "pass_if": True, "result": None}, |
| 23 | + {"label": "Documentation up to date", "type": bool, "pass_if": True, "result": None}, |
| 24 | + {"label": "Set tag in git", "type": bool, "pass_if": True, "result": None}, |
| 25 | + {"label": "Create deployment", "type": bool, "pass_if": True, "result": None}, |
| 26 | + {"label": "Publish deployment on LilyTronics", "type": bool, "pass_if": True, "result": None}, |
| 27 | + {"label": "Publish deployment on GitHub", "type": bool, "pass_if": True, "result": None} |
| 28 | +] |
| 29 | +REPORT_TIME_STAMP_FORMAT = "%Y%m%d_%H%M%S" |
| 30 | +REPORT_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" |
| 31 | + |
| 32 | + |
| 33 | +def _get_result_for_item(item, check): |
| 34 | + result = f"unknown type: {item["type"]}" |
| 35 | + if item["type"] is bool: |
| 36 | + if item["pass_if"] == check.GetValue(): |
| 37 | + result = "PASSED" |
| 38 | + else: |
| 39 | + result = "FAILED" |
| 40 | + return result |
| 41 | + |
| 42 | + |
| 43 | +def check_callback(checks, remarks): |
| 44 | + now = datetime.now() |
| 45 | + timestamp = now.strftime(REPORT_TIME_STAMP_FORMAT) |
| 46 | + |
| 47 | + template_values = { |
| 48 | + "start_message": f"Release checklist for application version: V{AppData.VERSION}", |
| 49 | + "date": now.strftime(REPORT_DATE_FORMAT), |
| 50 | + "result": "", |
| 51 | + "result_class": "", |
| 52 | + "result_message": "", |
| 53 | + "checklist_results": "" |
| 54 | + } |
| 55 | + |
| 56 | + results = '<table class="results">\n' |
| 57 | + results += '<tr><th>Test</th><th class="center">Result</th><th>Remarks</th>\n' |
| 58 | + n_passed = 0 |
| 59 | + for i, item in enumerate(ITEMS): |
| 60 | + result = _get_result_for_item(item, checks[i]) |
| 61 | + if result == "PASSED": |
| 62 | + n_passed += 1 |
| 63 | + results += f'<tr class="{result.lower()}">\n' |
| 64 | + results += f"<td>{html.escape(item["label"])}</td>" |
| 65 | + results += f'<td class="center">{html.escape(result)}</td>' |
| 66 | + results += f"<td>{html.escape(remarks[i].GetValue().strip())}</td>" |
| 67 | + results += "</tr>\n" |
| 68 | + results += "</table>" |
| 69 | + |
| 70 | + template_values["result"] = "FAILED" |
| 71 | + if n_passed == len(ITEMS): |
| 72 | + template_values["result"] = "PASSED" |
| 73 | + ratio = 100 * n_passed / len(ITEMS) |
| 74 | + template_values["result_message"] = f"{n_passed} of {len(ITEMS)} passed ({ratio:.1f}%)" |
| 75 | + template_values["checklist_results"] = results |
| 76 | + template_values["result_class"] = template_values["result"].lower() |
| 77 | + |
| 78 | + template_filename = os.path.join(os.path.dirname(view_checklist.__file__), |
| 79 | + "html_report_template.html") |
| 80 | + report_filename = os.path.join(os.path.dirname(tests.__file__), "test_reports", |
| 81 | + f"{timestamp}_release_checklist.html") |
| 82 | + with open(template_filename, "r", encoding="utf-8") as fp: |
| 83 | + template = fp.read() |
| 84 | + with open(report_filename, "w", encoding="utf-8") as fp: |
| 85 | + fp.write(Template(template).substitute(template_values)) |
| 86 | + |
| 87 | + |
| 88 | +def show_checklist(): |
| 89 | + app = wx.App(redirect=False) |
| 90 | + ViewCheckList(ITEMS, AppData.VERSION, check_callback).Show() |
| 91 | + app.MainLoop() |
| 92 | + |
| 93 | + |
| 94 | +if __name__ == "__main__": |
| 95 | + |
| 96 | + import pylint |
| 97 | + |
| 98 | + show_checklist() |
| 99 | + pylint.run_pylint([__file__]) |
0 commit comments