diff --git a/.github/actions/setup-rust/action.yaml b/.github/actions/setup-rust/action.yaml new file mode 100644 index 0000000..8b3af02 --- /dev/null +++ b/.github/actions/setup-rust/action.yaml @@ -0,0 +1,66 @@ +name: 'Setup Rust environment' +description: 'Composite action to checkout the repo, restore cargo caches and set up the Rust toolchain. Use this from job steps to keep setup DRY across jobs.' +inputs: + toolchain: + description: 'Rust toolchain to install' + required: false + default: 'stable' + override: + description: 'Whether to override the default toolchain' + required: false + default: 'true' + components: + description: 'Comma-separated list of additional rust components to install' + required: false + default: 'clippy, rustfmt' +runs: + using: 'composite' + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: ~/.cargo/registry + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo index + uses: actions/cache@v4 + with: + path: ~/.cargo/index + key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Sanitize components input + shell: bash + run: echo "SANITIZED_COMPONENTS=${{ inputs.components }}" | sed -E 's/, ?| /-/g' >> $GITHUB_ENV + + - name: Cache Rust toolchain + uses: actions/cache@v4 + with: + path: ~/.rustup + # Key includes the OS and the toolchain version (e.g., 'stable') + key: ${{ runner.os }}-rustup-${{ hashFiles('rust-toolchain.toml') }}-v1-${{ inputs.toolchain }}-${{ env.SANITIZED_COMPONENTS }} + restore-keys: | + ${{ runner.os }}-rustup- + + - name: Cache cargo build (target) + uses: actions/cache@v4 + with: + path: target + key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} + + - name: Set up rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ inputs.toolchain }} + override: ${{ inputs.override }} + components: ${{ inputs.components }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..e2076c3 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,140 @@ +# this workflow runs tests on pull request and push events targeting master branch +# it also verify the generated code is up to date and valid + +name: Test +on: + pull_request: + branches: + - master + push: + branches: + - master + +jobs: + test-crates: + needs: frontend-build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Rust, checkout and restore caches + uses: ./.github/actions/setup-rust + + - name: Restore frontend build cache + uses: actions/cache@v4 + with: + path: apps/nxmesh-frontend/build + key: frontend-build-${{ runner.os }}-run-${{ github.run_id }} + restore-keys: | + frontend-build-${{ runner.os }}- + + - name: install protobuf compiler + run: | + apt-get update + apt-get install -y protobuf-compiler + + - name: Run tests + run: cargo test --all-features + + lint-crates: + needs: frontend-build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Rust, checkout and restore caches + uses: ./.github/actions/setup-rust + with: + components: clippy, rustfmt + + - name: Restore frontend build cache + uses: actions/cache@v4 + with: + path: apps/nxmesh-frontend/build + key: frontend-build-${{ runner.os }}-run-${{ github.run_id }} + restore-keys: | + frontend-build-${{ runner.os }}- + + - name: install protobuf compiler + run: | + apt-get update + apt-get install -y protobuf-compiler + + - name: Run clippy + run: cargo clippy --all-features + + - name: Check code formatting + run: cargo fmt --all -- --check + + lint-frontend: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - uses: oven-sh/setup-bun@v2 + name: Install Bun + + - name: Install frontend dependencies + run: | + cd apps/nxmesh-frontend + bun install + + - name: Run frontend linter + run: | + cd apps/nxmesh-frontend + bun run lint + + test-frontend: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: oven-sh/setup-bun@v2 + name: Install Bun + + - name: Install frontend dependencies + run: | + cd apps/nxmesh-frontend + bun install + + - name: Run frontend tests + run: | + cd apps/nxmesh-frontend + bun run test + + frontend-build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - uses: oven-sh/setup-bun@v2 + name: Install Bun + + - name: Install frontend dependencies + run: | + cd apps/nxmesh-frontend + bun install + + - name: Build frontend + run: | + cd apps/nxmesh-frontend + bun run build + + - name: Cache frontend build + uses: actions/cache@v4 + with: + path: apps/nxmesh-frontend/build + key: frontend-build-${{ runner.os }}-run-${{ github.run_id }} + restore-keys: | + frontend-build-${{ runner.os }}- diff --git a/apps/nxmesh-agent/src/service/master_handler.rs b/apps/nxmesh-agent/src/service/master_handler.rs new file mode 100644 index 0000000..52ace69 --- /dev/null +++ b/apps/nxmesh-agent/src/service/master_handler.rs @@ -0,0 +1,38 @@ +use std::sync::Arc; + +use nxmesh_proto::ConfigUpdate; +use tracing::info; + +use crate::connector::master::MasterConnector; + +#[async_trait::async_trait] +pub trait MasterHandler { + async fn on_config_update( + &self, + config_info: ConfigUpdate, + ) -> Result<(), Box>; +} + +pub struct MasterHandlerImpl { + settings: Arc, +} + +impl MasterHandlerImpl { + pub fn new(settings: impl Into>) -> Self { + Self { + settings: settings.into(), + } + } +} + +#[async_trait::async_trait] +impl MasterHandler for MasterHandlerImpl { + async fn on_config_update( + &self, + config_info: ConfigUpdate, + ) -> Result<(), Box> { + info!("Received config update from master: {:?}", config_info); + + Ok(()) + } +} diff --git a/apps/nxmesh-frontend/package.json b/apps/nxmesh-frontend/package.json index 532cc0c..c59d76a 100644 --- a/apps/nxmesh-frontend/package.json +++ b/apps/nxmesh-frontend/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "test": "echo \"No test specified\" && exit 0" }, "dependencies": { "react": "^19.2.0", @@ -27,4 +28,4 @@ "typescript-eslint": "^8.48.0", "vite": "^7.3.1" } -} +} \ No newline at end of file diff --git a/crates/nxmesh-core/src/lib.rs b/crates/nxmesh-core/src/lib.rs index e69de29..8b13789 100644 --- a/crates/nxmesh-core/src/lib.rs +++ b/crates/nxmesh-core/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/nxmesh-proto/src/lib.rs b/crates/nxmesh-proto/src/lib.rs index c718240..249fd51 100644 --- a/crates/nxmesh-proto/src/lib.rs +++ b/crates/nxmesh-proto/src/lib.rs @@ -10,6 +10,7 @@ pub mod agent { pub use agent::*; pub mod auth; +#[allow(ambiguous_glob_reexports)] pub use tonic_async_interceptor::*; #[cfg(test)]