Files
AppStore/builder/public/js/build.js
trey 8dbe87da2e Phase 4-5: build pipeline + device enrollment
Builder service (Mac mini):
- Build worker: xcodebuild archive + export + fastlane signing + upload to unraid
- /api/build/upload (source archive) and /api/build/git (clone) ingest paths
- SSE-streamed build logs, builds list UI, live status updates
- /api/devices/from-enrollment bridge endpoint (shared-secret auth)

Storefront (unraid):
- /enroll/ public flow: landing page, mobileconfig generator, callback parser
- Forwards extracted UDIDs to the Mac mini builder for ASC registration
- docker-compose.yml now passes BUILDER_URL and BUILDER_SHARED_SECRET

Updated CLAUDE.md with full architecture, deploy flow, and gotchas.
2026-04-11 14:04:32 -05:00

52 lines
1.6 KiB
JavaScript

const $ = (s) => document.querySelector(s);
function toast(msg, kind = '') {
const t = $('#toast');
t.textContent = msg;
t.className = 'toast show ' + kind;
setTimeout(() => t.classList.remove('show'), 3500);
}
$('#upload-form').addEventListener('submit', async (e) => {
e.preventDefault();
const fd = new FormData(e.target);
const btn = e.target.querySelector('button[type=submit]');
btn.disabled = true;
btn.textContent = 'Uploading…';
try {
const r = await fetch('/api/build/upload', { method: 'POST', body: fd });
const data = await r.json();
if (!r.ok) throw new Error(data.error || 'Upload failed');
location.href = `/builds#${data.job_id}`;
} catch (err) {
toast(err.message, 'error');
btn.disabled = false;
btn.textContent = 'Queue Build';
}
});
$('#git-form').addEventListener('submit', async (e) => {
e.preventDefault();
const body = {
url: e.target.url.value.trim(),
branch: e.target.branch.value.trim() || null,
scheme: e.target.scheme.value.trim() || null,
};
const btn = e.target.querySelector('button[type=submit]');
btn.disabled = true;
btn.textContent = 'Cloning…';
try {
const r = await fetch('/api/build/git', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const data = await r.json();
if (!r.ok) throw new Error(data.error || 'Clone failed');
location.href = `/builds#${data.job_id}`;
} catch (err) {
toast(err.message, 'error');
btn.disabled = false;
btn.textContent = 'Queue Build';
}
});