Skip to content

feat: adopt freenet/mail build + release process#6

Merged
iduartgomez merged 10 commits into
mainfrom
feat/adopt-mail-build-release
Apr 27, 2026
Merged

feat: adopt freenet/mail build + release process#6
iduartgomez merged 10 commits into
mainfrom
feat/adopt-mail-build-release

Conversation

@netsirius
Copy link
Copy Markdown
Contributor

Problem

This repo had a plain Makefile, no CI, no release driver, no signed webapp, and no committed published-contract/ snapshot. Cutting a release would produce a non-reproducible, unsigned contract ID that nobody could verify against repo state. Two contributors building the same commit would derive different IDs (Vite chunk timestamps, tar mtime/owner, signing nonce drift). freenet/mail already solved this on top of freenet/river's baseline; aligning now is cheaper than retrofitting after the first release.

Solution

Port mail's pipeline, adapted from Dioxus to our Vite/TypeScript stack.

  • Makefile.toml (cargo-make) — replaces Makefile. 41 tasks for build, test, sign, snapshot, publish. Each contract/delegate task pins CARGO_TARGET_DIR so fdev's workspace walk doesn't panic from a stale install tree.
  • rust-toolchain.toml — pins stable (matches mail) so WASM bytes are reproducible across contributors.
  • tools/web-container-sign/ — vendored from freenet/mail/tools/. ed25519 signer CLI. Mail's freenet-email-core::WebContainerMetadata import inlined as a 2-field struct so we don't need a path dep.
  • compress-webapp — GNU tar with --sort=name --mtime='2024-01-01 ...' --owner=0 --group=0 --numeric-owner produces byte-identical archives. Warns (doesn't fail) without gtar.
  • sign-webapp{,-test} — version derived from git rev-parse --short=8 HEAD (interpret hex as u31), so two contributors on the same commit produce identical signatures. ed25519 is deterministic. Test variant uses committed key at test-contract/web-container-keys.toml; prod variant uses uncommitted ~/.config/freenet-microblogging/web-container-keys.toml (overridable via WEB_CONTAINER_KEY_FILE).
  • published-contract/ — committed snapshot (web_container_contract.wasm + webapp.parameters + contract-id.txt). Initial test ID: H5JJ7UXJS6Rs8DtKd4tHJaUV9kB839UcYZczuH1XbcNP. publish-webapp* publishes from this snapshot, not freshly built artifacts, so stale snapshots fail loudly.
  • CI.github/workflows/build.yml (build + clippy + test + Playwright with version-pinned cargo-make/fdev caches) and check-contract-wasm.yml (rebuilds at HEAD, fails if git diff --quiet -- published-contract/ doesn't pass).
  • Playwright at web/tests/ — runs against vite preview --port 8082 after build-ui-offline (Vite equivalent of mail's dx serve --features example-data,no-sync). production-liveness.spec.ts covers title set, sidebar mounts, post card renders.
  • scripts/release.sh — preflight (clean tree, on main, no tag collision, prod key + tools present, GNU tar, node reachable on 127.0.0.1:50509) → test gate → 3 confirmation prompts (publish ▸ commit ▸ push) → idempotent up to commit. --yes for CI. Plus generate-production-key.sh, smoke-test-production.sh, RELEASING.md runbook.
  • Offline modeVITE_OFFLINE_MODE=1 define in vite.config.ts branches web/src/index.ts to render MOCK_POSTS immediately without WebSocket/delegate. Required for Playwright in CI.

AGENTS.md and README.md updated to use cargo make X everywhere. .gitignore adds the new build outputs.

Testing

  • cargo make build succeeds — contracts + UI + web container.
  • cargo make compress-webapp × 2 → identical sha256 (byte-reproducible).
  • cargo make sign-webapp-test × 2 → identical metadata + parameters bytes.
  • cargo make update-published-contract × 2 → identical contract ID.
  • cargo make test-{posts,follows,likes} → 13/13 passing.
  • cargo make test-ui-playwright → 3/3 browsers (chromium/firefox/webkit) passing.
  • cargo make sign-webapp (no prod key present) → fails loudly with the documented error.
  • scripts/release.sh notaversion → rejected by semver regex; scripts/release.sh (no arg) → usage error.

Known caveats (not blockers, follow-up)

  • 4 pre-existing files have clippy/fmt drift (web/container/src/lib.rs, delegates/identity/src/lib.rs, contracts/{follows,likes,posts}/src/lib.rs). First CI run will fail on clippy + fmt-check until either fixed or -D warnings relaxed. Out of scope here.
  • web/container/src/lib.rs is still a stub — does not deserialize WebContainerMetadata or verify the signature. Pipeline produces signed metadata but on-chain contract doesn't enforce it. Mail's container does; porting that verification is a separate task.
  • Vitest has no specs in this repo — cargo make test exits non-zero at npm test. Pre-existing.

Closes #3

@netsirius netsirius force-pushed the feat/adopt-mail-build-release branch from 02b56de to 834f071 Compare April 26, 2026 09:57
@netsirius netsirius requested a review from iduartgomez April 26, 2026 15:04
* Merge main (brings Raven rebrand from #7) into PR branch.
* web/container: port full ed25519 + version validation from
  freenet/mail. Adds 6 unit tests covering valid/invalid sig,
  version monotonicity, summary/delta. Container is no longer
  a stub.
* common/: new crate. Hosts WebContainerMetadata struct shared
  between web/container and tools/web-container-sign so the two
  CBOR formats cannot drift.
* check-contract-wasm.yml: gate now fails on drift (was exit 0
  with warning). Adds published-contract/** + Cargo.toml to
  trigger paths and a push-on-main job.
* web/tests/production-liveness.spec.ts: title now "Raven"
  (matches merged rebrand).
* published-contract/: regenerated locally; contract id =
  6vGnrBknBqysGZFgzor8bVdvYXRNz1ddzsdrnHrosLeQ. CI on Linux
  may produce a different snapshot — first Linux run will
  surface drift; commit the Linux snapshot once.
* Cargo.toml: drop dead commented [target.wasm32-unknown-unknown]
  block. Add common/ to workspace members.
* Drop .claude/settings.json (per-machine path leaked into repo).
@iduartgomez iduartgomez changed the title feat: Adopt freenet/mail build + release process feat: adopt freenet/mail build + release process Apr 27, 2026
Lets reviewers grab the canonical Linux-built snapshot from the
failing run instead of guessing what to commit.
CI rebuild produces different bytes than macOS local build (different
LLVM/codegen between hosts). Snapshot now matches ubuntu-latest output
so check-contract-wasm gate passes.

Contract ID: CQTvAgQQuxZHTmTi17DaaNgrv3KCVNtxY1vCamFfkV41
@iduartgomez iduartgomez merged commit 0531804 into main Apr 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt freenet/mail build + release process (aligned with river)

2 participants