1
0
mirror of git://f0xx.org/ac/ac-be-builder synced 2026-07-29 02:58:34 +03:00
Files
ac-be-builder/views/build_detail.php
Anton Afanasyeu 5e3e5939a8 initial
2026-06-23 12:29:38 +02:00

125 lines
7.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php declare(strict_types=1);
$artifacts = json_decode($build['artifacts_json'] ?? '{}', true) ?: [];
$params = json_decode($build['params_json'] ?? '{}', true) ?: [];
$status = (string) ($build['status'] ?? '');
$phase = (string) ($build['phase'] ?? '');
$isRunning = $status === 'running';
$canRerunFromFailed = in_array($status, ['failed', 'cancelled'], true);
$failedStep = $canRerunFromFailed ? BuildRunner::detectFailedStep((int) ($build['id'] ?? 0)) : '';
$isSshDebug = $phase === 'ssh_debug' || ($isRunning && !empty($params['ssh_debug']));
$sshContainer = BuildRunner::debugContainerName((int) ($build['id'] ?? 0));
$builderHost = (string) ($build['builder_id'] ?? gethostname() ?: 'builder');
$pipelineYaml = trim((string) ($build['pipeline_yaml'] ?? ''));
if ($pipelineYaml === '') {
$pipelineYaml = '(none — will be generated on next trigger from build.config.yml or params)';
}
$stepLabels = [
'git' => 'Git checkout / shallow clone',
'docker-build' => 'Docker image build',
'docker-run' => 'Gradle pipeline (docker run)',
];
?>
<h1>Build <?= h($build['build_code'] ?? '') ?></h1>
<p class="muted build-status-line" id="build-status-line">
<span id="build-status-icon"><?= build_status_icon($status) ?></span>
<span id="build-status-text">Status: <strong><?= h($status) ?></strong> · Phase: <?= h($phase) ?>
<?php if (!empty($build['error_message'])): ?>
· <span class="error-text" id="build-error-message"><?= h($build['error_message']) ?></span>
<?php endif; ?>
</span>
</p>
<?php
$healthDocker = ($health['docker'] ?? '') === 'ok';
$dockerFail = str_contains((string) ($build['error_message'] ?? ''), 'Docker daemon not available');
if ($status === 'failed' && $dockerFail && $healthDocker):
?>
<p class="muted graphs-footnote">Ecosystem health reports <strong>Docker: ok</strong> now. The log below is from this failed run — use <strong>Re-run</strong> (do not only refresh).</p>
<?php endif; ?>
<?php if ($canRerunFromFailed && $failedStep !== ''): ?>
<p class="muted graphs-footnote">Failed at step: <strong><?= h($stepLabels[$failedStep] ?? $failedStep) ?></strong> — <em>Re-run from failed</em> skips earlier steps when artifacts allow (like CircleCI).</p>
<?php endif; ?>
<div class="build-actions card card--lift" style="margin-bottom:12px">
<h2>Actions</h2>
<div class="toolbar-actions" style="flex-wrap:wrap;gap:8px">
<a class="btn" href="<?= h(Auth::basePath()) ?>/">← Back</a>
<button type="button" class="btn" id="build-rerun-btn" data-build-id="<?= (int) $build['id'] ?>">Re-run</button>
<?php if ($canRerunFromFailed): ?>
<button type="button" class="btn" id="build-rerun-failed-btn" data-build-id="<?= (int) $build['id'] ?>" title="Resume from <?= h($failedStep) ?>">Re-run from failed</button>
<button type="button" class="btn" id="build-rerun-ssh-btn" data-build-id="<?= (int) $build['id'] ?>" title="Resume from failed step, then open an interactive container (CircleCI-style SSH debug)">Re-run with SSH</button>
<?php endif; ?>
<button type="button" class="btn" id="build-rerun-as-toggle">Re-run as…</button>
<?php if ($isRunning): ?>
<button type="button" class="btn btn-danger" id="build-stop-btn" data-build-id="<?= (int) $build['id'] ?>"><?= $isSshDebug ? 'End SSH session' : 'Stop' ?></button>
<?php endif; ?>
<span id="build-action-status" class="muted"></span>
</div>
<?php if ($isSshDebug): ?>
<div class="build-ssh-panel" id="build-ssh-panel">
<strong>SSH debug session</strong>
<p class="muted graphs-footnote" style="margin:6px 0 0">Shell into the CI container on the builder host (same idea as CircleCI “Rerun with SSH”). Stop ends the session.</p>
<pre id="build-ssh-command">ssh &lt;user&gt;@<?= h($builderHost) ?>
docker exec -it <?= h($sshContainer) ?> bash</pre>
</div>
<?php endif; ?>
<form id="build-rerun-as-form" class="build-form" hidden style="margin-top:12px">
<div class="build-form-grid">
<label>Git ref<input name="git_ref" value="<?= h($params['git_ref'] ?? $build['git_ref'] ?? 'next') ?>"></label>
<label>Gradle task<input name="gradle_task" value="<?= h($params['gradle_task'] ?? 'assembleDebug') ?>"></label>
<label>OTA channel<select name="ota_channel">
<?php foreach (['staging', 'dev', 'nightly', 'stable'] as $ch): ?>
<option value="<?= h($ch) ?>" <?= (($params['ota_channel'] ?? $build['ota_channel'] ?? 'staging') === $ch) ? 'selected' : '' ?>><?= h($ch) ?></option>
<?php endforeach; ?>
</select></label>
</div>
<div class="build-form-checks">
<label><input type="checkbox" name="run_tests" <?= !empty($params['run_tests']) ? 'checked' : '' ?>> Unit tests</label>
<label><input type="checkbox" name="run_native" <?= !isset($params['run_native']) || !empty($params['run_native']) ? 'checked' : '' ?>> Native codecs</label>
<label><input type="checkbox" name="run_apk" <?= !isset($params['run_apk']) || !empty($params['run_apk']) ? 'checked' : '' ?>> APK output</label>
<label><input type="checkbox" name="auto_ota" <?= !empty($params['auto_ota']) ? 'checked' : '' ?>> Create OTA artifacts</label>
<label><input type="checkbox" name="auto_deploy" <?= !empty($params['auto_deploy']) ? 'checked' : '' ?>> Publish OTA to mount</label>
</div>
<button type="submit" class="btn btn-primary">Start parametrized re-run</button>
</form>
</div>
<div class="detail-grid card card--lift">
<dl>
<dt>Builder</dt><dd><?= h($build['builder_id'] ?? '') ?></dd>
<dt>CI image</dt><dd><code><?= h($build['dockerfile_version'] ?? '') ?></code></dd>
<dt>Target OS</dt><dd><?= h($build['target_os'] ?? 'android') ?> (min API <?= (int) ($build['min_api_level'] ?? 24) ?>)</dd>
<dt>Git ref</dt><dd><code><?= h($build['git_ref'] ?? '—') ?></code></dd>
<dt>Git SHA</dt><dd><code><?= h($build['git_sha'] ?? '—') ?></code></dd>
<dt>OTA channel</dt><dd><?= h($build['ota_channel'] ?? '—') ?></dd>
<dt>Gradle task</dt><dd><code><?= h($params['gradle_task'] ?? '—') ?></code></dd>
</dl>
</div>
<?php if ($artifacts): ?>
<section class="card card--lift">
<h2>Artifacts</h2>
<ul>
<?php foreach ($artifacts as $k => $v): ?>
<li><strong><?= h($k) ?>:</strong> <code><?= h((string) $v) ?></code></li>
<?php endforeach; ?>
</ul>
</section>
<?php endif; ?>
<section class="card card--lift">
<h2>Pipeline (YAML)</h2>
<p class="muted graphs-footnote">Snapshot stored with this build. New triggers use <code>build.config.yml</code> from the repo when present, otherwise a generated default.</p>
<pre class="log-preview"><?= h($pipelineYaml) ?></pre>
</section>
<section class="card card--lift">
<h2>Build log</h2>
<p class="muted graphs-footnote">Live tail shows the last ~50&nbsp;KB while running. Failed builds load the full log automatically. Per-step files (when present): <code>docker-build.log</code>, <code>docker-run.log</code> under this builds artifact dir.</p>
<pre id="build-log-tail" class="log-preview log-preview--live" aria-live="polite"></pre>
<div class="build-log-actions">
<button type="button" class="btn" id="build-log-expand">Show full log</button>
<a class="btn" id="build-log-download" href="<?= h(Auth::basePath()) ?>/api/build_log.php?id=<?= (int) $build['id'] ?>&amp;download=1">Download log</a>
</div>
</section>