Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Site acceptance

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
acceptance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.13
- name: Install workspace
run: bun install --frozen-lockfile
- name: Content, types, generation, and static contracts
run: |
bun run check
bun run test
- name: Install browser
run: |
bunx playwright install --with-deps chromium
echo "CHROME_PATH=$(bun -e 'import { chromium } from "playwright"; console.log(chromium.executablePath())')" >> "$GITHUB_ENV"
- name: Browser, accessibility, and visual acceptance
run: bun run test:e2e
- name: Lighthouse budgets
run: bun run test:lighthouse
- name: Diff hygiene
run: git diff --check
- name: Upload browser diagnostics
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-diagnostics
path: |
playwright-report
test-results
if-no-files-found: ignore
108 changes: 108 additions & 0 deletions .github/workflows/release-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Mobench release sync

on:
schedule:
- cron: '23 7 * * *'
workflow_dispatch:
inputs:
tag:
description: Optional explicit stable tag; defaults to the latest release
required: false
type: string

permissions:
contents: write
pull-requests: write

concurrency:
group: mobench-release-sync
cancel-in-progress: false

jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.13

- name: Resolve stable release and checksum
id: release
env:
GH_TOKEN: ${{ github.token }}
REQUESTED_TAG: ${{ inputs.tag }}
run: |
tag="$REQUESTED_TAG"
if [ -z "$tag" ]; then
tag="$(gh api repos/worldcoin/mobile-bench-rs/releases/latest --jq '.tag_name')"
fi
current="$(bun -e 'console.log((await Bun.file("packages/truth/pin.json").json()).release)')"
if [ "$tag" = "$current" ]; then
echo "update=false" >> "$GITHUB_OUTPUT"
exit 0
fi
checksum_dir="$(mktemp -d)"
gh release download "$tag" \
--repo worldcoin/mobile-bench-rs \
--pattern 'mobench-site-manifest-v1.json.sha256' \
--dir "$checksum_dir"
expected="$(awk '{print $1}' "$checksum_dir/mobench-site-manifest-v1.json.sha256")"
if ! printf '%s' "$expected" | grep -Eq '^[0-9a-f]{64}$'; then
echo "Release checksum asset is invalid" >&2
exit 1
fi
echo "update=true" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
echo "checksum=$expected" >> "$GITHUB_OUTPUT"

- name: Install workspace
if: steps.release.outputs.update == 'true'
run: bun install --frozen-lockfile

- name: Sync pinned release
if: steps.release.outputs.update == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
bun run sync:release -- \
--tag "${{ steps.release.outputs.tag }}" \
--expected-manifest-sha256 "${{ steps.release.outputs.checksum }}"
bun install
bun run generate

- name: Validate update
if: steps.release.outputs.update == 'true'
run: |
bun run check
bun run test
git diff --check

- name: Open update pull request
if: steps.release.outputs.update == 'true'
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.release.outputs.tag }}
VERSION: ${{ steps.release.outputs.version }}
run: |
if git diff --quiet; then
exit 0
fi
branch="automation/mobench-release-$VERSION"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git switch -c "$branch"
git add .github apps docs packages scripts tests README.md bun.lock package.json
git commit -m "chore: sync mobench $TAG truth contract"
git push --force-with-lease origin "$branch"
existing="$(gh pr list --head "$branch" --state open --json url --jq '.[0].url // empty')"
if [ -z "$existing" ]; then
gh pr create \
--head "$branch" \
--title "chore: sync mobench $TAG truth contract" \
--body "Pins the tested $TAG release manifest, schemas, fixtures, generated references, and route-independent release copy. Preview deployment and E2E checks remain required before merge."
fi
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
node_modules
dist
.astro
.DS_Store
*.local
.vercel
.env
.env.*
!.env.example
.design-src
playwright-report
test-results
.lighthouseci
*.tsbuildinfo
64 changes: 42 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
# mobench.org

Marketing site and documentation for **mobench** (`mobile-bench-rs`) — an open-source Rust
benchmarking harness that runs your benchmarks on real iOS and Android phones and reports
wall-clock time, peak memory, and energy. Built by [World](https://world.org).
The public website for [mobench](https://github.com/worldcoin/mobile-bench-rs), a Rust toolkit for building mobile benchmark runners, executing ordinary benchmark suites on BrowserStack devices, and producing stable CI reports. The repository publishes two static Astro sites:

## Stack
- `mobench.org` — product education and task entry points.
- `docs.mobench.org` — Starlight documentation, search, references, and examples.

- [TanStack Router](https://tanstack.com/router) (file-based routing, SPA)
- [Vite](https://vite.dev) + React + TypeScript
- [Tailwind CSS v4](https://tailwindcss.com)
- [shadcn/ui](https://ui.shadcn.com) primitives (Button, Accordion)
The current stable documentation targets `mobench 0.1.43`. Use the `mobench` executable in published commands. The `cargo mobench` wrapper is not a supported documentation entry point until its upstream argument-forwarding fix is released and smoke-tested.

## Routes
## Workspace

| Path | Source | Description |
| ------- | ----------------------- | ------------------------------------------------------- |
| `/` | `src/routes/index.tsx` | Landing page — hero, features, benchmarks, FAQ, CTA. |
| `/docs` | `src/routes/docs.tsx` | Documentation app — sidebar nav, 8 pages, right-rail TOC. |
```text
apps/
marketing/ Astro marketing site
docs/ Astro Starlight documentation site
packages/
truth/ Pinned upstream manifest, schema snapshots, and checksums
scripts/ Content, command, routing, and release-sync validation
docs/ Authoring, architecture, release, and deployment runbooks
```

Both pages were imported from the Claude Design project *Mobile Bench landing page design*
(`Mobench Landing.dc.html`, `Mobench Docs.dc.html`) and reimplemented as React.
Both applications render complete HTML at build time. JavaScript is reserved for progressive enhancements such as theme selection, mobile navigation, search, and copy controls.

## Develop

Install [Bun](https://bun.sh/) and Rust only if you are validating upstream examples.

```bash
npm install
npm run dev # http://localhost:3000
bun install --frozen-lockfile
bun run dev:marketing # http://localhost:3000
bun run dev:docs # http://localhost:3001
```

## Build
Do not use npm, pnpm, or Yarn in this repository.

## Validate

```bash
npm run build # outputs to dist/
npm run serve # preview the production build
bun run check
bun run test
bun run build
bun run test:e2e
```

The checks validate MDX frontmatter, aliases, CLI and configuration snippets, upstream version alignment, internal links, generated `llms` files, redirect contracts, static routes, accessibility, and performance budgets. See [Authoring](docs/AUTHORING.md) and [Release sync](docs/RELEASE_SYNC.md) before changing product claims or reference material.

## Deploy

Configured for [Vercel](https://vercel.com) (`vercel.json`): framework preset `vite`, SPA
rewrites so client-side routes resolve to `index.html`.
Create two Vercel projects from this repository, with root directories `apps/marketing` and `apps/docs`. The marketing project owns only marketing routes; the docs project owns only canonical documentation routes. Cross-host duplicates and legacy aliases must return redirects, not duplicate pages.

Preview both projects before production and follow [Deployment and smoke checks](docs/DEPLOYMENT.md). Keep the preceding production deployments available for rollback.

## Source of truth

CLI flags, configuration keys, artifact names, schemas, and capability statements originate in the versioned `mobench-site-manifest-v1.json` release asset generated by `mobile-bench-rs`. This repository pins a release tag, commit SHA, manifest checksum, and schema snapshot. Upstream changes arrive through reviewed update pull requests; production builds never fetch `main`.

To prepare a release update manually, use `bun run sync:release -- --help`. The command requires an explicit tag and trusted manifest checksum; the scheduled watcher uses the same path and opens a review branch rather than updating production directly.

## License

[MIT](LICENSE)
86 changes: 86 additions & 0 deletions apps/docs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { defineConfig } from 'astro/config'
import sitemap from '@astrojs/sitemap'
import starlight from '@astrojs/starlight'

const repository = 'https://github.com/worldcoin/mobile-bench-rs'

export default defineConfig({
site: 'https://docs.mobench.org',
output: 'static',
integrations: [
starlight({
title: 'mobench docs',
disable404Route: true,
description: 'Build, run, and analyze Rust benchmarks on mobile targets.',
favicon: '/favicon.svg',
logo: {
src: './src/assets/logo.svg',
alt: 'mobench',
},
social: [
{ icon: 'github', label: 'GitHub', href: repository },
],
editLink: {
baseUrl: 'https://github.com/worldfnd/mobench.org/edit/main/apps/docs/',
},
lastUpdated: true,
customCss: ['./src/styles/mobench.css'],
components: {
Head: './src/components/Head.astro',
PageTitle: './src/components/PageTitle.astro',
},
sidebar: [
{ label: 'Get started', items: [
{ label: 'Installation', slug: 'installation' },
{ label: 'Quickstart', slug: 'quickstart' },
] },
{ label: 'Write benchmarks', items: [
{ label: 'Benchmark functions', slug: 'benchmark-functions' },
{ label: 'Setup and teardown', slug: 'setup-teardown' },
{ label: 'Benchmark quality', slug: 'benchmark-quality' },
] },
{ label: 'Run benchmarks', items: [
{ label: 'Host-side preflight', slug: 'host-preflight' },
{ label: 'BrowserStack devices', slug: 'browserstack' },
{ label: 'CI runs', slug: 'ci' },
] },
{ label: 'Analyze results', items: [
{ label: 'Outputs and metrics', slug: 'outputs' },
{ label: 'Regression comparison', slug: 'regressions' },
{ label: 'Local native profiling', slug: 'profiling' },
] },
{ label: 'Reference', items: [
{ label: 'CLI', slug: 'cli' },
{ label: 'Configuration', slug: 'configuration' },
{ label: 'Device matrices', slug: 'device-matrices' },
{ label: 'Output schemas', slug: 'schemas' },
{ label: 'Compatibility', slug: 'compatibility' },
] },
{ label: 'Examples', items: [
{ label: 'Basic benchmark', slug: 'basic-example' },
{ label: 'FFI benchmark', slug: 'ffi-example' },
] },
{ label: 'Help', items: [
{ label: 'Troubleshooting', slug: 'troubleshooting' },
] },
],
head: [
{
tag: 'script',
attrs: { type: 'application/ld+json' },
content: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'SoftwareSourceCode',
name: 'mobench',
codeRepository: repository,
programmingLanguage: 'Rust',
runtimePlatform: ['Android', 'iOS'],
}),
},
],
}),
sitemap(),
],
build: { format: 'directory' },
compressHTML: true,
})
24 changes: 24 additions & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@mobench/docs",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev --port 3001",
"build": "astro build",
"check": "astro check",
"preview": "astro preview --port 3001"
},
"dependencies": {
"@astrojs/sitemap": "^3.7.3",
"@astrojs/starlight": "^0.41.3",
"@mobench/site-config": "workspace:*",
"@vercel/analytics": "2.0.1",
"astro": "7.0.6",
"sharp": "0.35.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.6",
"typescript": "^6.0.3"
}
}
1 change: 1 addition & 0 deletions apps/docs/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading