mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
build: unify project development commands
This commit is contained in:
28
.github/workflows/apple.yml
vendored
28
.github/workflows/apple.yml
vendored
@@ -8,6 +8,9 @@ on:
|
|||||||
- "crates/uniffi-bindgen/**"
|
- "crates/uniffi-bindgen/**"
|
||||||
- "Cargo.toml"
|
- "Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/apple.yml"
|
- ".github/workflows/apple.yml"
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -18,6 +21,9 @@ on:
|
|||||||
- "crates/uniffi-bindgen/**"
|
- "crates/uniffi-bindgen/**"
|
||||||
- "Cargo.toml"
|
- "Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/apple.yml"
|
- ".github/workflows/apple.yml"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -57,23 +63,5 @@ jobs:
|
|||||||
- name: Install XcodeGen
|
- name: Install XcodeGen
|
||||||
run: brew install xcodegen
|
run: brew install xcodegen
|
||||||
|
|
||||||
- name: Build Rust core (xcframework + Swift bindings)
|
- name: Build and test Apple app
|
||||||
working-directory: apple
|
run: make check-apple
|
||||||
run: ./scripts/build-core.sh debug
|
|
||||||
|
|
||||||
- name: Generate Xcode project
|
|
||||||
working-directory: apple
|
|
||||||
run: xcodegen generate
|
|
||||||
|
|
||||||
- name: Run unit tests (iOS Simulator)
|
|
||||||
working-directory: apple
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
DEVICE=$(xcrun simctl list devices available \
|
|
||||||
| grep -oE 'iPhone [0-9]+( Pro)?' | head -1)
|
|
||||||
echo "Testing on: ${DEVICE:-iPhone 16}"
|
|
||||||
xcodebuild test \
|
|
||||||
-project VniDrop.xcodeproj \
|
|
||||||
-scheme VniDrop \
|
|
||||||
-destination "platform=iOS Simulator,name=${DEVICE:-iPhone 16}" \
|
|
||||||
CODE_SIGNING_ALLOWED=NO
|
|
||||||
|
|||||||
25
.github/workflows/diagnostics-api.yml
vendored
25
.github/workflows/diagnostics-api.yml
vendored
@@ -4,12 +4,18 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "services/diagnostics-api/**"
|
- "services/diagnostics-api/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/diagnostics-api.yml"
|
- ".github/workflows/diagnostics-api.yml"
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- "services/diagnostics-api/**"
|
- "services/diagnostics-api/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/diagnostics-api.yml"
|
- ".github/workflows/diagnostics-api.yml"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -23,9 +29,6 @@ jobs:
|
|||||||
quality:
|
quality:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: services/diagnostics-api
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -37,17 +40,5 @@ jobs:
|
|||||||
cache: npm
|
cache: npm
|
||||||
cache-dependency-path: services/diagnostics-api/package-lock.json
|
cache-dependency-path: services/diagnostics-api/package-lock.json
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Check diagnostics API
|
||||||
run: npm ci
|
run: make check-diagnostics
|
||||||
|
|
||||||
- name: Verify generated Worker types
|
|
||||||
run: npm run types:check
|
|
||||||
|
|
||||||
- name: Type-check
|
|
||||||
run: npm run typecheck
|
|
||||||
|
|
||||||
- name: Test in the Workers runtime
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
- name: Validate the deployment bundle
|
|
||||||
run: npm run deploy:dry-run
|
|
||||||
|
|||||||
19
.github/workflows/docs.yml
vendored
19
.github/workflows/docs.yml
vendored
@@ -4,12 +4,18 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/docs.yml"
|
- ".github/workflows/docs.yml"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -23,9 +29,6 @@ jobs:
|
|||||||
quality:
|
quality:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: docs
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -37,11 +40,5 @@ jobs:
|
|||||||
cache: npm
|
cache: npm
|
||||||
cache-dependency-path: docs/package-lock.json
|
cache-dependency-path: docs/package-lock.json
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Check documentation website
|
||||||
run: npm ci
|
run: make check-docs
|
||||||
|
|
||||||
- name: Type-check
|
|
||||||
run: npm run typecheck
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: npm run build
|
|
||||||
|
|||||||
65
.github/workflows/linux-packages.yml
vendored
65
.github/workflows/linux-packages.yml
vendored
@@ -17,6 +17,9 @@ on:
|
|||||||
- "gradle.properties"
|
- "gradle.properties"
|
||||||
- "gradle/**"
|
- "gradle/**"
|
||||||
- "gradlew"
|
- "gradlew"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- "v*.*.*"
|
- "v*.*.*"
|
||||||
@@ -92,37 +95,7 @@ jobs:
|
|||||||
echo "app=$version" >> "$GITHUB_OUTPUT"
|
echo "app=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Test and build Debian package
|
- name: Test and build Debian package
|
||||||
run: |
|
run: make package-deb VERSION=${{ steps.version.outputs.app }}
|
||||||
./gradlew \
|
|
||||||
:shared:jvmTest \
|
|
||||||
:desktopApp:packageReleaseDeb \
|
|
||||||
-Pvnidrop.version=${{ steps.version.outputs.app }} \
|
|
||||||
-Pvnidrop.desktop.rustVariant=release \
|
|
||||||
-Pvnidrop.diagnostics.included=false \
|
|
||||||
--no-daemon \
|
|
||||||
--no-configuration-cache \
|
|
||||||
--stacktrace
|
|
||||||
|
|
||||||
- name: Validate Debian package
|
|
||||||
id: package
|
|
||||||
env:
|
|
||||||
VERSION: ${{ steps.version.outputs.app }}
|
|
||||||
run: |
|
|
||||||
mapfile -t packages < <(find desktopApp/build/compose/binaries/main-release/deb -maxdepth 1 -type f -name '*.deb')
|
|
||||||
if (( ${#packages[@]} != 1 )); then
|
|
||||||
echo "Expected exactly one Debian package, found ${#packages[@]}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
output_directory=build/release/linux/deb
|
|
||||||
output_name="vnidrop_${VERSION}-1_amd64.deb"
|
|
||||||
mkdir -p "$output_directory"
|
|
||||||
cp "${packages[0]}" "$output_directory/$output_name"
|
|
||||||
packaging/linux/verify-package.sh deb "$VERSION" "$output_directory/$output_name"
|
|
||||||
(
|
|
||||||
cd "$output_directory"
|
|
||||||
sha256sum "$output_name" > "$output_name.sha256"
|
|
||||||
)
|
|
||||||
|
|
||||||
- name: Upload Debian artifact
|
- name: Upload Debian artifact
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
@@ -225,35 +198,7 @@ jobs:
|
|||||||
echo "app=$version" >> "$GITHUB_OUTPUT"
|
echo "app=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Build RPM package
|
- name: Build RPM package
|
||||||
run: |
|
run: make package-rpm VERSION=${{ steps.version.outputs.app }}
|
||||||
./gradlew \
|
|
||||||
:desktopApp:packageReleaseRpm \
|
|
||||||
-Pvnidrop.version=${{ steps.version.outputs.app }} \
|
|
||||||
-Pvnidrop.desktop.rustVariant=release \
|
|
||||||
-Pvnidrop.diagnostics.included=false \
|
|
||||||
--no-daemon \
|
|
||||||
--no-configuration-cache \
|
|
||||||
--stacktrace
|
|
||||||
|
|
||||||
- name: Validate RPM package
|
|
||||||
env:
|
|
||||||
VERSION: ${{ steps.version.outputs.app }}
|
|
||||||
run: |
|
|
||||||
mapfile -t packages < <(find desktopApp/build/compose/binaries/main-release/rpm -maxdepth 1 -type f -name '*.rpm')
|
|
||||||
if (( ${#packages[@]} != 1 )); then
|
|
||||||
echo "Expected exactly one RPM package, found ${#packages[@]}" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
output_directory=build/release/linux/rpm
|
|
||||||
output_name="vnidrop-${VERSION}-1.x86_64.rpm"
|
|
||||||
mkdir -p "$output_directory"
|
|
||||||
cp "${packages[0]}" "$output_directory/$output_name"
|
|
||||||
packaging/linux/verify-package.sh rpm "$VERSION" "$output_directory/$output_name"
|
|
||||||
(
|
|
||||||
cd "$output_directory"
|
|
||||||
sha256sum "$output_name" > "$output_name.sha256"
|
|
||||||
)
|
|
||||||
|
|
||||||
- name: Upload RPM artifact
|
- name: Upload RPM artifact
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
|
|||||||
20
.github/workflows/rust-core.yml
vendored
20
.github/workflows/rust-core.yml
vendored
@@ -6,6 +6,9 @@ on:
|
|||||||
- "Cargo.toml"
|
- "Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
- "crates/vnidrop/**"
|
- "crates/vnidrop/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/rust-core.yml"
|
- ".github/workflows/rust-core.yml"
|
||||||
push:
|
push:
|
||||||
# Only after merge (or direct master pushes). Feature-branch work is covered
|
# Only after merge (or direct master pushes). Feature-branch work is covered
|
||||||
@@ -16,6 +19,9 @@ on:
|
|||||||
- "Cargo.toml"
|
- "Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
- "crates/vnidrop/**"
|
- "crates/vnidrop/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/rust-core.yml"
|
- ".github/workflows/rust-core.yml"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -33,18 +39,10 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install Rust quality components
|
- name: Install Rust quality components
|
||||||
run: rustup component add clippy rustfmt
|
run: rustup component add clippy rustfmt
|
||||||
- name: Check formatting
|
- name: Check Rust core
|
||||||
run: cargo fmt --all -- --check
|
run: make check-rust
|
||||||
- name: Run strict Clippy
|
|
||||||
run: cargo clippy --workspace --all-targets -- -D warnings
|
|
||||||
- name: Run unit and integration tests
|
|
||||||
run: cargo test --workspace --all-targets
|
|
||||||
- name: Check documentation
|
|
||||||
env:
|
|
||||||
RUSTDOCFLAGS: -D warnings
|
|
||||||
run: cargo doc --workspace --no-deps
|
|
||||||
- name: Install cargo-audit
|
- name: Install cargo-audit
|
||||||
run: cargo install cargo-audit --locked
|
run: cargo install cargo-audit --locked
|
||||||
- name: Audit Rust dependencies
|
- name: Audit Rust dependencies
|
||||||
# Ignores are listed in .cargo/audit.toml for known transitive issues.
|
# Ignores are listed in .cargo/audit.toml for known transitive issues.
|
||||||
run: cargo audit
|
run: make audit-rust
|
||||||
|
|||||||
10
.github/workflows/shared-kmp.yml
vendored
10
.github/workflows/shared-kmp.yml
vendored
@@ -15,6 +15,9 @@ on:
|
|||||||
- "gradle.properties"
|
- "gradle.properties"
|
||||||
- "androidApp/**"
|
- "androidApp/**"
|
||||||
- "desktopApp/**"
|
- "desktopApp/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/shared-kmp.yml"
|
- ".github/workflows/shared-kmp.yml"
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -32,6 +35,9 @@ on:
|
|||||||
- "gradle.properties"
|
- "gradle.properties"
|
||||||
- "androidApp/**"
|
- "androidApp/**"
|
||||||
- "desktopApp/**"
|
- "desktopApp/**"
|
||||||
|
- "Makefile"
|
||||||
|
- "config.mk"
|
||||||
|
- "make/**"
|
||||||
- ".github/workflows/shared-kmp.yml"
|
- ".github/workflows/shared-kmp.yml"
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -94,7 +100,7 @@ jobs:
|
|||||||
echo "ANDROID_NDK_ROOT=${{ steps.setup-ndk.outputs.ndk-path }}" >> "$GITHUB_ENV"
|
echo "ANDROID_NDK_ROOT=${{ steps.setup-ndk.outputs.ndk-path }}" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: Run shared JVM tests
|
- name: Run shared JVM tests
|
||||||
run: ./gradlew :shared:jvmTest --no-daemon --stacktrace
|
run: make check-shared
|
||||||
|
|
||||||
- name: Verify Android native libraries
|
- name: Verify Android native libraries
|
||||||
run: ./gradlew :androidApp:verifyDebugVnidropLibraries --no-daemon --stacktrace
|
run: make verify-android-libs
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,6 +19,7 @@ captures
|
|||||||
node_modules/
|
node_modules/
|
||||||
target/
|
target/
|
||||||
.junie
|
.junie
|
||||||
|
config.override.mk
|
||||||
|
|
||||||
# Local design export scratch
|
# Local design export scratch
|
||||||
output/
|
output/
|
||||||
|
|||||||
39
AGENTS.md
39
AGENTS.md
@@ -53,7 +53,7 @@ Domain docs (reference, do not paste into PRs):
|
|||||||
|
|
||||||
## Build and test
|
## Build and test
|
||||||
|
|
||||||
Install prerequisites when missing: Rust stable + rustfmt + clippy, JDK 17,
|
Install prerequisites when missing: GNU Make + Bash, Rust stable + rustfmt + clippy, JDK 17,
|
||||||
Android NDK/SDK only if building Android, Xcode only for the native Apple app.
|
Android NDK/SDK only if building Android, Xcode only for the native Apple app.
|
||||||
|
|
||||||
### Rust core (`crates/vnidrop` or workspace root)
|
### Rust core (`crates/vnidrop` or workspace root)
|
||||||
@@ -61,43 +61,40 @@ Android NDK/SDK only if building Android, Xcode only for the native Apple app.
|
|||||||
Run from the **repo root** (Cargo workspace):
|
Run from the **repo root** (Cargo workspace):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all -- --check
|
make check-rust
|
||||||
cargo clippy --workspace --all-targets -- -D warnings
|
|
||||||
cargo test --workspace --all-targets
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Focused:
|
Focused:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test -p vnidrop
|
make test-rust
|
||||||
cargo test -p vnidrop --test output_sink
|
make test-rust-output-sink
|
||||||
cargo test -p vnidrop --test transfer
|
make test-rust-transfer
|
||||||
cargo test -p vnidrop --test approval
|
make test-rust-approval
|
||||||
cargo test -p vnidrop --test lifecycle
|
make test-rust-lifecycle
|
||||||
```
|
```
|
||||||
|
|
||||||
After finishing Rust edits, format:
|
After finishing Rust edits, format:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all
|
make format
|
||||||
```
|
```
|
||||||
|
|
||||||
CI also runs `cargo doc --workspace --no-deps` with `RUSTDOCFLAGS=-D warnings`
|
`make check-rust` includes documentation with warnings denied, matching
|
||||||
(see `.github/workflows/rust-core.yml`). Run it before large Rust public-API changes.
|
`.github/workflows/rust-core.yml`.
|
||||||
|
|
||||||
### Shared KMP / Compose (`shared/`)
|
### Shared KMP / Compose (`shared/`)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:jvmTest
|
make check-shared
|
||||||
./gradlew :shared:compileKotlinJvm
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Other targets (slower / machine-dependent):
|
Other targets (slower / machine-dependent):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:testAndroidHostTest
|
make test-android-host
|
||||||
./gradlew :androidApp:assembleDebug
|
make check-android
|
||||||
./gradlew :desktopApp:run
|
make run-desktop
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** `jvmTest` CI runs on **Linux**. Gobley host cargo is enabled for the
|
**Note:** `jvmTest` CI runs on **Linux**. Gobley host cargo is enabled for the
|
||||||
@@ -108,10 +105,10 @@ Rust library.
|
|||||||
|
|
||||||
| You changed… | Minimum verification |
|
| You changed… | Minimum verification |
|
||||||
|--------------|----------------------|
|
|--------------|----------------------|
|
||||||
| `crates/vnidrop/**` only | `cargo fmt`, `cargo clippy … -D warnings`, `cargo test -p vnidrop` |
|
| `crates/vnidrop/**` only | `make check-rust` |
|
||||||
| Cancel / export / sinks | Above + `cargo test -p vnidrop --test output_sink` |
|
| Cancel / export / sinks | Above + `make test-rust-output-sink` |
|
||||||
| `shared/**` only | `./gradlew :shared:jvmTest` |
|
| `shared/**` only | `make test-shared` |
|
||||||
| Both | Rust suite + `:shared:jvmTest` |
|
| Both | `make test-rust test-shared` |
|
||||||
| Docs only | No suite required; verify links/paths |
|
| Docs only | No suite required; verify links/paths |
|
||||||
|
|
||||||
Do not kill long `cargo` / Gradle runs mid-flight unless they hang past several
|
Do not kill long `cargo` / Gradle runs mid-flight unless they hang past several
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ Use a branch name that describes the outcome, such as
|
|||||||
|
|
||||||
Install the tools needed for the area you plan to change:
|
Install the tools needed for the area you plan to change:
|
||||||
|
|
||||||
|
- GNU Make and Bash for the root command interface
|
||||||
- JDK 17 or newer for Gradle and application builds
|
- JDK 17 or newer for Gradle and application builds
|
||||||
- Rust stable with `rustfmt` and Clippy for the transfer core
|
- Rust stable with `rustfmt` and Clippy for the transfer core
|
||||||
- Android SDK and NDK for Android builds
|
- Android SDK and NDK for Android builds
|
||||||
@@ -44,6 +45,25 @@ Install the tools needed for the area you plan to change:
|
|||||||
The first Rust and Gradle builds may take several minutes while dependencies are
|
The first Rust and Gradle builds may take several minutes while dependencies are
|
||||||
downloaded and native components are compiled.
|
downloaded and native components are compiled.
|
||||||
|
|
||||||
|
## Command Interface
|
||||||
|
|
||||||
|
Run development commands through the root `Makefile`. It keeps local and CI
|
||||||
|
commands aligned while continuing to delegate builds to Cargo, Gradle, Xcode,
|
||||||
|
Bun, and npm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make help # list commands
|
||||||
|
make doctor # report missing host tools
|
||||||
|
make setup # install repository-local JavaScript dependencies
|
||||||
|
make check # portable Rust, shared, localization, docs, and service checks
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration can be passed on the command line, for example
|
||||||
|
`make package-deb VERSION=1.2.0`, or placed in an ignored
|
||||||
|
`config.override.mk`. Windows use requires GNU Make in a Bash environment; the
|
||||||
|
underlying Gradle and PowerShell entry points remain available when Make is not
|
||||||
|
installed.
|
||||||
|
|
||||||
## Repository Structure
|
## Repository Structure
|
||||||
|
|
||||||
| Path | Purpose |
|
| Path | Purpose |
|
||||||
@@ -87,55 +107,48 @@ Run checks from the repository root. Choose the suite for the files you changed.
|
|||||||
### Rust Core
|
### Rust Core
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all
|
make format
|
||||||
cargo clippy --workspace --all-targets -- -D warnings
|
make test-rust
|
||||||
cargo test -p vnidrop
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For cancel, export, or output-sink changes, also run:
|
For cancel, export, or output-sink changes, also run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test -p vnidrop --test output_sink
|
make test-rust-output-sink
|
||||||
```
|
```
|
||||||
|
|
||||||
For broader core changes, run the complete workspace suite:
|
For broader core changes, run the complete workspace suite:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test --workspace --all-targets
|
make check-rust
|
||||||
```
|
```
|
||||||
|
|
||||||
### Shared Kotlin and Compose
|
### Shared Kotlin and Compose
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:jvmTest
|
make test-shared
|
||||||
```
|
```
|
||||||
|
|
||||||
Platform-specific checks may also be appropriate:
|
Platform-specific checks may also be appropriate:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:testAndroidHostTest
|
make test-android-host
|
||||||
./gradlew :androidApp:assembleDebug
|
make check-android
|
||||||
```
|
```
|
||||||
|
|
||||||
### Native Apple App
|
### Native Apple App
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd apple
|
make check-apple
|
||||||
./scripts/build-core.sh debug
|
|
||||||
xcodegen generate
|
|
||||||
xcodebuild test \
|
|
||||||
-project VniDrop.xcodeproj \
|
|
||||||
-scheme VniDrop \
|
|
||||||
-destination 'platform=iOS Simulator,name=iPhone 16' \
|
|
||||||
CODE_SIGNING_ALLOWED=NO
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Override the selected simulator when needed with
|
||||||
|
`make check-apple APPLE_DESTINATION='platform=iOS Simulator,name=iPhone 16'`.
|
||||||
|
|
||||||
### Diagnostics Service
|
### Diagnostics Service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd services/diagnostics-api
|
make check-diagnostics
|
||||||
npm ci
|
|
||||||
npm run check
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If a required check cannot run on your machine, explain why in the pull request
|
If a required check cannot run on your machine, explain why in the pull request
|
||||||
|
|||||||
181
Makefile
Normal file
181
Makefile
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
ROOT := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
|
||||||
|
|
||||||
|
SHELL := bash
|
||||||
|
.SHELLFLAGS := -eu -o pipefail -c
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
include $(ROOT)/config.mk
|
||||||
|
-include $(ROOT)/config.override.mk
|
||||||
|
include $(ROOT)/make/release.mk
|
||||||
|
|
||||||
|
.PHONY: help doctor setup setup-localization setup-docs setup-diagnostics
|
||||||
|
.PHONY: format test check check-rust audit-rust test-rust test-rust-all
|
||||||
|
.PHONY: test-rust-transfer test-rust-approval test-rust-lifecycle test-rust-output-sink
|
||||||
|
.PHONY: check-shared test-shared test-android-host check-android verify-android-libs build-android run-desktop
|
||||||
|
.PHONY: apple-core apple-project open-apple-project open-apple build-apple-macos build-apple-ios check-apple
|
||||||
|
.PHONY: check-localization localization localization-migrate
|
||||||
|
.PHONY: check-docs run-docs check-diagnostics run-diagnostics diagnostics-db-local diagnostics-db-remote diagnostics-typegen deploy-diagnostics
|
||||||
|
|
||||||
|
help: ## Show available commands and common configuration variables.
|
||||||
|
@grep -hE '^[A-Za-z0-9_.-]+:.*## ' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*## "} {printf " %-28s %s\n", $$1, $$2}'
|
||||||
|
@printf '\nCommon variables:\n'
|
||||||
|
@printf ' %-28s %s\n' 'VERSION=x.y.z' 'Package version (default: $(VERSION))'
|
||||||
|
@printf ' %-28s %s\n' 'APPLE_PROFILE=debug|release' 'Rust profile for the Apple XCFramework'
|
||||||
|
@printf ' %-28s %s\n' 'APPLE_CONFIGURATION=...' 'Xcode configuration (default: $(APPLE_CONFIGURATION))'
|
||||||
|
@printf ' %-28s %s\n' 'APPLE_DESTINATION=...' 'Optional xcodebuild destination override'
|
||||||
|
@printf ' %-28s %s\n' 'APPLE_CODE_SIGNING=NO|YES' 'Enable Apple code signing (default: $(APPLE_CODE_SIGNING))'
|
||||||
|
|
||||||
|
doctor: ## Check that tools required by the current host are available.
|
||||||
|
@missing=0; \
|
||||||
|
for tool in "$(firstword $(CARGO))" java "$(firstword $(NPM))" "$(firstword $(BUN))"; do \
|
||||||
|
if command -v "$$tool" >/dev/null 2>&1; then \
|
||||||
|
printf 'ok %s\n' "$$tool"; \
|
||||||
|
else \
|
||||||
|
printf 'missing %s\n' "$$tool"; \
|
||||||
|
missing=1; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
if [[ ! -f "$(GRADLE)" ]]; then printf 'missing %s\n' "$(GRADLE)"; missing=1; else printf 'ok %s\n' "$(GRADLE)"; fi; \
|
||||||
|
if [[ "$(HOST_OS)" == macos ]]; then \
|
||||||
|
for tool in "$(firstword $(XCODEBUILD))" "$(firstword $(XCODEGEN))"; do \
|
||||||
|
if command -v "$$tool" >/dev/null 2>&1; then printf 'ok %s\n' "$$tool"; else printf 'missing %s\n' "$$tool"; missing=1; fi; \
|
||||||
|
done; \
|
||||||
|
fi; \
|
||||||
|
exit $$missing
|
||||||
|
|
||||||
|
setup: setup-localization setup-docs setup-diagnostics ## Install repository-local JavaScript dependencies.
|
||||||
|
|
||||||
|
setup-localization: ## Install localization CLI dependencies with Bun.
|
||||||
|
cd $(ROOT)/localization && $(BUN) install --frozen-lockfile
|
||||||
|
|
||||||
|
setup-docs: ## Install documentation website dependencies.
|
||||||
|
cd $(ROOT)/docs && $(NPM) ci
|
||||||
|
|
||||||
|
setup-diagnostics: ## Install diagnostics Worker dependencies.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) ci
|
||||||
|
|
||||||
|
format: ## Format Rust sources.
|
||||||
|
cd $(ROOT) && $(CARGO) fmt --all
|
||||||
|
|
||||||
|
test: test-rust test-shared ## Run the main Rust and shared JVM test suites.
|
||||||
|
|
||||||
|
check: check-rust check-shared check-localization check-docs check-diagnostics ## Run portable pre-PR verification.
|
||||||
|
|
||||||
|
check-rust: ## Run Rust formatting, lint, tests, and documentation checks.
|
||||||
|
cd $(ROOT) && $(CARGO) fmt --all -- --check
|
||||||
|
cd $(ROOT) && $(CARGO) clippy --workspace --all-targets -- -D warnings
|
||||||
|
cd $(ROOT) && $(CARGO) test --workspace --all-targets
|
||||||
|
cd $(ROOT) && RUSTDOCFLAGS='-D warnings' $(CARGO) doc --workspace --no-deps
|
||||||
|
|
||||||
|
audit-rust: ## Audit Rust dependencies (requires cargo-audit).
|
||||||
|
cd $(ROOT) && $(CARGO) audit
|
||||||
|
|
||||||
|
test-rust: ## Run the focused Rust core suite.
|
||||||
|
cd $(ROOT) && $(CARGO) test -p vnidrop
|
||||||
|
|
||||||
|
test-rust-all: ## Run every Rust workspace test target.
|
||||||
|
cd $(ROOT) && $(CARGO) test --workspace --all-targets
|
||||||
|
|
||||||
|
test-rust-transfer: ## Run Rust transfer integration tests.
|
||||||
|
cd $(ROOT) && $(CARGO) test -p vnidrop --test transfer
|
||||||
|
|
||||||
|
test-rust-approval: ## Run Rust approval integration tests.
|
||||||
|
cd $(ROOT) && $(CARGO) test -p vnidrop --test approval
|
||||||
|
|
||||||
|
test-rust-lifecycle: ## Run Rust lifecycle integration tests.
|
||||||
|
cd $(ROOT) && $(CARGO) test -p vnidrop --test lifecycle
|
||||||
|
|
||||||
|
test-rust-output-sink: ## Run Rust output-sink integration tests.
|
||||||
|
cd $(ROOT) && $(CARGO) test -p vnidrop --test output_sink
|
||||||
|
|
||||||
|
check-shared: ## Test and compile the shared Android/JVM module.
|
||||||
|
cd $(ROOT) && $(GRADLE) :shared:jvmTest :shared:compileKotlinJvm $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
test-shared: ## Run shared JVM tests.
|
||||||
|
cd $(ROOT) && $(GRADLE) :shared:jvmTest $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
test-android-host: ## Run Android host-side shared tests.
|
||||||
|
cd $(ROOT) && $(GRADLE) :shared:testAndroidHostTest $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
check-android: ## Build Android debug and verify packaged Rust libraries.
|
||||||
|
cd $(ROOT) && $(GRADLE) :androidApp:assembleDebug :androidApp:verifyDebugVnidropLibraries $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
verify-android-libs: ## Verify the Rust libraries packaged in the Android debug app.
|
||||||
|
cd $(ROOT) && $(GRADLE) :androidApp:verifyDebugVnidropLibraries $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
build-android: ## Build the Android debug APK.
|
||||||
|
cd $(ROOT) && $(GRADLE) :androidApp:assembleDebug $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
run-desktop: ## Run the Windows/Linux Compose desktop app.
|
||||||
|
cd $(ROOT) && $(GRADLE) :desktopApp:run $(GRADLE_FLAGS)
|
||||||
|
|
||||||
|
apple-core: ## Build the Rust XCFramework and generated Swift bindings.
|
||||||
|
@test "$(HOST_OS)" = macos || { printf 'Apple builds require macOS.\n' >&2; exit 1; }
|
||||||
|
cd $(ROOT) && apple/scripts/build-core.sh $(APPLE_PROFILE)
|
||||||
|
|
||||||
|
apple-project: apple-core ## Generate the native Apple Xcode project.
|
||||||
|
cd $(ROOT)/apple && $(XCODEGEN) generate
|
||||||
|
|
||||||
|
open-apple-project: apple-project ## Generate and open the native Apple Xcode project.
|
||||||
|
cd $(ROOT)/apple && $(OPEN) VniDrop.xcodeproj
|
||||||
|
|
||||||
|
build-apple-macos: apple-project ## Build the native macOS app (unsigned by default).
|
||||||
|
cd $(ROOT)/apple && $(XCODEBUILD) -project VniDrop.xcodeproj -scheme VniDrop -configuration $(APPLE_CONFIGURATION) -derivedDataPath "$(APPLE_DERIVED_DATA)" -destination 'platform=macOS' CODE_SIGNING_ALLOWED=$(APPLE_CODE_SIGNING) CODE_SIGNING_REQUIRED=$(APPLE_CODE_SIGNING) build
|
||||||
|
|
||||||
|
open-apple: build-apple-macos ## Build and launch the native macOS app.
|
||||||
|
@test -d "$(APPLE_DERIVED_DATA)/Build/Products/$(APPLE_CONFIGURATION)/VniDrop.app" || { printf 'Built macOS app was not found.\n' >&2; exit 1; }
|
||||||
|
$(OPEN) "$(APPLE_DERIVED_DATA)/Build/Products/$(APPLE_CONFIGURATION)/VniDrop.app"
|
||||||
|
|
||||||
|
build-apple-ios: apple-project ## Build the native iOS simulator app (unsigned by default).
|
||||||
|
@destination="$(APPLE_DESTINATION)"; \
|
||||||
|
if [[ -z "$$destination" ]]; then \
|
||||||
|
device_id="$$(xcrun simctl list devices available | sed -nE '/iPhone/ s/.*\(([0-9A-F-]{36})\) \((Booted|Shutdown)\).*/\1/p' | head -1 || true)"; \
|
||||||
|
[[ -n "$$device_id" ]] || { printf 'No available iPhone simulator found. Set APPLE_DESTINATION explicitly.\n' >&2; exit 1; }; \
|
||||||
|
destination="platform=iOS Simulator,id=$$device_id"; \
|
||||||
|
fi; \
|
||||||
|
cd $(ROOT)/apple && $(XCODEBUILD) -project VniDrop.xcodeproj -scheme VniDrop -configuration $(APPLE_CONFIGURATION) -derivedDataPath "$(APPLE_DERIVED_DATA)" -destination "$$destination" CODE_SIGNING_ALLOWED=$(APPLE_CODE_SIGNING) CODE_SIGNING_REQUIRED=$(APPLE_CODE_SIGNING) build
|
||||||
|
|
||||||
|
check-apple: apple-project ## Build the Apple core and run iOS simulator tests.
|
||||||
|
@destination="$(APPLE_DESTINATION)"; \
|
||||||
|
if [[ -z "$$destination" ]]; then \
|
||||||
|
device_id="$$(xcrun simctl list devices available | sed -nE '/iPhone/ s/.*\(([0-9A-F-]{36})\) \((Booted|Shutdown)\).*/\1/p' | head -1 || true)"; \
|
||||||
|
[[ -n "$$device_id" ]] || { printf 'No available iPhone simulator found. Set APPLE_DESTINATION explicitly.\n' >&2; exit 1; }; \
|
||||||
|
destination="platform=iOS Simulator,id=$$device_id"; \
|
||||||
|
fi; \
|
||||||
|
printf 'Testing on: %s\n' "$$destination"; \
|
||||||
|
cd $(ROOT)/apple && $(XCODEBUILD) test -project VniDrop.xcodeproj -scheme VniDrop -configuration $(APPLE_CONFIGURATION) -derivedDataPath "$(APPLE_DERIVED_DATA)" -destination "$$destination" CODE_SIGNING_ALLOWED=$(APPLE_CODE_SIGNING) CODE_SIGNING_REQUIRED=$(APPLE_CODE_SIGNING)
|
||||||
|
|
||||||
|
check-localization: setup-localization ## Validate the localization source catalog.
|
||||||
|
cd $(ROOT)/localization && $(BUN) run validate
|
||||||
|
|
||||||
|
localization: setup-localization ## Regenerate Apple and KMP localization resources.
|
||||||
|
cd $(ROOT)/localization && $(BUN) run generate
|
||||||
|
|
||||||
|
localization-migrate: setup-localization ## Rebuild strings.json from platform resources.
|
||||||
|
cd $(ROOT)/localization && $(BUN) run migrate
|
||||||
|
|
||||||
|
check-docs: setup-docs ## Lint, type-check, and build the documentation website.
|
||||||
|
cd $(ROOT)/docs && $(NPM) run lint
|
||||||
|
cd $(ROOT)/docs && $(NPM) run typecheck
|
||||||
|
cd $(ROOT)/docs && $(NPM) run build
|
||||||
|
|
||||||
|
run-docs: setup-docs ## Run the documentation development server.
|
||||||
|
cd $(ROOT)/docs && $(NPM) run dev
|
||||||
|
|
||||||
|
check-diagnostics: setup-diagnostics ## Run diagnostics types, tests, and deployment dry-run.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run check
|
||||||
|
|
||||||
|
run-diagnostics: setup-diagnostics ## Run the diagnostics Worker locally.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run dev
|
||||||
|
|
||||||
|
diagnostics-db-local: setup-diagnostics ## Apply diagnostics database migrations locally.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run db:migrate:local
|
||||||
|
|
||||||
|
diagnostics-db-remote: setup-diagnostics ## Apply diagnostics database migrations to the configured remote D1 database.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run db:migrate:remote
|
||||||
|
|
||||||
|
diagnostics-typegen: setup-diagnostics ## Regenerate diagnostics Worker binding types.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run typegen
|
||||||
|
|
||||||
|
deploy-diagnostics: setup-diagnostics ## Check and deploy the diagnostics Worker to Cloudflare.
|
||||||
|
cd $(ROOT)/services/diagnostics-api && $(NPM) run deploy
|
||||||
18
README.md
18
README.md
@@ -118,17 +118,21 @@ if you want to try the current version.
|
|||||||
git clone https://github.com/vnidrop/vnidrop.git
|
git clone https://github.com/vnidrop/vnidrop.git
|
||||||
cd vnidrop
|
cd vnidrop
|
||||||
|
|
||||||
|
# List the supported development commands and check prerequisites
|
||||||
|
make help
|
||||||
|
make doctor
|
||||||
|
|
||||||
# Windows/Linux desktop
|
# Windows/Linux desktop
|
||||||
./gradlew :desktopApp:run
|
make run-desktop
|
||||||
|
|
||||||
# Android debug build
|
# Android debug build
|
||||||
./gradlew :androidApp:assembleDebug
|
make build-android
|
||||||
|
|
||||||
# iOS, iPadOS, and macOS
|
# Build and launch the macOS app
|
||||||
cd apple
|
make open-apple
|
||||||
./scripts/build-core.sh debug
|
|
||||||
xcodegen generate
|
# Open the native project for iOS, iPadOS, or Xcode development
|
||||||
open VniDrop.xcodeproj
|
make open-apple-project
|
||||||
```
|
```
|
||||||
|
|
||||||
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for prerequisites, development setup,
|
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for prerequisites, development setup,
|
||||||
|
|||||||
@@ -30,21 +30,24 @@ Prerequisites: Xcode, Rust with the Apple targets
|
|||||||
`aarch64-apple-darwin`), and `xcodegen` (`brew install xcodegen`).
|
`aarch64-apple-darwin`), and `xcodegen` (`brew install xcodegen`).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Build the Rust core and generate the Swift bindings + xcframework.
|
# From the repository root:
|
||||||
apple/scripts/build-core.sh debug # or: release (see note below)
|
make apple-core # Rust core, Swift bindings, and XCFramework
|
||||||
|
make apple-project # generate apple/VniDrop.xcodeproj
|
||||||
# 2. Generate the Xcode project.
|
make open-apple-project # generate and open the project in Xcode
|
||||||
cd apple && xcodegen generate
|
make build-apple-macos # unsigned macOS build
|
||||||
|
make open-apple # build and launch the macOS app
|
||||||
# 3. Open and run, or build from the CLI:
|
make build-apple-ios # unsigned iOS simulator build
|
||||||
open VniDrop.xcodeproj
|
make check-apple # iOS simulator tests
|
||||||
# macOS:
|
|
||||||
xcodebuild -project VniDrop.xcodeproj -scheme VniDrop -destination 'platform=macOS' build
|
|
||||||
# iOS simulator:
|
|
||||||
xcodebuild -project VniDrop.xcodeproj -scheme VniDrop \
|
|
||||||
-destination 'platform=iOS Simulator,name=iPhone 15' build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use `APPLE_PROFILE=release` to request a release Rust core, or set
|
||||||
|
`APPLE_DESTINATION` to override the automatically selected iOS simulator.
|
||||||
|
Code signing is disabled for the app and test targets; local and CI builds do
|
||||||
|
not require an Apple Development team or provisioning profile. Make builds can
|
||||||
|
opt in with `APPLE_CODE_SIGNING=YES`. For signed builds from Xcode, create the
|
||||||
|
ignored `apple/Local.xcconfig` and override the signing settings there, including
|
||||||
|
the development team.
|
||||||
|
|
||||||
## Command-line typecheck & tests
|
## Command-line typecheck & tests
|
||||||
|
|
||||||
`Package.swift` builds the same sources as a library (minus the `@main` entry),
|
`Package.swift` builds the same sources as a library (minus the `@main` entry),
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// Committed signing config. Contains no secrets.
|
// VniDrop development and CI builds are intentionally unsigned.
|
||||||
//
|
CODE_SIGNING_ALLOWED = NO
|
||||||
// Per-developer signing (e.g. DEVELOPMENT_TEAM) goes in Local.xcconfig, which is
|
CODE_SIGNING_REQUIRED = NO
|
||||||
// gitignored. The optional include below means the build still works for anyone
|
|
||||||
// who doesn't have a Local.xcconfig — Xcode automatic signing fills in their team.
|
// Signed local builds can opt in through this ignored file.
|
||||||
//
|
|
||||||
// To persist your team across `xcodegen generate`, create apple/Local.xcconfig:
|
|
||||||
// DEVELOPMENT_TEAM = XXXXXXXXXX
|
|
||||||
#include? "Local.xcconfig"
|
#include? "Local.xcconfig"
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ targets:
|
|||||||
SWIFT_STRICT_CONCURRENCY: complete
|
SWIFT_STRICT_CONCURRENCY: complete
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING: NO
|
ENABLE_USER_SCRIPT_SANDBOXING: NO
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||||||
CODE_SIGN_STYLE: Automatic
|
|
||||||
configs:
|
configs:
|
||||||
debug:
|
debug:
|
||||||
CODE_SIGN_ENTITLEMENTS: VniDrop/Resources/VniDrop.entitlements
|
CODE_SIGN_ENTITLEMENTS: VniDrop/Resources/VniDrop.entitlements
|
||||||
@@ -56,6 +55,9 @@ targets:
|
|||||||
VniDropTests:
|
VniDropTests:
|
||||||
type: bundle.unit-test
|
type: bundle.unit-test
|
||||||
supportedDestinations: [iOS, macOS]
|
supportedDestinations: [iOS, macOS]
|
||||||
|
configFiles:
|
||||||
|
Debug: Signing.xcconfig
|
||||||
|
Release: Signing.xcconfig
|
||||||
sources:
|
sources:
|
||||||
- path: Tests
|
- path: Tests
|
||||||
settings:
|
settings:
|
||||||
@@ -63,7 +65,6 @@ targets:
|
|||||||
GENERATE_INFOPLIST_FILE: YES
|
GENERATE_INFOPLIST_FILE: YES
|
||||||
SWIFT_VERSION: "6.0"
|
SWIFT_VERSION: "6.0"
|
||||||
SWIFT_STRICT_CONCURRENCY: complete
|
SWIFT_STRICT_CONCURRENCY: complete
|
||||||
CODE_SIGN_STYLE: Automatic
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- target: VniDrop
|
- target: VniDrop
|
||||||
|
|
||||||
|
|||||||
35
config.mk
Normal file
35
config.mk
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Default command configuration. Override locally in the ignored
|
||||||
|
# config.override.mk or on the command line (for example: make package-deb VERSION=1.2.0).
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
HOST_OS := windows
|
||||||
|
GRADLE ?= ./gradlew.bat
|
||||||
|
else
|
||||||
|
HOST_UNAME := $(shell uname -s)
|
||||||
|
ifeq ($(HOST_UNAME),Darwin)
|
||||||
|
HOST_OS := macos
|
||||||
|
else ifeq ($(HOST_UNAME),Linux)
|
||||||
|
HOST_OS := linux
|
||||||
|
else
|
||||||
|
HOST_OS := unknown
|
||||||
|
endif
|
||||||
|
GRADLE ?= ./gradlew
|
||||||
|
endif
|
||||||
|
|
||||||
|
CARGO ?= cargo
|
||||||
|
NPM ?= npm
|
||||||
|
BUN ?= bun
|
||||||
|
XCODEBUILD ?= xcodebuild
|
||||||
|
XCODEGEN ?= xcodegen
|
||||||
|
OPEN ?= open
|
||||||
|
POWERSHELL ?= pwsh
|
||||||
|
|
||||||
|
VERSION ?= $(shell sed -n 's/^vnidrop.version=//p' $(ROOT)/gradle.properties)
|
||||||
|
APPLE_PROFILE ?= debug
|
||||||
|
APPLE_CONFIGURATION ?= Debug
|
||||||
|
APPLE_DESTINATION ?=
|
||||||
|
APPLE_CODE_SIGNING ?= NO
|
||||||
|
APPLE_DERIVED_DATA ?= $(ROOT)/apple/DerivedData
|
||||||
|
|
||||||
|
GRADLE_FLAGS ?= --no-daemon --stacktrace
|
||||||
|
GRADLE_RELEASE_FLAGS ?= --no-daemon --no-configuration-cache --stacktrace
|
||||||
@@ -19,20 +19,18 @@ Read [`CORE_FLOW.md`](CORE_FLOW.md) before changing send/receive/export/cancel.
|
|||||||
Always prefer workspace commands so lockfile/fmt stay consistent:
|
Always prefer workspace commands so lockfile/fmt stay consistent:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all
|
make format
|
||||||
cargo fmt --all -- --check
|
make test-rust
|
||||||
cargo clippy --workspace --all-targets -- -D warnings
|
make check-rust
|
||||||
cargo test -p vnidrop
|
|
||||||
cargo test --workspace --all-targets
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Focused integration suites:
|
Focused integration suites:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test -p vnidrop --test transfer
|
make test-rust-transfer
|
||||||
cargo test -p vnidrop --test approval
|
make test-rust-approval
|
||||||
cargo test -p vnidrop --test lifecycle
|
make test-rust-lifecycle
|
||||||
cargo test -p vnidrop --test output_sink
|
make test-rust-output-sink
|
||||||
```
|
```
|
||||||
|
|
||||||
Docs (CI uses `-D warnings`):
|
Docs (CI uses `-D warnings`):
|
||||||
@@ -41,7 +39,7 @@ Docs (CI uses `-D warnings`):
|
|||||||
RUSTDOCFLAGS='-D warnings' cargo doc -p vnidrop --no-deps
|
RUSTDOCFLAGS='-D warnings' cargo doc -p vnidrop --no-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `cargo fmt --all` after finishing Rust edits without asking.
|
Run `make format` after finishing Rust edits without asking.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -116,13 +114,11 @@ Details: [`tests/README.md`](tests/README.md).
|
|||||||
## PR / verify checklist for this crate
|
## PR / verify checklist for this crate
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all -- --check
|
make check-rust
|
||||||
cargo clippy --workspace --all-targets -- -D warnings
|
|
||||||
cargo test -p vnidrop
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you touched cancel, export, or sinks, also:
|
If you touched cancel, export, or sinks, also:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo test -p vnidrop --test output_sink
|
make test-rust-output-sink
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ The product website for VniDrop, built with Next.js and exported as a static sit
|
|||||||
## Local development
|
## Local development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
# From the repository root:
|
||||||
npm run dev
|
make run-docs
|
||||||
```
|
```
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000).
|
Open [http://localhost:3000](http://localhost:3000).
|
||||||
@@ -14,9 +14,7 @@ Open [http://localhost:3000](http://localhost:3000).
|
|||||||
## Checks
|
## Checks
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run lint
|
make check-docs
|
||||||
npm run typecheck
|
|
||||||
npm run build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The production build is written to `out/` and can be hosted by any static web server.
|
The production build is written to `out/` and can be hosted by any static web server.
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ A Bun CLI generates the platform-native files from it:
|
|||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd localization
|
# From the repository root:
|
||||||
bun run src/cli.ts validate # structural checks (run before committing)
|
make check-localization # structural checks (run before committing)
|
||||||
bun run src/cli.ts generate # regenerate .xcstrings + strings.xml from strings.json
|
make localization # regenerate .xcstrings + strings.xml from strings.json
|
||||||
bun run src/cli.ts migrate # one-time: rebuild strings.json from existing platform files
|
make localization-migrate # one-time: rebuild strings.json from platform files
|
||||||
```
|
```
|
||||||
|
|
||||||
**Never edit the generated `.xcstrings` / `strings.xml` by hand** — edit `strings.json` and
|
**Never edit the generated `.xcstrings` / `strings.xml` by hand** — edit `strings.json` and
|
||||||
|
|||||||
51
make/release.mk
Normal file
51
make/release.mk
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
.PHONY: package-deb package-rpm package-msix
|
||||||
|
|
||||||
|
package-deb: ## Build and verify a Debian x64 package (VERSION=x.y.z).
|
||||||
|
@test "$(HOST_OS)" = linux || { printf 'Debian packaging requires Linux.\n' >&2; exit 1; }
|
||||||
|
@cd $(ROOT); \
|
||||||
|
version="$$(packaging/linux/resolve-version.sh "$(VERSION)")"; \
|
||||||
|
$(GRADLE) :shared:jvmTest :desktopApp:packageReleaseDeb \
|
||||||
|
-Pvnidrop.version="$$version" \
|
||||||
|
-Pvnidrop.desktop.rustVariant=release \
|
||||||
|
-Pvnidrop.diagnostics.included=false \
|
||||||
|
$(GRADLE_RELEASE_FLAGS); \
|
||||||
|
mapfile -t packages < <(find desktopApp/build/compose/binaries/main-release/deb -maxdepth 1 -type f -name '*.deb'); \
|
||||||
|
(( $${#packages[@]} == 1 )) || { printf 'Expected exactly one Debian package, found %s\n' "$${#packages[@]}" >&2; exit 1; }; \
|
||||||
|
output_directory=build/release/linux/deb; \
|
||||||
|
output_name="vnidrop_$${version}-1_amd64.deb"; \
|
||||||
|
mkdir -p "$$output_directory"; \
|
||||||
|
cp "$${packages[0]}" "$$output_directory/$$output_name"; \
|
||||||
|
packaging/linux/verify-package.sh deb "$$version" "$$output_directory/$$output_name"; \
|
||||||
|
( cd "$$output_directory" && sha256sum "$$output_name" > "$$output_name.sha256" ); \
|
||||||
|
printf 'Package: %s/%s\n' "$$output_directory" "$$output_name"
|
||||||
|
|
||||||
|
package-rpm: ## Build and verify an RPM x64 package (VERSION=x.y.z).
|
||||||
|
@test "$(HOST_OS)" = linux || { printf 'RPM packaging requires Linux.\n' >&2; exit 1; }
|
||||||
|
@cd $(ROOT); \
|
||||||
|
version="$$(packaging/linux/resolve-version.sh "$(VERSION)")"; \
|
||||||
|
$(GRADLE) :desktopApp:packageReleaseRpm \
|
||||||
|
-Pvnidrop.version="$$version" \
|
||||||
|
-Pvnidrop.desktop.rustVariant=release \
|
||||||
|
-Pvnidrop.diagnostics.included=false \
|
||||||
|
$(GRADLE_RELEASE_FLAGS); \
|
||||||
|
mapfile -t packages < <(find desktopApp/build/compose/binaries/main-release/rpm -maxdepth 1 -type f -name '*.rpm'); \
|
||||||
|
(( $${#packages[@]} == 1 )) || { printf 'Expected exactly one RPM package, found %s\n' "$${#packages[@]}" >&2; exit 1; }; \
|
||||||
|
output_directory=build/release/linux/rpm; \
|
||||||
|
output_name="vnidrop-$${version}-1.x86_64.rpm"; \
|
||||||
|
mkdir -p "$$output_directory"; \
|
||||||
|
cp "$${packages[0]}" "$$output_directory/$$output_name"; \
|
||||||
|
packaging/linux/verify-package.sh rpm "$$version" "$$output_directory/$$output_name"; \
|
||||||
|
( cd "$$output_directory" && sha256sum "$$output_name" > "$$output_name.sha256" ); \
|
||||||
|
printf 'Package: %s/%s\n' "$$output_directory" "$$output_name"
|
||||||
|
|
||||||
|
package-msix: ## Build and verify an unsigned Windows Store MSIX (VERSION=x.y.z).
|
||||||
|
@test "$(HOST_OS)" = windows || { printf 'MSIX packaging requires Windows.\n' >&2; exit 1; }
|
||||||
|
cd $(ROOT) && $(GRADLE) :shared:jvmTest :desktopApp:createReleaseDistributable \
|
||||||
|
-Pvnidrop.version="$(VERSION)" \
|
||||||
|
-Pvnidrop.desktop.rustVariant=release \
|
||||||
|
-Pvnidrop.diagnostics.included=false \
|
||||||
|
$(GRADLE_RELEASE_FLAGS)
|
||||||
|
cd $(ROOT) && $(POWERSHELL) -NoProfile -File packaging/windows/build-msix.ps1 \
|
||||||
|
-Version "$(VERSION)" \
|
||||||
|
-AppImage desktopApp/build/compose/binaries/main-release/app/VniDrop \
|
||||||
|
-OutputDirectory build/release/windows
|
||||||
@@ -64,21 +64,10 @@ Ubuntu prevents `jpackage` from discovering normal RPM dependencies.
|
|||||||
From the repository root on the matching Linux family, run one of:
|
From the repository root on the matching Linux family, run one of:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:jvmTest :desktopApp:packageReleaseDeb \
|
make package-deb VERSION=1.0.0
|
||||||
-Pvnidrop.version=1.0.0 \
|
make package-rpm VERSION=1.0.0
|
||||||
-Pvnidrop.desktop.rustVariant=release \
|
|
||||||
-Pvnidrop.diagnostics.included=false \
|
|
||||||
--no-daemon --no-configuration-cache --stacktrace
|
|
||||||
|
|
||||||
./gradlew :shared:jvmTest :desktopApp:packageReleaseRpm \
|
|
||||||
-Pvnidrop.version=1.0.0 \
|
|
||||||
-Pvnidrop.desktop.rustVariant=release \
|
|
||||||
-Pvnidrop.diagnostics.included=false \
|
|
||||||
--no-daemon --no-configuration-cache --stacktrace
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Compose writes the packages under
|
The Make targets collect the Compose output under `build/release/linux/`, then
|
||||||
`desktopApp/build/compose/binaries/main-release/deb/` and
|
validate package identity, version, architecture, dependencies, bundled JVM,
|
||||||
`desktopApp/build/compose/binaries/main-release/rpm/`. The workflow then
|
and release Rust payload before generating a SHA-256 checksum.
|
||||||
validates package identity, version, architecture, dependencies, bundled JVM,
|
|
||||||
and release Rust payload before publishing anything.
|
|
||||||
|
|||||||
@@ -85,19 +85,23 @@ npx wrangler r2 bucket create vnidrop-diagnostics
|
|||||||
```
|
```
|
||||||
|
|
||||||
Replace the placeholder `database_id` in `wrangler.jsonc` with the UUID returned
|
Replace the placeholder `database_id` in `wrangler.jsonc` with the UUID returned
|
||||||
by `wrangler d1 create`. Set the ingest key interactively, apply the tracked D1
|
by `wrangler d1 create`. Set the ingest key interactively and configure the R2
|
||||||
migrations, and configure the R2 retention rule once:
|
retention rule once:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx wrangler secret put INGEST_KEY
|
npx wrangler secret put INGEST_KEY
|
||||||
npm run db:migrate:remote
|
|
||||||
npx wrangler r2 bucket lifecycle add vnidrop-diagnostics diagnostics-retention --expire-days 90
|
npx wrangler r2 bucket lifecycle add vnidrop-diagnostics diagnostics-retention --expire-days 90
|
||||||
npm run check
|
|
||||||
npm run deploy
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`npm run deploy` also runs the complete `check` script automatically before
|
Then apply migrations and deploy from the repository root:
|
||||||
Wrangler changes the remote Worker.
|
|
||||||
|
```bash
|
||||||
|
make diagnostics-db-remote
|
||||||
|
make deploy-diagnostics
|
||||||
|
```
|
||||||
|
|
||||||
|
`make deploy-diagnostics` runs the complete check before Wrangler changes the
|
||||||
|
remote Worker.
|
||||||
|
|
||||||
The lifecycle command changes the remote bucket. Before adding or changing a
|
The lifecycle command changes the remote bucket. Before adding or changing a
|
||||||
rule, inspect the current state with:
|
rule, inspect the current state with:
|
||||||
@@ -117,8 +121,9 @@ INGEST_KEY=local-development-only
|
|||||||
Then initialize the local D1 database and run the Worker:
|
Then initialize the local D1 database and run the Worker:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run db:migrate:local
|
# From the repository root:
|
||||||
npm run dev
|
make diagnostics-db-local
|
||||||
|
make run-diagnostics
|
||||||
```
|
```
|
||||||
|
|
||||||
Wrangler keeps local D1 and R2 state under the ignored `.wrangler/` directory.
|
Wrangler keeps local D1 and R2 state under the ignored `.wrangler/` directory.
|
||||||
@@ -133,7 +138,7 @@ Never edit an applied migration; add the next numbered SQL file instead.
|
|||||||
bindings cannot silently drift from the Worker code:
|
bindings cannot silently drift from the Worker code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run typegen # regenerate after changing bindings or vars
|
make diagnostics-typegen # from the repository root
|
||||||
npm run types:check # verify the committed file is current
|
npm run types:check # verify the committed file is current
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -46,16 +46,15 @@ compose-skill “Existing Project Policy”: adapt to this repo; do not force-mi
|
|||||||
From repo root:
|
From repo root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:jvmTest
|
make check-shared
|
||||||
./gradlew :shared:compileKotlinJvm
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:testAndroidHostTest
|
make test-android-host
|
||||||
./gradlew :desktopApp:run
|
make run-desktop
|
||||||
./gradlew :androidApp:assembleDebug
|
make check-android
|
||||||
```
|
```
|
||||||
|
|
||||||
CI `:shared:jvmTest` runs on **Linux**. Gobley host cargo follows the current
|
CI `:shared:jvmTest` runs on **Linux**. Gobley host cargo follows the current
|
||||||
@@ -113,7 +112,7 @@ Never pass a directory as a single Android FD into `SourceKind.FILE_DESCRIPTOR`.
|
|||||||
- Prefer fakes in `commonTest` support over real UniFFI in pure unit tests.
|
- Prefer fakes in `commonTest` support over real UniFFI in pure unit tests.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew :shared:jvmTest
|
make test-shared
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
Reference in New Issue
Block a user