feat: rename Docker Watcher to Tinyforge
Build / build (push) Successful in 12m20s

Rebrand the project as Tinyforge to reflect its evolution from a Docker
container watcher into a self-hosted mini CI/deployment platform.

Rename covers: Go module path, Docker labels, DB/config filenames,
JWT issuer, Dockerfile binary, docker-compose, CI workflows, frontend
i18n, README with static sites docs, and all code comments.
This commit is contained in:
2026-04-12 21:30:23 +03:00
parent 8d2c5a063b
commit 791cd4d6af
68 changed files with 512 additions and 224 deletions
+8 -8
View File
@@ -8,7 +8,8 @@
import { fetchEventLog, fetchEventLogStats, clearAllEvents, deleteEvent } from '$lib/api';
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
import { toasts } from '$lib/stores/toast';
import { connectGlobalEvents, type SSEConnection, type EventLogSSEPayload } from '$lib/sse';
import { subscribeEventLog } from '$lib/stores/event-log-bus';
import type { EventLogSSEPayload } from '$lib/sse';
import type { EventLogEntry, EventLogStats } from '$lib/types';
import EventLogEntryComponent from '$lib/components/EventLogEntry.svelte';
import EventLogFilter from '$lib/components/EventLogFilter.svelte';
@@ -35,7 +36,7 @@
const PAGE_SIZE = 50;
let offset = $state(0);
let sseConnection: SSEConnection | null = null;
let unsubscribeEventLog: (() => void) | null = null;
let listEl: HTMLDivElement | undefined = $state();
let showClearConfirm = $state(false);
@@ -198,16 +199,15 @@
loadEvents();
loadStats();
sseConnection = connectGlobalEvents({
onEventLog(payload) {
handleSSEEvent(payload);
}
// Subscribe to event_log events from the global SSE connection (no duplicate connection).
unsubscribeEventLog = subscribeEventLog((payload: EventLogSSEPayload) => {
handleSSEEvent(payload);
});
});
onDestroy(() => {
sseConnection?.close();
sseConnection = null;
unsubscribeEventLog?.();
unsubscribeEventLog = null;
});
</script>
+16 -15
View File
@@ -161,7 +161,7 @@
let showDeleteConfirm = $state(false);
const projectId = $derived($page.params.id);
const projectId = $derived($page.params.id!); // always present on [id] route
async function loadProject() {
if (!project) loading = true;
@@ -188,21 +188,22 @@
}
instancesByStage = mapped;
try {
const allDeploys = await api.listDeploys(20);
deploys = allDeploys.filter((d) => d.project_id === projectId);
} catch {
deploys = [];
}
// Fetch deploys, settings, and images in parallel (independent of each other).
const [deploysResult, settingsResult, imagesResult] = await Promise.allSettled([
api.listDeploys(20),
api.getSettings(),
api.listProjectImages(projectId)
]);
try {
const settings = await api.getSettings();
settingsDomain = settings.domain ?? '';
} catch { /* non-critical */ }
try {
localImages = await api.listProjectImages(projectId);
} catch { localImages = []; }
deploys = deploysResult.status === 'fulfilled'
? deploysResult.value.filter((d) => d.project_id === projectId)
: [];
settingsDomain = settingsResult.status === 'fulfilled'
? (settingsResult.value.domain ?? '')
: settingsDomain;
localImages = imagesResult.status === 'fulfilled'
? imagesResult.value
: [];
} catch (e) {
error = e instanceof Error ? e.message : $t('projectDetail.loadFailed');
} finally {
+1 -1
View File
@@ -145,7 +145,7 @@
<h3 class="text-base font-semibold text-[var(--text-primary)]">{$t('settingsAuth.oidcConfig')}</h3>
<div class="mt-4 space-y-4">
{#each [
{ id: 'issuer', label: $t('settingsAuth.issuerUrl'), type: 'url', key: 'oidc_issuer_url', placeholder: 'https://auth.example.com/application/o/docker-watcher/' },
{ id: 'issuer', label: $t('settingsAuth.issuerUrl'), type: 'url', key: 'oidc_issuer_url', placeholder: 'https://auth.example.com/application/o/tinyforge/' },
{ id: 'client_id', label: $t('settingsAuth.clientId'), type: 'text', key: 'oidc_client_id', placeholder: '' },
{ id: 'client_secret', label: $t('settingsAuth.clientSecret'), type: 'password', key: 'oidc_client_secret', placeholder: '' },
{ id: 'redirect', label: $t('settingsAuth.redirectUrl'), type: 'url', key: 'oidc_redirect_url', placeholder: 'https://watcher.example.com/api/auth/oidc/callback' }