diff --git a/desktop/.github/workflows/e2e.yaml b/.github/workflows/desktop-e2e.yml similarity index 72% rename from desktop/.github/workflows/e2e.yaml rename to .github/workflows/desktop-e2e.yml index 2585f0d13..d8e68d101 100644 --- a/desktop/.github/workflows/e2e.yaml +++ b/.github/workflows/desktop-e2e.yml @@ -1,3 +1,4 @@ +name: desktop-e2e on: pull_request: push: @@ -6,6 +7,10 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true +defaults: + run: + working-directory: desktop + jobs: e2e: runs-on: ubuntu-latest @@ -16,7 +21,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: - node-version-file: ".nvmrc" + node-version-file: "desktop/.nvmrc" - run: | apt-get update && apt-get install -y --no-install-recommends \ @@ -31,14 +36,17 @@ jobs: libjavascriptcoregtk-4.1-dev \ openssh-client - run: npm ci - - uses: dtolnay/rust-toolchain@stable + # The version in desktop/rust-toolchain.toml, which cargo uses here. + - uses: dtolnay/rust-toolchain@1.97.1 - uses: Swatinem/rust-cache@v2 + with: + workspaces: desktop - name: Cache heartwood binaries uses: actions/cache@v5 with: - path: tests/tmp/bin - key: heartwood-${{ hashFiles('tests/support/heartwood-release') }} + path: desktop/tests/tmp/bin + key: heartwood-${{ hashFiles('desktop/tests/support/heartwood-release') }} - run: scripts/install-binaries - run: npm run build:http @@ -53,6 +61,6 @@ jobs: if: ${{ !cancelled() }} uses: actions/upload-artifact@v6 with: - name: e2e-artifacts - path: tests/artifacts + name: desktop-e2e-artifacts + path: desktop/tests/artifacts retention-days: 7 diff --git a/desktop/.github/workflows/lint.yaml b/.github/workflows/desktop-lint.yml similarity index 73% rename from desktop/.github/workflows/lint.yaml rename to .github/workflows/desktop-lint.yml index c9d43863a..299fb413e 100644 --- a/desktop/.github/workflows/lint.yaml +++ b/.github/workflows/desktop-lint.yml @@ -1,3 +1,4 @@ +name: desktop-lint on: pull_request: push: @@ -6,6 +7,10 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true +defaults: + run: + working-directory: desktop + jobs: lint-typescript: runs-on: ubuntu-latest @@ -14,7 +19,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: - node-version-file: ".nvmrc" + node-version-file: "desktop/.nvmrc" - run: npm ci - run: npm run check-js @@ -33,9 +38,12 @@ jobs: libwebkit2gtk-4.1-dev \ libjavascriptcoregtk-4.1-dev - - uses: dtolnay/rust-toolchain@stable + # The version in desktop/rust-toolchain.toml, which cargo uses here. + - uses: dtolnay/rust-toolchain@1.97.1 with: components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 + with: + workspaces: desktop - run: scripts/check-rs diff --git a/desktop/.github/workflows/unit-test.yaml b/.github/workflows/desktop-unit-test.yml similarity index 71% rename from desktop/.github/workflows/unit-test.yaml rename to .github/workflows/desktop-unit-test.yml index e71a02c93..3a6d5d162 100644 --- a/desktop/.github/workflows/unit-test.yaml +++ b/.github/workflows/desktop-unit-test.yml @@ -1,3 +1,4 @@ +name: desktop-unit-test on: pull_request: push: @@ -6,6 +7,10 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true +defaults: + run: + working-directory: desktop + jobs: unit-tests: runs-on: ubuntu-latest @@ -14,6 +19,6 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: - node-version-file: ".nvmrc" + node-version-file: "desktop/.nvmrc" - run: npm ci - run: npm run test:unit diff --git a/desktop/.ryph/Dockerfile b/.ryph/Dockerfile similarity index 76% rename from desktop/.ryph/Dockerfile rename to .ryph/Dockerfile index 6068b206d..b1f8d446d 100644 --- a/desktop/.ryph/Dockerfile +++ b/.ryph/Dockerfile @@ -2,8 +2,8 @@ FROM ghcr.io/drips-network/ryph-universal:1 USER root -# Tauri's system libraries (radicle-desktop's cargo build, clippy and tests), -# and bzip2 for radicle-explorer's .tar.bz2 test fixtures. +# Tauri's system libraries (desktop/'s cargo build, clippy and tests), and +# bzip2 for the explorer's .tar.bz2 test fixtures. RUN apt-get update \ && apt-get install -y --no-install-recommends \ libwebkit2gtk-4.1-dev \ @@ -14,8 +14,8 @@ RUN apt-get update \ bzip2 \ && rm -rf /var/lib/apt/lists/* -# The OS libraries Playwright's browsers need: WebKit for radicle-desktop's e2e -# tests, Chromium and WebKit for radicle-explorer's and always-on-node's. The +# The OS libraries Playwright's browsers need: WebKit for desktop/'s e2e tests, +# Chromium and WebKit for the explorer's and always-on-node's. The # browsers themselves are installed by each member's setup, keyed on its lockfile. RUN npx -y playwright@1.61.1 install-deps chromium webkit \ && rm -rf /var/lib/apt/lists/* /root/.npm \ @@ -33,7 +33,7 @@ USER runner # instead of using the image's newer Go. ENV MISE_IDIOMATIC_VERSION_FILE_ENABLE_TOOLS=node,python,deno,bun -# Debug info is most of a warm target/ (8 GB of radicle-desktop's 13). Line +# Debug info is most of a warm target/ (8 GB of desktop/'s 13). Line # tables keep file:line in panics and backtraces. Set for the whole machine, # so the image's warm build and every run's builds use the same profile. ENV CARGO_PROFILE_DEV_DEBUG=line-tables-only diff --git a/.ryph/environment.md b/.ryph/environment.md index 9d2a9fbb2..567f48f1f 100644 --- a/.ryph/environment.md +++ b/.ryph/environment.md @@ -1,13 +1,39 @@ -# radicle-explorer environment +# radicle-gui environment + +This repository holds two projects: the explorer web app and `radicle-httpd` +at the root, and the desktop app in `desktop/`. Each has its own npm package +and Cargo workspace. + +`.ryph/Dockerfile` is written as the machine for the whole Radicle +workspace, and a workspace builds only its environment repository's +Dockerfile: the description of the machine above says which one this run +is on. On top of the universal image it adds: + +- Tauri's system libraries (`libwebkit2gtk-4.1-dev`, + `libjavascriptcoregtk-4.1-dev`, `libayatana-appindicator3-dev`, + `librsvg2-dev`, `libxdo-dev`), so the desktop crates build here; +- the OS libraries Playwright's Chromium and WebKit need, and `bzip2`; +- `golangci-lint` v2.14.0 in `/usr/local/bin`, for garden-broker; +- `MISE_IDIOMATIC_VERSION_FILE_ENABLE_TOOLS=node,python,deno,bun`, so mise + does not read a `go.mod` `go` line as a pin: Go is the image's own. +- `CARGO_PROFILE_DEV_DEBUG=line-tables-only`: dev and test builds carry + line tables, not full debug info. Backtraces keep file and line. Do not + override it, or every crate rebuilds. `.ryph/setup.yml` installs the npm dependencies and the pinned Radicle -binaries (`tests/tmp/bin`), and warms clippy and the Rust test build in -`target/`. Node 24.15.0 (`.nvmrc`) and Rust 1.97.1 (`rust-toolchain`) come -from mise and rustup. The machine itself, from radicle-desktop's Dockerfile, -carries Playwright's OS libraries and `bzip2`. +binaries (`tests/tmp/bin`, `desktop/tests/tmp/bin`) for both projects, +Playwright's Chromium for the explorer and its WebKit for the desktop app. +At image build it warms clippy and the Rust test builds of both workspaces, +and the desktop e2e backend (`test-http-api`, `rad-job`), in `target/` and +`desktop/target/`. At run start it only reinstalls what the lockfiles +changed, and cargo builds what a command needs when it runs. Node 24.15.0 +(`.nvmrc`) and Rust 1.97.1 (`rust-toolchain`, `desktop/rust-toolchain.toml`) +come from mise and rustup. ## Checks (what CI runs) +Explorer and `radicle-httpd`, from the repository root: + ```sh npm run check npm run test:unit @@ -18,11 +44,24 @@ cargo fmt --all -- --check cargo test --workspace --all-features cargo test -p radicle-httpd RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features +npm run test:e2e -- --project chromium ``` +Desktop, from `desktop/`: + +```sh +npm run check-js # svelte-check, eslint, prettier +scripts/check-rs # cargo fmt --check, clippy -Dwarnings, cargo test +npm run test:unit +npm run test:e2e # WebKit; needs scripts/install-binaries, done by setup +``` + +In `desktop/`, `npm run check:ci` runs all of the desktop checks in order and +logs to `desktop/tests/tmp/check-ci.log`. The machine has 2 CPUs: the Rust +test builds and the e2e suites are the slow parts. + ## What does not work here -- `npm run test:e2e -- --project chromium` and the build smoke test: Playwright's - Chromium download redirects to `storage.googleapis.com`, which the egress - allowlist refuses. Leave e2e to CI. -- Visual tests: their baselines exist only as CI artifacts. +- The explorer's visual tests: their baselines exist only as CI artifacts. +- There is no container runtime, so nothing that runs `docker` or `podman` + works (always-on-node's `pnpm test:e2e`, garden-broker's integration tests). diff --git a/.ryph/setup.yml b/.ryph/setup.yml index dfd40cc1b..39b0d51b1 100644 --- a/.ryph/setup.yml +++ b/.ryph/setup.yml @@ -1,20 +1,32 @@ steps: - # An image layer keeps whole-second mtimes, but cargo fingerprints the - # nanoseconds it saw at build time. Rounding tracked files down to the - # second before building keeps the warm target/ fresh at run time. Never - # set them to the commit time: on an incremental image build that can make - # a changed file older than its stale build output. - - name: round source mtimes down to whole seconds (image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || git ls-files -z | xargs -0 perl -e ''for (@ARGV) { next if -l; my $m = (lstat)[9]; utime $m, $m, $_ }''' + # Explorer and radicle-httpd, at the repository root. - name: install npm dependencies run: npm install --prefer-offline + - name: install Playwright Chromium (explorer e2e) + run: npx playwright install chromium - name: install the pinned Radicle binaries for http-client and e2e tests run: ./scripts/install-binaries - - name: warm clippy (check-rust lint) - run: RUSTFLAGS="-D warnings" cargo clippy --workspace --all-features --tests --locked - - name: warm the Rust test build (check-rust test) - run: cargo test --workspace --all-features --no-run --locked + # The cargo warm steps only fill the image's target/ directories. At run + # time cargo builds what a command needs when it runs, so a run that works + # on another workspace member doesn't wait for two Rust workspaces. + - name: warm clippy (check-rust lint, image builds only) + run: '[ "$RYPH_SETUP_PHASE" != image ] || RUSTFLAGS="-D warnings" cargo clippy --workspace --all-features --tests --locked' + - name: warm the Rust test build (check-rust test, image builds only) + run: '[ "$RYPH_SETUP_PHASE" != image ] || cargo test --workspace --all-features --no-run --locked' + # desktop/ is its own npm package and Cargo workspace. + - name: install desktop npm dependencies + run: cd desktop && npm install --prefer-offline + - name: install Playwright WebKit (desktop e2e) + run: cd desktop && npx playwright install webkit + - name: install the pinned Radicle binaries for desktop e2e tests + run: desktop/scripts/install-binaries + - name: warm desktop clippy (desktop/scripts/check-rs, image builds only) + run: 'cd desktop && mkdir -p build && { [ "$RYPH_SETUP_PHASE" != image ] || cargo clippy --workspace --all-targets --locked; }' + - name: warm desktop cargo test (desktop/scripts/check-rs, image builds only) + run: 'cd desktop && { [ "$RYPH_SETUP_PHASE" != image ] || cargo test --workspace --no-run --locked; }' + - name: warm the desktop e2e backend (desktop/tests/support/globalSetup.ts, image builds only) + run: 'cd desktop && { [ "$RYPH_SETUP_PHASE" != image ] || { cargo build --manifest-path ./crates/test-http-api/Cargo.toml --locked && cargo build -p radicle-job --bin rad-job --locked; }; }' # rustc's incremental cache only speeds up rebuilding this repo's own # crates after an edit, and it is gigabytes. Image builds only. - - name: drop the incremental cache (image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || rm -rf target/debug/incremental' + - name: drop the incremental caches (image builds only) + run: '[ "$RYPH_SETUP_PHASE" != image ] || rm -rf target/debug/incremental desktop/target/debug/incremental' diff --git a/desktop/.ryph/environment.md b/desktop/.ryph/environment.md deleted file mode 100644 index 640217f20..000000000 --- a/desktop/.ryph/environment.md +++ /dev/null @@ -1,43 +0,0 @@ -# radicle-desktop environment - -This repository's `.ryph/Dockerfile` is the machine for the whole Radicle -workspace. On top of the universal image it adds: - -- Tauri's system libraries (`libwebkit2gtk-4.1-dev`, - `libjavascriptcoregtk-4.1-dev`, `libayatana-appindicator3-dev`, - `librsvg2-dev`, `libxdo-dev`), so the Rust crates build here; -- the OS libraries Playwright's Chromium and WebKit need, and `bzip2`; -- `golangci-lint` v2.14.0 in `/usr/local/bin`, for garden-broker; -- `MISE_IDIOMATIC_VERSION_FILE_ENABLE_TOOLS=node,python,deno,bun`, so mise - does not read a `go.mod` `go` line as a pin: Go is the image's own. -- `CARGO_PROFILE_DEV_DEBUG=line-tables-only`: dev and test builds carry - line tables, not full debug info. Backtraces keep file and line. Do not - override it, or every crate rebuilds. - -`.ryph/setup.yml` installs the npm dependencies, Playwright's WebKit and the -pinned Radicle binaries (`tests/tmp/bin`), and warms clippy, the test build -and the e2e backend (`test-http-api`, `rad-job`) in `target/`. Node 24.15.0 -(`.nvmrc`) and Rust 1.97.1 (`rust-toolchain.toml`) are installed by mise and -rustup on first use. - -## Checks (what CI runs) - -```sh -npm run check-js # svelte-check, eslint, prettier -scripts/check-rs # cargo fmt --check, clippy -Dwarnings, cargo test -npm run test:unit -npm run test:e2e # WebKit; needs scripts/install-binaries, done by setup -``` - -`npm run check:ci` runs all of them in order and logs to -`tests/tmp/check-ci.log`. The machine has 2 CPUs: the Rust test build and the -e2e suite are the slow parts. - -## What does not work here - -- Chromium cannot be installed by Playwright: its download redirects to - `storage.googleapis.com`, which the egress allowlist refuses. This app's - e2e tests use WebKit only and are unaffected; radicle-explorer's and - always-on-node's Chromium e2e tests are. -- There is no container runtime, so nothing that runs `docker` or `podman` - works (always-on-node's `pnpm test:e2e`, garden-broker's integration tests). diff --git a/desktop/.ryph/setup.yml b/desktop/.ryph/setup.yml deleted file mode 100644 index 3bd3c8bf7..000000000 --- a/desktop/.ryph/setup.yml +++ /dev/null @@ -1,26 +0,0 @@ -steps: - # An image layer keeps whole-second mtimes, but cargo fingerprints the - # nanoseconds it saw at build time. Rounding tracked files down to the - # second before building keeps the warm target/ fresh at run time. Never - # set them to the commit time: on an incremental image build that can make - # a changed file older than its stale build output. - - name: round source mtimes down to whole seconds (image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || git ls-files -z | xargs -0 perl -e ''for (@ARGV) { next if -l; my $m = (lstat)[9]; utime $m, $m, $_ }''' - - name: install npm dependencies - run: npm install --prefer-offline - - name: install Playwright WebKit - run: npx playwright install webkit - - name: install the pinned Radicle binaries for e2e tests - run: scripts/install-binaries - # The cargo warm steps only fill the image's target/. At run time cargo - # builds what a command needs when it runs. - - name: warm clippy (scripts/check-rs, image builds only) - run: 'mkdir -p build && { [ "$RYPH_SETUP_PHASE" != image ] || cargo clippy --workspace --all-targets --locked; }' - - name: warm cargo test (scripts/check-rs, image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || cargo test --workspace --no-run --locked' - - name: warm the e2e backend (tests/support/globalSetup.ts, image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || { cargo build --manifest-path ./crates/test-http-api/Cargo.toml --locked && cargo build -p radicle-job --bin rad-job --locked; }' - # rustc's incremental cache only speeds up rebuilding this repo's own - # crates after an edit, and it is gigabytes. Image builds only. - - name: drop the incremental cache (image builds only) - run: '[ "$RYPH_SETUP_PHASE" != image ] || rm -rf target/debug/incremental'