1
0
mirror of git://f0xx.org/ac/ac-be-builder synced 2026-08-12 18:12:50 +03:00

Builder: monotonic OTA versions, duration UI, OTA publish fixes.

VersionAllocator for AA.BB.CC.DDDD, build elapsed display, branded QR alerts, shared cache env, and auto_deploy when auto_ota is set.
This commit is contained in:
Anton Afanasyeu
2026-08-12 14:08:12 +02:00
parent ef6718a5f2
commit e8039aab78
12 changed files with 548 additions and 21 deletions

View File

@@ -2,6 +2,63 @@
'use strict';
var base = document.body.getAttribute('data-base-path') || '';
function formatDuration(seconds) {
seconds = Math.max(0, Math.floor(Number(seconds) || 0));
if (seconds < 60) return seconds + 's';
var m = Math.floor(seconds / 60);
var s = seconds % 60;
if (m < 60) return s > 0 ? m + 'm ' + s + 's' : m + 'm';
var h = Math.floor(m / 60);
m = m % 60;
var parts = [h + 'h'];
if (m > 0) parts.push(m + 'm');
if (s > 0 && h < 48) parts.push(s + 's');
return parts.join(' ');
}
function durationLabelForBuild(build) {
if (!build) return '—';
if (build.duration_label) return build.duration_label;
var kind = build.duration_kind || '';
var sec = build.duration_seconds;
if (sec == null) return '—';
var label = formatDuration(sec);
if (kind === 'elapsed') return 'Running for ' + label;
if (kind === 'queued') return 'queued · ' + label;
return label;
}
function tickDurationFromIso(startIso, kind) {
if (!startIso) return '—';
var start = Date.parse(startIso);
if (!start || isNaN(start)) return '—';
var sec = Math.max(0, Math.floor((Date.now() - start) / 1000));
var label = formatDuration(sec);
if (kind === 'elapsed') return 'Running for ' + label;
if (kind === 'queued') return 'queued · ' + label;
return label;
}
function updateDurationCells() {
document.querySelectorAll('.build-duration-cell[data-duration-started]').forEach(function (cell) {
var kind = cell.getAttribute('data-duration-kind') || '';
if (kind !== 'elapsed' && kind !== 'queued') return;
var start = cell.getAttribute('data-duration-started') || '';
cell.textContent = tickDurationFromIso(start, kind);
});
var kind = document.body.getAttribute('data-duration-kind') || '';
if (kind === 'elapsed' || kind === 'queued') {
var start = document.body.getAttribute('data-build-started-at') || '';
var label = tickDurationFromIso(start, kind);
var el = document.getElementById('build-duration-label');
var detail = document.getElementById('build-duration-detail');
if (el) el.textContent = label;
if (detail) detail.textContent = kind === 'elapsed' ? label : label;
}
}
setInterval(updateDurationCells, 1000);
function buildStatusIconHtml(status) {
var s = String(status || '').toLowerCase();
if (s === 'running' || s === 'queued') {
@@ -37,6 +94,21 @@
}
}
}
if (build.duration_label !== undefined) {
var row2 = cell ? cell.closest('tr') : null;
if (row2) {
var durCell = row2.querySelector('.build-duration-cell');
if (durCell) {
durCell.textContent = durationLabelForBuild(build);
if (build.duration_kind) {
durCell.setAttribute('data-duration-kind', build.duration_kind);
}
if (build.duration_started_at) {
durCell.setAttribute('data-duration-started', build.duration_started_at);
}
}
}
}
}
function updateBuildRow(row, build) {
@@ -139,11 +211,17 @@
run_native: !!form.querySelector('[name=run_native]').checked,
run_apk: !!form.querySelector('[name=run_apk]').checked,
auto_ota: !!form.querySelector('[name=auto_ota]').checked,
auto_deploy: !!form.querySelector('[name=auto_deploy]').checked,
auto_deploy: !!form.querySelector('[name=auto_ota]').checked,
notify_on_fail: !!form.querySelector('[name=notify_on_fail]').checked,
notify_channel: fd.get('notify_channel') || 'email',
trigger_source: 'manual'
};
['ota_major', 'ota_minor', 'ota_patch'].forEach(function (k) {
var el = form.querySelector('[name=' + k + ']');
if (el && el.value !== '') {
payload[k] = parseInt(el.value, 10);
}
});
status.textContent = 'Starting…';
fetch(base + '/api/build_trigger.php', {
method: 'POST',
@@ -310,6 +388,23 @@
+ '</span>') : '';
textEl.innerHTML = 'Status: <strong>' + (j.build.status || '') + '</strong> · Phase: '
+ (j.build.phase || '') + err;
var durLabel = durationLabelForBuild(j.build);
if (durLabel !== '—') {
textEl.innerHTML += ' · <span id="build-duration-label">' + durLabel + '</span>';
}
var durDetail = document.getElementById('build-duration-detail');
if (durDetail && j.build.duration_kind === 'final') {
durDetail.textContent = j.build.duration_label || durLabel;
}
}
if (j.build.duration_kind) {
document.body.setAttribute('data-duration-kind', j.build.duration_kind);
}
if (j.build.duration_started_at) {
document.body.setAttribute('data-build-started-at', j.build.duration_started_at);
}
if (j.build.duration_finished_at) {
document.body.setAttribute('data-build-finished-at', j.build.duration_finished_at);
}
document.body.setAttribute('data-build-status', j.build.status || '');
}