mirror of
https://github.com/linuxserver/docker-ci.git
synced 2026-01-21 12:21:34 +08:00
702 lines
17 KiB
HTML
702 lines
17 KiB
HTML
<!doctype html>
|
||
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>CI Results {{ image }}:{{ meta_tag }}</title>
|
||
<meta name="description" content="CI: {{ 'PASS ✅' if report_status=='PASS' else 'FAIL ❌' }}">
|
||
<meta name="author" content="linuxserver.io">
|
||
|
||
<meta name="theme-color" content="#da3b8a">
|
||
<!-- Google / Search Engine Tags -->
|
||
<meta itemprop="name" content="CI Results for {{ image }}:{{ meta_tag }}">
|
||
<meta itemprop="description" content="CI: {{ 'PASS ✅' if report_status=='PASS' else 'FAIL ❌' }}">
|
||
<meta itemprop="image" content="https://{{ bucket }}/{{ image }}/{{ meta_tag }}/logo.jpg">
|
||
<!-- Open Graph / Facebook -->
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:site_name" content="{{ bucket }}">
|
||
<meta property="og:url" content="https://{{ bucket }}/">
|
||
<meta property="og:title" content="CI Results for {{ image }}:{{ meta_tag }}">
|
||
<meta property="og:description" content="CI: {{ 'PASS ✅' if report_status=='PASS' else 'FAIL ❌' }}">
|
||
<meta property="og:image" content="https://{{ bucket }}/{{ image }}/{{ meta_tag }}/logo.jpg">
|
||
<!-- Twitter -->
|
||
<meta property="twitter:card" content="summary_large_image">
|
||
<meta property="twitter:url" content="https://{{ bucket }}/">
|
||
<meta property="twitter:title" content="CI Results for {{ image }}:{{ meta_tag }}">
|
||
<meta property="twitter:description" content="CI: {{ 'PASS ✅' if report_status=='PASS' else 'FAIL ❌' }}">
|
||
<meta property="twitter:image" content="https://{{ bucket }}/{{ image }}/{{ meta_tag }}/logo.jpg">
|
||
<!-- Favicon-->
|
||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet">
|
||
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"
|
||
integrity="sha384-rOA1PnstxnOBLzCLMcre8ybwbTmemjzdNlILg8O7z1lUkLXozs4DHonlDtnE7fpc"
|
||
crossorigin="anonymous"></script>
|
||
<style>
|
||
@media (prefers-color-scheme: dark) {
|
||
body {
|
||
background: linear-gradient(to right, rgba(34, 34, 34, 1), rgba(34, 34, 34, 1));
|
||
color: #96a2b4;
|
||
}
|
||
|
||
h1 {
|
||
color: #dce2ec;
|
||
}
|
||
|
||
h1 span {
|
||
color: rgba(218, 59, 138);
|
||
}
|
||
|
||
a {
|
||
color: rgba(218, 59, 138);
|
||
}
|
||
|
||
a:hover {
|
||
color: rgb(188, 52, 120);
|
||
}
|
||
|
||
section {
|
||
background: rgba(44, 44, 44);
|
||
border: solid 1px rgb(255 255 255 / 10%);
|
||
}
|
||
|
||
.section-header {
|
||
background: rgba(44, 44, 44);
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1)
|
||
}
|
||
|
||
.section-header-h2 {
|
||
color: #96a2b4;
|
||
}
|
||
|
||
section h3 {
|
||
color: rgba(218, 59, 138);
|
||
}
|
||
|
||
.summary {
|
||
color: rgba(218, 59, 138);
|
||
}
|
||
|
||
.summary:hover {
|
||
color: rgb(188, 52, 120);
|
||
}
|
||
|
||
.styled-table {
|
||
border: solid 1px rgb(255 255 255 / 10%);
|
||
}
|
||
|
||
.styled-table thead tr {
|
||
background-color: #1f1f1f;
|
||
}
|
||
|
||
.styled-table tbody tr {
|
||
border-bottom: 1px solid rgba(221, 221, 221, 0.1);
|
||
}
|
||
|
||
.styled-table tbody tr:nth-of-type(even) {
|
||
background-color: rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.summary-container {
|
||
background: #1f1f1f;
|
||
}
|
||
|
||
summary:hover {
|
||
color: #dce2ec;
|
||
}
|
||
|
||
pre {
|
||
background: #1f1f1f;
|
||
}
|
||
|
||
.build {
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||
background: rgba(0, 0, 0, 0.25);
|
||
}
|
||
|
||
.build-header {
|
||
color:rgba(218, 59, 138);
|
||
}
|
||
|
||
.runtime {
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
background: rgba(0, 0, 0, 0.25);
|
||
}
|
||
|
||
strong {
|
||
color: rgba(218, 59, 138);
|
||
}
|
||
.warning-note {
|
||
color: #96a2b4;
|
||
}
|
||
|
||
.log-debug {color:lightgray}
|
||
.log-info {color:lightskyblue}
|
||
.log-warning {color:darkorange}
|
||
.log-error {color:red;font-weight: bolder;}
|
||
.log-success{color:limegreen;font-weight: bolder;}
|
||
}
|
||
|
||
@media (prefers-color-scheme: light) {
|
||
body {
|
||
background: #e8e8e8;
|
||
color: #738694;
|
||
}
|
||
|
||
.warning-note {
|
||
color: #738694;
|
||
}
|
||
|
||
h1 {
|
||
color: #738694;
|
||
}
|
||
|
||
h1 span {
|
||
color: #9bb0bf;
|
||
}
|
||
|
||
a {
|
||
color: #738694;
|
||
}
|
||
|
||
a:hover {
|
||
color: #9bb0bf;
|
||
}
|
||
|
||
section {
|
||
background: #efefef;
|
||
border: solid 1px rgb(0 0 0 / 15%);
|
||
}
|
||
|
||
.section-header {
|
||
background: #738694;
|
||
}
|
||
|
||
.section-header-h2 {
|
||
color: #FFFFFF;
|
||
}
|
||
|
||
.styled-table thead tr {
|
||
background-color: #738694;
|
||
}
|
||
|
||
.styled-table tbody tr {
|
||
border-bottom: 1px solid #dddddd;
|
||
}
|
||
|
||
.styled-table tbody tr:nth-of-type(even) {
|
||
background-color: #f3f3f3;
|
||
}
|
||
|
||
.section-header-status .report-status-pass {
|
||
color: #00c29a;
|
||
}
|
||
.summary-container {
|
||
background: #e8e8e8;
|
||
}
|
||
|
||
summary:hover {
|
||
color: #4b5d6a;
|
||
}
|
||
|
||
pre {
|
||
background: #e8e8e8;
|
||
}
|
||
|
||
.build {
|
||
border-bottom: 1px solid #dcdcdc;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.runtime {
|
||
border-bottom: 1px solid #dcdcdc;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.build-header {
|
||
color:#738694;
|
||
}
|
||
|
||
.log-debug {color:#9bb0bf}
|
||
.log-info {color:#60707c}
|
||
.log-warning {color:darkorange}
|
||
.log-error {color:red;font-weight: bolder;}
|
||
.log-success{color:#009879;font-weight: bolder;}
|
||
}
|
||
|
||
body,
|
||
html {
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Lato', sans-serif;
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
}
|
||
|
||
body * {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
#logohttpsrawgithubusercontentcomlinuxserverdockertemplatesmasterlinuxserverioimglinuxserver_mediumpng {
|
||
display: none;
|
||
}
|
||
|
||
a {
|
||
text-decoration: none;
|
||
}
|
||
|
||
a[target="_blank"]::after {
|
||
content: " \2197";
|
||
font-size: 80%;
|
||
margin-left: 4px;
|
||
vertical-align: middle;
|
||
}
|
||
|
||
#app {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 15px;
|
||
}
|
||
|
||
#results {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
width: 100%;
|
||
}
|
||
|
||
h1 {
|
||
font-size: 30px;
|
||
letter-spacing: 3px;
|
||
text-transform: uppercase;
|
||
font-weight: 400;
|
||
}
|
||
|
||
#results h1 {
|
||
font-size: 18px;
|
||
margin: 0 10px 25px;
|
||
word-break: break-all;
|
||
}
|
||
|
||
#results table {
|
||
margin: auto;
|
||
width: 100%;
|
||
}
|
||
|
||
.styled-table th,
|
||
.styled-table td {
|
||
word-wrap: break-word;
|
||
}
|
||
|
||
table {
|
||
table-layout: fixed;
|
||
}
|
||
|
||
th {
|
||
text-align: left
|
||
}
|
||
|
||
section {
|
||
display: flex;
|
||
width: 100%;
|
||
flex-direction: column;
|
||
margin: 10px;
|
||
min-width: 320px;
|
||
max-width: 50vw;
|
||
padding: 0 0 30px 0;
|
||
flex: 1 1 0;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
section>* {
|
||
padding: 0 30px;
|
||
}
|
||
|
||
.section-header {
|
||
border-radius: 10px 10px 0 0;
|
||
overflow-wrap: break-word;
|
||
}
|
||
|
||
.section-header-h2 {
|
||
font-size: 17px;
|
||
padding: 15px 30px;
|
||
margin: 0;
|
||
text-align: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.section-header-status {
|
||
font-size: 17px;
|
||
padding-top: .5rem;
|
||
margin: 0;
|
||
text-align: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
em {
|
||
color: #32a7c1;
|
||
}
|
||
|
||
/* No image */
|
||
section h2+h3 {
|
||
border-bottom: 1px solid #dcdcdc;
|
||
padding-bottom: 20px;
|
||
background: #f5f5f5;
|
||
margin: 0;
|
||
font-size: 12px;
|
||
word-break: break-all;
|
||
}
|
||
|
||
/* Has an image */
|
||
section h2+p+h3 {
|
||
border-bottom: 1px solid #dcdcdc;
|
||
padding: 20px 30px;
|
||
background: #f5f5f5;
|
||
margin: 0;
|
||
font-size: 12px;
|
||
word-break: break-all;
|
||
}
|
||
|
||
section h2+p {
|
||
margin: 0;
|
||
}
|
||
|
||
section p:empty {
|
||
display: none;
|
||
}
|
||
|
||
section h3 {
|
||
font-size: 16px;
|
||
padding: 0 30px;
|
||
}
|
||
|
||
.summary {
|
||
font-weight: bold;
|
||
margin-block-start: 1em;
|
||
margin-inline-start: 0px;
|
||
margin-inline-end: 0px;
|
||
}
|
||
|
||
section img {
|
||
width: calc(100% + 60px);
|
||
height: auto;
|
||
margin-left: -30px;
|
||
margin-right: -30px;
|
||
padding: 0;
|
||
display: block;
|
||
}
|
||
|
||
.debug-section {
|
||
max-width: 100%;
|
||
}
|
||
|
||
main {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: stretch;
|
||
flex-wrap: wrap;
|
||
max-width: 100%;
|
||
}
|
||
|
||
@media only screen and (min-width: 500px) {
|
||
h1 {
|
||
font-size: 50px;
|
||
letter-spacing: 5px;
|
||
|
||
}
|
||
|
||
#results h1 {
|
||
font-size: 25px;
|
||
}
|
||
}
|
||
@media only screen and (max-width: 500px) {
|
||
/*Mobile*/
|
||
section h3,
|
||
section details,
|
||
.warning-notice,
|
||
.table-container {
|
||
padding: 0 5px;
|
||
}
|
||
|
||
.table-container {
|
||
padding-top: 10px;
|
||
}
|
||
}
|
||
.table-container {
|
||
padding-top: 1rem;
|
||
}
|
||
|
||
.styled-table {
|
||
border-collapse: collapse;
|
||
margin: 25px 0;
|
||
font-size: 0.9em;
|
||
font-family: sans-serif;
|
||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.styled-table thead tr {
|
||
color: #ffffff;
|
||
text-align: left;
|
||
}
|
||
|
||
.styled-table th,
|
||
.styled-table td {
|
||
padding: 12px 15px;
|
||
}
|
||
|
||
|
||
.styled-table tbody tr.active-row {
|
||
font-weight: bold;
|
||
color: #738694;
|
||
}
|
||
|
||
.fa-check-circle {
|
||
color: rgb(0, 152, 121);
|
||
margin-left: 5px;
|
||
}
|
||
|
||
.fa-exclamation-circle {
|
||
color: #f44336;
|
||
margin-left: 5px;
|
||
}
|
||
|
||
.fa-exclamation-triangle {
|
||
color: darkorange;
|
||
}
|
||
|
||
.summary-container {
|
||
min-height: 100px;
|
||
height: 300px;
|
||
margin-top: 0.5em;
|
||
overflow: auto;
|
||
resize: vertical;
|
||
}
|
||
|
||
summary {
|
||
cursor: pointer;
|
||
}
|
||
|
||
#logs {
|
||
overflow: auto;
|
||
}
|
||
|
||
pre {
|
||
padding: 10px;
|
||
}
|
||
|
||
.build-section {
|
||
text-align: center;
|
||
font-weight: bold;
|
||
padding: .3rem;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.build-info-section {
|
||
padding: 10px 30px;
|
||
margin: 0;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.build-info {
|
||
padding-right: .3rem;
|
||
padding-left: .3rem;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.build-summary {
|
||
display: flex;
|
||
}
|
||
|
||
.tag-image {
|
||
text-align: center;
|
||
}
|
||
|
||
.report-status-pass {
|
||
color: rgb(0, 152, 121)
|
||
}
|
||
|
||
.report-status-fail {
|
||
color: #f44336;
|
||
}
|
||
|
||
.warning-notice {
|
||
display: inline-flex;
|
||
}
|
||
|
||
.warning-note {
|
||
padding-left: .5rem;
|
||
padding-top: 0.5em;
|
||
font-weight: normal;
|
||
}
|
||
|
||
div.warning-notice > p {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.warning-summary {
|
||
padding-right:5px;
|
||
padding-bottom:0;
|
||
margin-block-start: 1em;
|
||
color: darkorange;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.warning-summary:hover {
|
||
color: #ff8c00db;
|
||
}
|
||
</style>
|
||
|
||
</head>
|
||
|
||
<body>
|
||
<div id="app">
|
||
<header>
|
||
<h1>Linux<span>Server</span>.io</h1>
|
||
</header>
|
||
<div id="results">
|
||
<h1 style="margin-bottom: 0; text-align: center;">Test Results</h1>
|
||
<h2 style="margin-bottom: 0; text-align: center;"><strong>{{ image }}</strong></span></h2>
|
||
<h3 style="margin-top:0; margin-bottom: 0; text-align: center;"><strong>{{ meta_tag }}</strong></span></h2>
|
||
<h2 style="margin-bottom: 0">Cumulative: <span class="report-status-{{ report_status.lower() }}">{{ report_status }}</span></h2>
|
||
<span>Total Runtime: {{ total_runtime }}</span>
|
||
<main>
|
||
{% for tag in report_containers %}
|
||
<section>
|
||
<div class="section-header">
|
||
{% if report_containers[tag]["test_success"] %}
|
||
<h3 class="section-header-status"><span class="report-status-pass">{{ report_containers[tag]["platform"] }} PASS</span></h3>
|
||
{% else %}
|
||
<h3 class="section-header-status"><span class="report-status-fail">{{ report_containers[tag]["platform"] }} FAIL</span></h3>
|
||
{% endif %}
|
||
<h2 class="section-header-h2">
|
||
{% if report_status.lower() == "pass" %}
|
||
<a target="_blank" href="{{ report_containers[tag]['build_url'] }}">{{ image }}</a>
|
||
{% else %}
|
||
{{ image }}:{{ tag }}
|
||
{% endif %}
|
||
</h2> </div>
|
||
<div class="runtime build-section">Runtime: {{ report_containers[tag]["runtime"] }}</div>
|
||
{% if screenshot %}
|
||
<a href="{{ tag }}.png">
|
||
<img src="{{ tag }}.png" alt="{{ tag }}" width="600" height="auto" onerror="this.onerror=null; this.src='404.jpg'; this.parentElement.setAttribute('href','#')">
|
||
</a>
|
||
{% else %}
|
||
<div class="tag-image">
|
||
<span>WEB_SCREENSHOT ENV Disabled</span><i class="fas fa-file-image"></i>
|
||
</div>
|
||
{% endif %}
|
||
<div class="build-section">Build Information</div>
|
||
<div class="build-info-section build">
|
||
{% for key, value in report_containers[tag]["build_info"].items() %}
|
||
<div class="build-summary">
|
||
<span class="build-header">{{ key|capitalize }}:</span> <span class="build-info">{{ value }}</span>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
<summary class="summary">
|
||
<a href="{{ tag }}.log.html" target="_blank">View Container Logs</a>
|
||
</summary>
|
||
<details>
|
||
<summary>Expand</summary>
|
||
<div class="summary-container">
|
||
<pre><code>{{ report_containers[tag]["logs"] }}</code></pre>
|
||
</div>
|
||
</details>
|
||
<summary class="summary">
|
||
<a href="{{ tag }}.sbom.html" target="_blank">View SBOM output</a>
|
||
</summary>
|
||
<details>
|
||
<summary>Expand</summary>
|
||
<div class="summary-container">
|
||
<pre><code>{{ report_containers[tag]["sysinfo"] }}</code></pre>
|
||
</div>
|
||
</details>
|
||
{% if report_containers[tag]["browser_logs"] %}
|
||
<summary class="summary">
|
||
<a href="{{ tag }}.browser.html" target="_blank">View Browser Console Logs</a>
|
||
</summary>
|
||
<details>
|
||
<summary>Expand</summary>
|
||
<div class="summary-container">
|
||
<pre><code>{{ report_containers[tag]["browser_logs"] }}</code></pre>
|
||
</div>
|
||
</details>
|
||
{% endif %}
|
||
{% if report_containers[tag]["has_warnings"]%}
|
||
<details open>
|
||
<summary class="warning-summary">Warnings</summary>
|
||
{% for warning in report_containers[tag]["warnings"] %}
|
||
{% if report_containers[tag]["warnings"][warning] %}
|
||
<div class="warning-notice">
|
||
<code class="warning-note"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> {{ report_containers[tag]["warnings"][warning] }}</code>
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</details>
|
||
{% endif %}
|
||
<div class="table-container">
|
||
<table class="styled-table">
|
||
<thead>
|
||
<tr class="active-row">
|
||
<th>Test</th>
|
||
<th>Result</th>
|
||
<th>Message</th>
|
||
<th>Runtime</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for test in report_containers[tag]["test_results"] %}
|
||
<tr>
|
||
<td>{{ test }}</td>
|
||
{% if report_containers[tag]["test_results"][test]['status'] == 'PASS' %}
|
||
<td class="result-cell">{{ report_containers[tag]["test_results"][test]['status'] }} <i class="fas fa-check-circle"></i></td>
|
||
{% else %}
|
||
<td class="result-cell">{{ report_containers[tag]["test_results"][test]['status'] }} <i class="fas fa-exclamation-circle"></i></td>
|
||
{% endif %}
|
||
<td>{{ report_containers[tag]["test_results"][test]["message"] }}</td>
|
||
<td>{{ report_containers[tag]["test_results"][test]["runtime"] }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
{% endfor %}
|
||
</main>
|
||
</div>
|
||
<section class="debug-section">
|
||
<summary class="summary">
|
||
<a href="python.log.html" target="_blank">View Python Logs</a>
|
||
</summary>
|
||
<details>
|
||
<summary>Expand</summary>
|
||
<pre id="logs"></pre>
|
||
</details>
|
||
</section>
|
||
</div>
|
||
<script type="text/javascript" charset="utf-8">
|
||
fetch("ci.log")
|
||
.then(response => response.text())
|
||
.then(logs => {
|
||
pylogs = logs.replace(/\[38;20m/gi,"<span class='log-debug'>"
|
||
).replace(/\[33;20m/gi,"<span class='log-warning'>"
|
||
).replace(/\[31;20m/gi,"<span class='log-error'>"
|
||
).replace(/\[36;20m/gi,"<span class='log-info'>"
|
||
).replace(/\[32;20m/gi,"<span class='log-success'>"
|
||
).replace(/\[0m/gi,"</span>")
|
||
document.getElementById("logs").innerHTML = pylogs
|
||
})
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|