diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 0056e586..4c6def2c 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -48,6 +48,15 @@ jobs: - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov + - name: Free up disk space + run: | + # Remove unnecessary tools and files to free up ~10GB + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + df -h + - name: Cache dependencies uses: actions/cache@v4 with: @@ -55,16 +64,19 @@ jobs: ~/.cargo/registry ~/.cargo/git target - key: ${{ runner.os }}-cargo-coverage-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} + key: ${{ runner.os }}-cargo-coverage-only-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} restore-keys: | - ${{ runner.os }}-cargo-coverage-1.88- - ${{ runner.os }}-cargo- + ${{ runner.os }}-cargo-coverage-only-1.88- - - name: Generate code coverage + - name: Clean previous coverage artifacts run: | - # Clean any existing coverage data + # Remove previous coverage data but keep compiled dependencies cargo llvm-cov clean --workspace + # Show disk space before coverage generation + df -h + - name: Generate code coverage + run: | # Run tests with coverage for all packages (excluding same files as Codecov) # Use debug mode for coverage (release mode can interfere with coverage instrumentation) cargo llvm-cov test --all-features --workspace --lcov --output-path lcov.info \ @@ -95,11 +107,6 @@ jobs: > coverage-summary.txt cat coverage-summary.txt - # Clean target to save space after coverage generation - du -sh target || true - cargo clean - echo "Cleaned target directory to save disk space" - # Extract coverage percentage for PR comment (use tail -1 to get TOTAL line, not first file) COVERAGE=$(grep -oP '\d+\.\d+(?=%)' coverage-summary.txt | tail -1) echo "COVERAGE_PERCENT=$COVERAGE" >> $GITHUB_ENV @@ -107,6 +114,29 @@ jobs: # Note: Coverage validation is now handled by Codecov, not locally echo "â„šī¸ Coverage validation delegated to Codecov - see https://codecov.io/gh/${{ github.repository }}" + - name: Cleanup cache before saving + run: | + echo "📊 Disk usage before cleanup:" + du -sh target || true + + # Remove coverage-specific artifacts that shouldn't be cached + rm -rf target/llvm-cov-target + rm -rf target/debug/.fingerprint/*-llvm-cov* + rm -rf target/*/debug/coverage* + + # Remove test binaries (large and rebuilt every time) + find target -type f -name '*-????????????????' -executable -delete 2>/dev/null || true + + # Remove incremental compilation data (doesn't help across runs) + rm -rf target/debug/incremental + rm -rf target/release/incremental + + # Keep: compiled dependencies in target/debug/deps/*.rlib + # Keep: build script outputs in target/debug/build/*/out + + echo "📊 Disk usage after cleanup:" + du -sh target || true + - name: Post coverage comment if: github.event_name == 'pull_request' uses: actions/github-script@v7 diff --git a/.github/workflows/external-validation.yml b/.github/workflows/external-validation.yml index 5528740c..b7b5ffa7 100644 --- a/.github/workflows/external-validation.yml +++ b/.github/workflows/external-validation.yml @@ -25,6 +25,10 @@ env: MCP_VALIDATOR_API_URL: https://api.mcp-validator.com JSONRPC_VALIDATOR_URL: https://json-rpc.dev/api/validate +permissions: + contents: read + packages: read + jobs: # Fast validation for PRs - Ubuntu only validate-framework-fast: @@ -54,8 +58,7 @@ jobs: target key: ${{ runner.os }}-cargo-external-fast-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} restore-keys: | - ${{ runner.os }}-cargo-external-1.88- - ${{ runner.os }}-cargo- + ${{ runner.os }}-cargo-external-fast-1.88- - name: Clean procedural macro artifacts run: | @@ -64,11 +67,13 @@ jobs: - name: Build framework (parallel) run: | - cargo build --all-features --release --jobs $(nproc) + # Cargo automatically detects CPU count for parallel builds + cargo build --all-features --release - name: Run core tests (parallel) run: | - cargo test --all-features --release --jobs $(nproc) --workspace --exclude pulseengine-mcp-external-validation + # Cargo automatically detects CPU count for parallel tests + cargo test --all-features --release --workspace --exclude pulseengine-mcp-external-validation - name: Run external validation tests run: | @@ -114,6 +119,16 @@ jobs: with: python-version: ${{ matrix.python }} + - name: Free up disk space + if: runner.os == 'Linux' + run: | + # Remove unnecessary tools and files to free up ~10GB + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + df -h + - name: Cache Rust dependencies uses: actions/cache@v4 with: @@ -121,11 +136,9 @@ jobs: ~/.cargo/registry ~/.cargo/git target - key: ${{ runner.os }}-cargo-external-${{ matrix.rust }}-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} + key: ${{ runner.os }}-cargo-external-full-${{ matrix.rust }}-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} restore-keys: | - ${{ runner.os }}-cargo-external-${{ matrix.rust }}-1.88- - ${{ runner.os }}-cargo-external-1.88- - ${{ runner.os }}-cargo- + ${{ runner.os }}-cargo-external-full-${{ matrix.rust }}-1.88- - name: Cache Python dependencies uses: actions/cache@v4 @@ -180,13 +193,13 @@ jobs: - name: Build framework (parallel) run: | - # Use parallel compilation and release mode - cargo build --all-features --release --jobs $(if [ "${{ runner.os }}" = "Windows" ]; then echo $NUMBER_OF_PROCESSORS; else nproc; fi) + # Use parallel compilation and release mode (Cargo automatically detects CPU count) + cargo build --all-features --release - name: Run core tests (parallel) run: | - # Run tests in parallel, excluding external validation to reduce time - cargo test --all-features --release --jobs $(if [ "${{ runner.os }}" = "Windows" ]; then echo $NUMBER_OF_PROCESSORS; else nproc; fi) --workspace --exclude pulseengine-mcp-external-validation + # Run tests in parallel, excluding external validation to reduce time (Cargo automatically detects CPU count) + cargo test --all-features --release --workspace --exclude pulseengine-mcp-external-validation - name: Run external validation tests run: | @@ -201,6 +214,7 @@ jobs: echo "✅ Validation tools built successfully" - name: Build timedate-mcp-server for stdio testing + shell: bash run: | # Check if timedate-mcp-server exists in external workspace if [ -d "../timedate-mcp" ]; then @@ -217,6 +231,7 @@ jobs: continue-on-error: true - name: Run stdio integration tests + shell: bash run: | # Only run if we have the timedate-mcp-server binary if [ -f "./target/release/timedate-mcp-server" ]; then @@ -229,6 +244,24 @@ jobs: env: RUST_LOG: info + - name: Cleanup cache before saving + run: | + echo "📊 Disk usage before cleanup:" + du -sh target 2>/dev/null || true + + # Remove test binaries (large and rebuilt every time) + find target -type f -name '*-????????????????' -executable -delete 2>/dev/null || true + + # Remove incremental compilation data (doesn't help across runs) + rm -rf target/debug/incremental + rm -rf target/release/incremental + + # Keep: compiled dependencies in target/*/deps/*.rlib + # Keep: build script outputs in target/*/build/*/out + + echo "📊 Disk usage after cleanup:" + du -sh target 2>/dev/null || true + # TODO: Re-enable server validation once we have a proper HTTP test server # - name: Run full compliance validation # run: | @@ -265,7 +298,6 @@ jobs: key: ${{ runner.os }}-cargo-stdio-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} restore-keys: | ${{ runner.os }}-cargo-stdio-1.88- - ${{ runner.os }}-cargo- - name: Build framework run: | @@ -280,20 +312,25 @@ jobs: continue-on-error: true - name: Build timedate-mcp-server + shell: bash run: | if [ -d "timedate-mcp" ]; then echo "Building timedate-mcp-server" cd timedate-mcp - cargo build --release - cd .. - # Copy binary to expected location - mkdir -p ./target/release - cp timedate-mcp/target/release/timedate-mcp-server ./target/release/ - echo "✅ timedate-mcp-server built successfully" + if cargo build --release; then + cd .. + # Copy binary to expected location + mkdir -p ./target/release + cp timedate-mcp/target/release/timedate-mcp-server ./target/release/ + echo "✅ timedate-mcp-server built successfully" + else + cd .. + echo "❌ timedate-mcp-server build failed - tests will be skipped" + fi else - echo "❌ timedate-mcp repository not available" - exit 1 + echo "âš ī¸ timedate-mcp repository not available - tests will be skipped" fi + continue-on-error: true - name: Install MCP Inspector run: | diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index bd20aa3e..66f4a784 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -61,6 +61,15 @@ jobs: echo "Clippy version: $(cargo clippy --version)" echo "Rustfmt version: $(cargo fmt --version)" + - name: Free up disk space + run: | + # Remove unnecessary tools and files to free up ~10GB + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + df -h + - name: Cache dependencies uses: actions/cache@v4 with: @@ -68,10 +77,9 @@ jobs: ~/.cargo/registry ~/.cargo/git target - key: ${{ runner.os }}-cargo-pr-release-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} + key: ${{ runner.os }}-cargo-pr-quick-1.88-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} restore-keys: | - ${{ runner.os }}-cargo-pr-1.88- - ${{ runner.os }}-cargo- + ${{ runner.os }}-cargo-pr-quick-1.88- - name: Check formatting run: cargo fmt --all -- --check @@ -95,10 +103,14 @@ jobs: - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov + - name: Clean previous coverage artifacts + run: | + # Remove previous coverage data but keep compiled dependencies + cargo llvm-cov clean --workspace + df -h + - name: Generate coverage report run: | - # Clean previous builds to save space, then generate coverage - cargo clean cargo llvm-cov test --all-features --workspace --lcov --output-path lcov.info cargo llvm-cov report --summary-only > coverage-summary.txt COVERAGE=$(grep -oP '\d+\.\d+(?=%)' coverage-summary.txt | head -1) @@ -106,10 +118,29 @@ jobs: - name: Check documentation run: | - # Clean before docs to save space, build docs for all packages - cargo clean + # Build docs for all packages cargo doc --all-features --no-deps + - name: Cleanup cache before saving + run: | + echo "📊 Disk usage before cleanup:" + du -sh target || true + + # Remove coverage-specific artifacts + rm -rf target/llvm-cov-target + rm -rf target/debug/.fingerprint/*-llvm-cov* + rm -rf target/*/debug/coverage* + + # Remove test binaries (large and rebuilt every time) + find target -type f -name '*-????????????????' -executable -delete 2>/dev/null || true + + # Remove incremental compilation data + rm -rf target/debug/incremental + rm -rf target/release/incremental + + echo "📊 Disk usage after cleanup:" + du -sh target || true + validation-specific-tests: name: Validation Framework Tests runs-on: ubuntu-latest diff --git a/.github/workflows/release-validation.yml b/.github/workflows/release-validation.yml index 1fdf2c4c..ccf85d91 100644 --- a/.github/workflows/release-validation.yml +++ b/.github/workflows/release-validation.yml @@ -13,6 +13,10 @@ on: env: CARGO_TERM_COLOR: always +permissions: + contents: write + packages: read + jobs: validate-release: name: Validate Release @@ -87,7 +91,6 @@ jobs: with: files: | mcp-validation-tools-*.tar.gz - release-compliance-report.html env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -145,6 +148,7 @@ jobs: cargo test --release --target ${{ matrix.target }} --package pulseengine-mcp-external-validation - name: Package platform-specific release + shell: bash run: | mkdir -p dist diff --git a/.github/workflows/scheduled-validation.yml b/.github/workflows/scheduled-validation.yml index 18407a08..e8c731ac 100644 --- a/.github/workflows/scheduled-validation.yml +++ b/.github/workflows/scheduled-validation.yml @@ -15,6 +15,10 @@ env: CARGO_TERM_COLOR: always RUST_LOG: info +permissions: + contents: write + issues: write + jobs: validate-external-servers: name: Validate External MCP Servers diff --git a/examples/hello-world-with-auth/src/main.rs b/examples/hello-world-with-auth/src/main.rs index f396ffe9..06b379f2 100644 --- a/examples/hello-world-with-auth/src/main.rs +++ b/examples/hello-world-with-auth/src/main.rs @@ -54,9 +54,6 @@ impl HelloWorldAuth { .name .unwrap_or_else(|| "Authenticated World".to_string()); - // In a real implementation, you could access the auth context here - // let auth = request_context.auth_context(); - info!("Hello tool called with name: {}", name); Ok(format!( "Hello, {name}! 🔐 (Secured with MCP Security Middleware)" diff --git a/mcp-auth/src/bin/mcp-auth-cli.rs b/mcp-auth/src/bin/mcp-auth-cli.rs index a60ddc51..65ee523c 100644 --- a/mcp-auth/src/bin/mcp-auth-cli.rs +++ b/mcp-auth/src/bin/mcp-auth-cli.rs @@ -1624,8 +1624,6 @@ async fn handle_rate_limit_operation( cli: &Cli, operation: RateLimitCommands, ) -> Result<(), Box> { - // use pulseengine_mcp_auth::models::Role; - match operation { RateLimitCommands::Stats => { let stats = auth_manager.get_rate_limit_stats().await; diff --git a/mcp-cli-derive/tests/test_mcp_backend.rs b/mcp-cli-derive/tests/test_mcp_backend.rs index 536a4852..2f5f9327 100644 --- a/mcp-cli-derive/tests/test_mcp_backend.rs +++ b/mcp-cli-derive/tests/test_mcp_backend.rs @@ -197,7 +197,6 @@ mod full_backend_tests { /// Test backend with delegate field #[test] - // #[ignore] // TODO: Fix trait disambiguation issues fn test_backend_with_delegate() { // Create a mock inner backend #[derive(Clone)] @@ -427,7 +426,6 @@ async fn test_async_methods() { /// Test full backend async methods #[tokio::test] -// #[ignore] // TODO: Fix trait disambiguation issues async fn test_full_backend_async() { #[derive(Clone, McpBackend)] struct FullAsyncBackend { diff --git a/mcp-cli/src/server.rs b/mcp-cli/src/server.rs index 278b9728..4eb72bf3 100644 --- a/mcp-cli/src/server.rs +++ b/mcp-cli/src/server.rs @@ -31,9 +31,6 @@ where info!("Server info: {:?}", _config.get_server_info()); // TODO: Integrate with actual server implementation - // let server = create_server_from_config(config).await?; - // server.run().await?; - Err(CliError::server_setup( "Server implementation not yet complete", )) diff --git a/mcp-external-validation/src/jsonrpc.rs b/mcp-external-validation/src/jsonrpc.rs index 2924524d..a377d477 100644 --- a/mcp-external-validation/src/jsonrpc.rs +++ b/mcp-external-validation/src/jsonrpc.rs @@ -8,10 +8,8 @@ use crate::{ report::{IssueSeverity, JsonRpcValidatorResult, TestScore, ValidationIssue}, }; use jsonschema::{Draft, JSONSchema}; -// Note: reqwest::Client used for real message collection use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; -// use std::collections::HashMap; // Removed unused import use tokio::io::AsyncWriteExt; use tracing::{debug, info, warn}; diff --git a/mcp-external-validation/src/mcp_validator.rs b/mcp-external-validation/src/mcp_validator.rs index 06ad691b..771bba77 100644 --- a/mcp-external-validation/src/mcp_validator.rs +++ b/mcp-external-validation/src/mcp_validator.rs @@ -9,7 +9,6 @@ use crate::{ }; use reqwest::Client; use serde::{Deserialize, Serialize}; -// use std::time::Duration; // Removed unused import use tracing::{debug, info, warn}; /// Client for the MCP Validator service diff --git a/mcp-macros/tests/integration_full_tests.rs b/mcp-macros/tests/integration_full_tests.rs index 8457ddc2..0fee79a3 100644 --- a/mcp-macros/tests/integration_full_tests.rs +++ b/mcp-macros/tests/integration_full_tests.rs @@ -186,54 +186,25 @@ mod tests { let _info = server.get_server_info(); let status = "Server is running"; // Simulate server status from the tool, since get_server_info returns ServerInfo assert_eq!(status, "Server is running"); - - // Skip tool method calls for now due to macro issues - //let count1 = server.increment_counter().await; - //let count2 = server.increment_counter().await; - //assert_eq!(count2, count1 + 1); } #[tokio::test] async fn test_data_processing() { let _server = FullIntegrationServer::with_defaults(); - let _valid_input = json!({"key": "value"}); - // Skip process_data calls for now - // let result = server - // .process_data(valid_input.clone(), "validate".to_string()) - // .await; - // assert!(result.is_ok()); - // - // let count_result = server - // .process_data(json!("test"), "count".to_string()) - // .await; - // assert!(count_result.is_ok()); + // TODO: Implement process_data tests when macro issues are resolved } #[tokio::test] async fn test_resource_access() { let _server = FullIntegrationServer::with_defaults(); - - // Skip resource test for now due to signature mismatch - // let config_result = server.read_resource("config".to_string()).await; - // assert!(config_result.is_ok()); - // assert!(config_result.unwrap().contains("dark")); - - // Skip missing resource test for now - // let missing_result = server.read_resource("nonexistent".to_string()).await; - // assert!(missing_result.is_err()); + // TODO: Implement resource tests when signature mismatch is resolved } #[tokio::test] async fn test_error_handling() { let _server = FullIntegrationServer::with_defaults(); - - // Skip risky_operation calls for now - // let success_result = server.risky_operation("success".to_string()).await; - // assert!(success_result.is_ok()); - // - // let fail_result = server.risky_operation("fail".to_string()).await; - // assert!(fail_result.is_err()); + // TODO: Implement error handling tests when macro issues are resolved } #[test] diff --git a/mcp-transport/src/config_tests.rs b/mcp-transport/src/config_tests.rs index abb2eb68..af47680e 100644 --- a/mcp-transport/src/config_tests.rs +++ b/mcp-transport/src/config_tests.rs @@ -160,39 +160,6 @@ mod tests { } #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig - fn test_cors_origins_variants() { - let cors_variants = vec![ - vec![], // No CORS origins - vec!["*".to_string()], // Wildcard - vec!["https://example.com".to_string()], // Single origin - vec![ - "https://app.example.com".to_string(), - "http://localhost:3000".to_string(), - "https://*.example.com".to_string(), - ], // Multiple origins - vec!["null".to_string()], // Null origin (for file://) - vec!["data:".to_string()], // Data URLs - ]; - - for _cors_origins in cors_variants { - let config = TransportConfig::Http { - host: Some("localhost".to_string()), - port: 8080, - }; - - // Should serialize correctly - let json = serde_json::to_string(&config).unwrap(); - let recovered: TransportConfig = serde_json::from_str(&json).unwrap(); - - if let TransportConfig::Http { .. } = recovered { - // Config validated successfully - } - } - } - - #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig fn test_host_variants() { let host_variants = vec![ "localhost", @@ -228,7 +195,6 @@ mod tests { } #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig fn test_port_variants() { let port_variants = vec![ 0, // System assigned @@ -274,7 +240,6 @@ mod tests { } #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig fn test_json_structure() { let config = TransportConfig::Http { host: Some("localhost".to_string()), @@ -292,29 +257,33 @@ mod tests { } #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig fn test_config_debug_display() { - let configs = vec![ - TransportConfig::Http { - host: Some("example.com".to_string()), - port: 443, - }, - TransportConfig::WebSocket { - host: Some("localhost".to_string()), - port: 8081, - }, - TransportConfig::Stdio, + let test_cases = vec![ + ( + TransportConfig::Http { + host: Some("example.com".to_string()), + port: 443, + }, + "Http", + ), + ( + TransportConfig::WebSocket { + host: Some("localhost".to_string()), + port: 8081, + }, + "WebSocket", + ), + (TransportConfig::Stdio, "Stdio"), ]; - for config in configs { + for (config, expected_variant) in test_cases { let debug_str = format!("{config:?}"); assert!(!debug_str.is_empty()); - assert!(debug_str.contains("TransportConfig")); + assert!(debug_str.contains(expected_variant)); } } #[test] - #[ignore] // CORS origins field doesn't exist in current TransportConfig fn test_config_clone() { let original = TransportConfig::Http { host: Some("original.com".to_string()),