Commit c1137e0
authored
v1 release infrastructure: UI overhaul, README, CI, release pipeline (#1)
* Overhaul dashboard UI to match Android
Replace the flat list/text dashboard with Android-parity device cards: each peer renders as a Material-3 card containing a tile grid (hero/wide + paired narrow tiles), with quick actions, overflow menu, and a per-tile bottom-sheet detail view. Tile layouts persist per-device in IndexedDB. Self device pins to the top-left of a responsive multi-column grid that scales to ultrawide displays. Read-only modules (Apps, Power, WiFi, Connectivity) join Clipboard/Files/Meta via a central module registry with ETag-cached payload decoding. Adds a sticky nav header (title + identity subtitle + version pill + last-sync pill + Refresh + Settings + overflow), Settings sheet (editable device label with republish + read-only diagnostics + SHA-256 keyset fingerprint), and route-level width classes (onboarding stays narrow, dashboard fills viewport up to header cap at 1400px).
* Add P0+P1 unit tests and smoke harness
P0 (correctness-critical): base64 ↔ bytes roundtrip, HKDF-SHA256 against RFC 5869 vectors, blob-cipher roundtrip + AAD format pinning. P1 (high-value): mocked-fetch coverage of the octi-api surface (auth header, deviceHeaders propagation including label, URL encoding, ETag passthrough, 412 mapping), blob-session lifecycle (create → multi-chunk PATCH with Upload-Offset progression → finalize → returns blobId), including the dangerous-server failure modes the implementation could previously hang on (non-progressing offset → infinite loop, offset past ciphertext length); poll-loop fake-timer coverage (interval, visibility pause + immediate-on-focus, re-entrancy dedup, error survival, stop); credentials-repo IndexedDB roundtrip via fake-indexeddb (stale-pointer scrub, multi-account list, wipe). Adds blob-session offset-progress guards to fix the infinite-loop on a misbehaving server (Codex flagged during plan review). Adds src/__smoke__/smoke.test.ts: full account-create → encrypted meta publish + read against a real sync-server. Skipped by default; CI smoke job runs it explicitly via SMOKE_SERVER_URL. Adds jsdom devDep for the localStorage + document tests.
* Add app icon, manifest, custom-domain hosting
Vendors the Octi.png master from app-desktop's resources (512×512) into public/icons/, plus ImageMagick-downscaled 192 (PWA + Apple touch + nav header) and 32 (favicon) variants. Adds a webmanifest declaring name/short_name/standalone-display/theme + the two PWA icon sizes. Adds public/CNAME for the custom-domain Pages hosting at web.octi.darken.eu (must be DNS-pointed at GitHub Pages before the first release). Wires <link rel="icon|apple-touch-icon|manifest"> + <meta name="theme-color"> into index.html (CSP already allows img-src 'self' data: and manifest-src 'self'). Adds inline boot-flash style so the tab background matches the dark theme between document parse and Svelte mount. Renders the 36×36 brand icon next to the title in NavBar (restructures .identity into a flex row), and re-cases the title to "Octi Web" to match the wordmark.
* Rewrite README for v1 release
Drops the Status/Stack/Storage sections (internal churn / not user-facing) and leads with the Octi banner + badges (release version, CI status, license, Discord) above an Install section pointing at the hosted instance, the static-host tarball, and the Docker image. Keeps the sync-server CORS guide (still relevant to self-hosters), compatibility notes (shortened), and the Develop block (with the new pnpm test:smoke target) at the bottom. Adds an explicit mixed-content caveat for users with HTTP-only LAN sync-servers.
* Add CI: type-check, test, build, smoke, release-tooling
Five parallel jobs on every PR/push to main: svelte-check (types), vitest (unit tests), Vite production build (with dist upload as a 7-day artifact for reviewer spot-checks), a real-server smoke job against a digest-pinned sync-server Docker service (account create + encrypted-meta roundtrip), and the release-tooling validator (shellcheck + bats on bump.sh, consistency check). Composite action .github/actions/common-setup installs pnpm + Node 24 with pnpm-cache enabled so every job warms in seconds. Actions pinned by SHA + version comment, matching the Android repo's pattern. Release-tooling job runs even though bump.sh isn't committed yet — the next commit adds it; CI on this branch's first push will show that job red until the release pipeline commit lands.
* Add release pipeline (prepare + tag + Pages + Docker)
Ports the Android dispatch UX (Actions tab → Release prepare → version inputs → optional dry-run → atomic commit + tag push) to a Node/Vite SPA. Source of truth is package.json#version (no version.properties / versionCode — web has no app-store gating). tools/release/bump.sh mirrors the Android bump.sh CLI (--mode={check,plan,write}, --bump-kind, --version-type, --version-override, --expected-current) and refuses to bump from the placeholder 0.0.0 without an explicit override. 16-case bats suite + shellcheck-clean. release-prepare.yml gates Job 2 with the web-production environment so the bump commit + tag push happen only after operator approval — diverges from Android's pattern (rationale documented in RELEASE.md and inline). Job 1 also asserts the named required checks (check/test/build/smoke/release-tooling) are present + green on the candidate commit so a path-ignored push can't sneak through. release-tag.yml fans out three publish jobs after a single validate-tag (regex, on-main, name matches): release-github (tarball + softprops/action-gh-release with pre-release flag for -rc/-beta), release-pages (configure-pages → upload-pages-artifact → deploy-pages, environment github-pages, pages:write + id-token:write), release-docker (login-action + buildx + multi-arch amd64+arm64, :latest only on suffix-free vM.m.p). pages.yml standalone manual deploy mirrors Android. Dockerfile is a two-stage node:24-alpine → nginx:alpine static serve; the strict CSP travels with index.html's meta tag. .dockerignore keeps the image lean. RELEASE.md walks the one-time setup (App install, ruleset bypass, GH Pages enable, environment, DNS, sync-server digest refresh) and the first-release dispatch flow.
* Fix test:smoke filter — pass path positionally instead of --dir
vitest's --dir changes the project root, so 'src/**/*.test.ts' (relative to the new root) finds nothing inside the directory we wanted to filter. Pass the test path positionally so vitest uses it as a name filter against the configured include pattern.1 parent 133bfb6 commit c1137e0
81 files changed
Lines changed: 8479 additions & 476 deletions
File tree
- .github
- actions/common-setup
- workflows
- public
- icons
- src
- __smoke__
- crypto
- modules
- protocol
- storage
- sync
- ui
- dashboard
- tiles
- util
- tools/release
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
Loading
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
0 commit comments