golang.org/x/build@v0.0.0-20240506185731-218518f32b70/devapp/templates/release.tmpl (about) 1 <!DOCTYPE html> 2 <html lang="en"> 3 <meta charset="utf-8"> 4 <meta name="viewport" content="width=device-width, initial-scale=1"> 5 <title>Go Release Dashboard</title> 6 <style> 7 * { 8 box-sizing: border-box; 9 margin: 0; 10 padding: 0; 11 } 12 body { 13 font: 13px monospace; 14 padding: 1rem; 15 } 16 a:link, 17 a:visited { 18 color: #00c; 19 } 20 .CountSummary { 21 font-weight: bold; 22 list-style: none; 23 margin: .5em 0 1em; 24 } 25 .Header { 26 display: flex; 27 flex-wrap: wrap; 28 font-weight: bold; 29 justify-content: space-between; 30 } 31 .BurndownChart { 32 height: 250px; 33 width: 500px; 34 } 35 .Section { 36 border-top: 1px solid #aaa; 37 padding-bottom: 2em; 38 } 39 .Section-title { 40 margin: .5em 0; 41 } 42 .Performance-separator { 43 margin-left:4ch; 44 } 45 .Item { 46 display: flex; 47 } 48 .Item-num { 49 margin-left: 1ch; 50 min-width: 12ch; 51 } 52 .Mark { 53 width: 3ch; 54 height: 1ch; 55 text-align: center; 56 vertical-align: middle; 57 } 58 .DirTitle { 59 margin: 1em 0 .25em; 60 } 61 </style> 62 <header class="Header"> 63 <div class="Header-left"> 64 <div>Release dashboard</div> 65 <div>{{.LastUpdated}}</div> 66 <ul class="CountSummary"> 67 {{range .Sections}} 68 <li><a href="#{{.Title}}">{{.Count}} {{.Title}}</a></li> 69 {{end}} 70 </ul> 71 </div> 72 <div class="BurndownChart"> 73 <canvas class="js-burndownChart"></canvas> 74 </div> 75 </header> 76 <main> 77 {{range .Sections}} 78 <section class="Section"> 79 <h3 class="Section-title" id="{{.Title}}">{{.Title}}</h3> 80 {{range .Groups}} 81 {{if .Dir}}<h4 class="DirTitle">{{.Dir}}</h4>{{end}} 82 {{range .Items}} 83 {{if .FirstPerformance}}<h5 class="Performance-separator">performance</h5>{{end}} 84 {{$i := .Issue}} 85 {{if $i}} 86 <div class="Item"> 87 {{$currentBlocker := and (eq .Issue.Milestone.Title $.CurMilestone) .ReleaseBlocker}} 88 {{if $currentBlocker}} 89 <div class="Mark" title="{{.Issue.Milestone.Title}} release blocker">★</div> 90 {{else if .ReleaseBlocker}} 91 <div class="Mark" title="Release blocker">✩</div> 92 {{else if .EarlyInCycle}} 93 <div class="Mark" title="Early In Cycle">⏱󠄀</div> 94 {{else}} 95 <div class="Mark"> </div> 96 {{end}} 97 <a class="Item-num" href="https://golang.org/issue/{{.Issue.Number}}" target="_blank">#{{.Issue.Number}}</a> 98 <span class="Item-title">{{.Issue.Title}}</span> 99 </div> 100 {{end}} 101 {{range .CLs}} 102 {{if not .Closed}} 103 <div class="Item"> 104 <div class="Mark"></div> 105 <span class="Item-num"> 106 {{if $i}}⤷{{end}} <a href="{{.ReviewURL}}" target="_blank">CL {{.Number}}</a> 107 </span> 108 <span class="Item-title">{{if $i}}⤷{{end}} {{.NoPrefixTitle}}</span> 109 </div> 110 {{end}} 111 {{end}} 112 {{end}} 113 {{end}} 114 </section> 115 {{end}} 116 </main> 117 <script src="/js/Chart.min.js"></script> 118 <script> 119 const data = {{.BurndownJSON}} 120 new Chart(document.querySelector('.js-burndownChart'), { 121 type: 'line', 122 data: { 123 labels: data.entries.map(d => d.dateStr), 124 datasets: [ 125 { 126 label: `${data.milestone} total issues`, 127 yAxisID: 'total', 128 data: data.entries.map(d => d.open), 129 backgroundColor: 'transparent', 130 borderColor: 'rgba(54, 162, 235, 0.8)', 131 pointRadius: 0, 132 }, 133 { 134 label: `${data.milestone} release blocking`, 135 yAxisID: 'release-blocking', 136 data: data.entries.map(d => d.blockers), 137 backgroundColor: 'rgba(0,0,0,0)', 138 borderColor: 'rgba(255, 99, 132, 0.8)', 139 pointRadius: 0, 140 }, 141 ], 142 }, 143 options: { 144 animation: { 145 duration: 0, 146 }, 147 title: { 148 display: true, 149 text: `${data.milestone} Issues`, 150 position: 'left', 151 }, 152 legend: { 153 display: false, 154 }, 155 tooltips: { 156 intersect: false, 157 }, 158 scales: { 159 yAxes: [ 160 { 161 id: 'total', 162 ticks: { 163 beginAtZero: true, 164 }, 165 position: 'left', 166 }, 167 { 168 id: 'release-blocking', 169 ticks: { 170 beginAtZero: true, 171 }, 172 position: 'right', 173 }, 174 ], 175 }, 176 }, 177 }); 178 </script>