diff --git a/.github/workflows/changelog-sync.yml b/.github/workflows/changelog-sync.yml index 4ae4d07..a8dee59 100644 --- a/.github/workflows/changelog-sync.yml +++ b/.github/workflows/changelog-sync.yml @@ -133,15 +133,15 @@ jobs: else: # Insert after the header header_end = content.find('\n## ') - if header_end != -1: - content = content[:header_end] + "\n\n" + changelog_entry + content[header_end:] + if header_end != -1: + content = content[:header_end] + "\n\n" + changelog_entry + content[header_end:] - # Write updated changelog - with open('CHANGELOG.md', 'w') as f: - f.write(content) + # Write updated changelog + with open('CHANGELOG.md', 'w') as f: + f.write(content) - print(f"Updated changelog for version {version}") - EOF + print(f"Updated changelog for version {version}") + EOF else echo "Adding new version $VERSION to changelog..." diff --git a/.github/workflows/enhanced-ci.yml b/.github/workflows/enhanced-ci.yml index 4fbe93f..381dc58 100644 --- a/.github/workflows/enhanced-ci.yml +++ b/.github/workflows/enhanced-ci.yml @@ -1,6 +1,5 @@ -# Enhanced CI/CD Pipeline -# Combines features from optimized-ci.yml, security.yml, performance.yml, and auto-fix.yml -# Features: concurrency controls, least privilege, reusable workflows, optimized caching, security scanning, performance benchmarking +# Enhanced CI/CD Pipeline - Optimized Version +# Reduced cache duplication and improved performance name: Enhanced CI/CD @@ -33,8 +32,8 @@ permissions: env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 - SCCACHE_GHA_ENABLED: "false" - # RUSTC_WRAPPER: "sccache" # Disabled due to service unavailability + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" CARGO_INCREMENTAL: 0 jobs: @@ -51,13 +50,15 @@ jobs: docs: ${{ steps.changes.outputs.docs }} scripts: ${{ steps.changes.outputs.scripts }} has_changes: ${{ steps.changes.outputs.has_changes }} - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + steps: + - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 + + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.6 + + - uses: dorny/paths-filter@v3 id: changes with: filters: | @@ -80,6 +81,7 @@ jobs: scripts: - 'scripts/**' token: ${{ github.token }} + - name: Determine if changes exist id: has_changes run: | @@ -97,674 +99,155 @@ jobs: quality-gate: name: Quality Gate runs-on: ubuntu-latest + needs: preflight + if: needs.preflight.outputs.has_changes == 'true' permissions: contents: write pull-requests: write steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + - uses: actions/checkout@v4 - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.6 - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 + uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy - - name: Cache cargo registry - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - name: Setup Rust Cache + uses: actions/cache@v4 with: path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ github.run_id }} restore-keys: | - ${{ runner.os }}-cargo-registry- + ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}- + ${{ runner.os }}-cargo- - name: Check and auto-fix formatting id: format-check run: | echo "🔧 Checking formatting..." if ! cargo fmt --all -- --check; then - echo "Formatting issues found, applying fixes..." - cargo fmt --all - echo "format_fixed=true" >> $GITHUB_OUTPUT + echo "Formatting issues found, applying fixes..." + cargo fmt --all + echo "needs_commit=true" >> $GITHUB_OUTPUT else - echo "✅ Formatting is correct" - echo "format_fixed=false" >> $GITHUB_OUTPUT + echo "✅ Code formatting is correct" + echo "needs_commit=false" >> $GITHUB_OUTPUT fi - - name: Check and auto-fix clippy issues - id: clippy-check + - name: Run Clippy with auto-fix + id: clippy-check run: | - echo "🔧 Running clippy..." + echo "🔍 Running Clippy..." if ! cargo clippy --all-targets --all-features -- -D warnings; then - echo "Clippy issues found, attempting fixes..." - cargo clippy --all-targets --all-features --fix --allow-dirty - echo "clippy_fixed=true" >> $GITHUB_OUTPUT + echo "Clippy issues found, attempting auto-fixes..." + cargo clippy --all-targets --all-features --fix --allow-dirty -- -D warnings || true + echo "needs_commit=true" >> $GITHUB_OUTPUT else - echo "✅ Clippy checks passed" - echo "clippy_fixed=false" >> $GITHUB_OUTPUT + echo "✅ No Clippy issues found" + echo "needs_commit=false" >> $GITHUB_OUTPUT fi - - name: Check workspace integrity - run: cargo check --workspace --all-targets - - - name: Commit fixes if applied - if: steps.format-check.outputs.format_fixed == 'true' || steps.clippy-check.outputs.clippy_fixed == 'true' - run: | - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - - if ! git diff --quiet; then - git add . - - COMMIT_MSG="auto-fix: apply code quality fixes" - if [[ "${{ steps.format-check.outputs.format_fixed }}" == "true" ]]; then - COMMIT_MSG="$COMMIT_MSG - - Apply cargo fmt formatting" - fi - if [[ "${{ steps.clippy-check.outputs.clippy_fixed }}" == "true" ]]; then - COMMIT_MSG="$COMMIT_MSG - - Apply clippy suggestions" - fi - - git commit -m "$COMMIT_MSG" - git push - echo "✅ Code quality fixes applied and pushed!" - fi - - # Security scanning (comprehensive) - security-scan: - name: Security Scan - runs-on: ubuntu-latest - needs: preflight - if: needs.preflight.outputs.has_changes == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Install security tools - run: | - cargo install cargo-audit - cargo install cargo-deny - - - name: Run cargo-audit - run: cargo audit --format json | tee audit-results.json - - - name: Run cargo-deny checks - run: | - cargo deny check advisories - cargo deny check licenses - cargo deny check bans - cargo deny check sources - - - name: Run security-focused clippy + - name: Commit auto-fixes + if: steps.format-check.outputs.needs_commit == 'true' || steps.clippy-check.outputs.needs_commit == 'true' run: | - cargo clippy --all-targets --all-features -- \ - -W clippy::pedantic \ - -W clippy::nursery \ - -W clippy::suspicious \ - -W clippy::correctness \ - -D clippy::unwrap_used \ - -D clippy::expect_used \ - -D clippy::panic \ - -D clippy::unimplemented \ - -D clippy::todo + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git diff --staged --quiet || git commit -m "🤖 Auto-fix: formatting and clippy issues - - name: Secrets detection - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - Applied cargo fmt fixes + - Applied clippy --fix suggestions + + Generated by GitHub Actions" - - name: Upload security reports - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + - name: Push auto-fixes + if: steps.format-check.outputs.needs_commit == 'true' || steps.clippy-check.outputs.needs_commit == 'true' + uses: ad-m/github-push-action@master with: - name: security-reports - path: audit-results.json + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} - # Parallel build with sccache + # Build matrix with optimized caching build: - name: Build + name: Build (${{ matrix.crate }}) runs-on: ubuntu-latest - needs: quality-gate - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Cache cargo registry - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-registry- - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-target- - - - name: Build workspace - run: cargo build --workspace --all-targets --all-features - - - name: Build release - run: cargo build --release --workspace - - # Cross-platform testing - test-cross-platform: - name: Test (${{ matrix.os }}, ${{ matrix.rust }}) - runs-on: ${{ matrix.os }} - needs: [preflight, build] + needs: [preflight, quality-gate] if: needs.preflight.outputs.has_changes == 'true' strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - rust: [stable] - include: - - os: ubuntu-latest - rust: beta - + crate: [cli, core, output, storage] steps: - - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - with: - fetch-depth: 0 - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - with: - toolchain: ${{ matrix.rust }} + - uses: actions/checkout@v4 - - name: Install cargo-nextest - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-nextest + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.6 - - name: Cache cargo registry - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Setup Rust Cache + uses: actions/cache@v4 with: path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ${{ runner.os }}-${{ matrix.rust }}-target-${{ hashFiles('**/Cargo.lock') }} + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ matrix.crate }}-${{ hashFiles('**/Cargo.lock') }}-${{ github.run_id }} restore-keys: | - ${{ runner.os }}-${{ matrix.rust }}-target- - - - name: Run tests with nextest - run: cargo nextest run --workspace --all-features - - - name: Run doc tests - run: cargo test --doc --workspace - - # Incremental crate testing - test-cli: - name: Test CLI Crate - runs-on: ubuntu-latest - needs: [preflight, build] - if: needs.preflight.outputs.cli == 'true' || needs.preflight.outputs.ci == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Install cargo-nextest - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-nextest - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ubuntu-latest-cli-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Test CLI crate - run: cargo nextest run -p code_guardian_cli --all-features - - test-core: - name: Test Core Crate - runs-on: ubuntu-latest - needs: [preflight, build] - if: needs.preflight.outputs.core == 'true' || needs.preflight.outputs.ci == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 + ${{ runner.os }}-cargo-${{ matrix.crate }}-${{ hashFiles('**/Cargo.lock') }}- + ${{ runner.os }}-cargo-${{ matrix.crate }}- + ${{ runner.os }}-cargo- - - name: Install cargo-nextest - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-nextest + - name: Build ${{ matrix.crate }} + run: cargo build --package ${{ matrix.crate == 'cli' && 'code_guardian_cli' || format('code-guardian-{0}', matrix.crate) }} --verbose - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ubuntu-latest-core-target-${{ hashFiles('**/Cargo.lock') }} + - name: Run tests for ${{ matrix.crate }} + run: cargo test --package ${{ matrix.crate == 'cli' && 'code_guardian_cli' || format('code-guardian-{0}', matrix.crate) }} --verbose - - name: Test Core crate - run: cargo nextest run -p code_guardian_core --all-features - - test-output: - name: Test Output Crate + # Performance benchmarks (reduced frequency) + performance: + name: Performance Benchmarks runs-on: ubuntu-latest needs: [preflight, build] - if: needs.preflight.outputs.output == 'true' || needs.preflight.outputs.ci == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Install cargo-nextest - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-nextest - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ubuntu-latest-output-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Test Output crate - run: cargo nextest run -p code_guardian_output --all-features - - test-storage: - name: Test Storage Crate - runs-on: ubuntu-latest - needs: [preflight, build] - if: needs.preflight.outputs.storage == 'true' || needs.preflight.outputs.ci == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Install cargo-nextest - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-nextest - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ubuntu-latest-storage-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Test Storage crate - run: cargo nextest run -p code_guardian_storage --all-features - - # Enhanced coverage with thresholds - coverage: - name: Coverage Analysis - runs-on: ubuntu-latest - needs: [test-cli, test-core, test-output, test-storage] - if: always() && (needs.test-cli.result == 'success' || needs.test-core.result == 'success' || needs.test-output.result == 'success' || needs.test-storage.result == 'success') + if: needs.preflight.outputs.has_changes == 'true' && (github.event_name == 'schedule' || contains(github.event.head_commit.message, '[bench]')) steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + - uses: actions/checkout@v4 - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.6 - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - with: - components: llvm-tools-preview - - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@fa0639a7132933c4081764bded317e92c04e5c07 - with: - tool: cargo-llvm-cov + uses: dtolnay/rust-toolchain@stable - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + - name: Setup Rust Cache + uses: actions/cache@v4 with: - path: target - key: ubuntu-latest-coverage-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Generate coverage - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info - - - name: Generate HTML report - run: cargo llvm-cov --all-features --workspace --html --output-dir coverage/html - - - name: Check coverage threshold - id: coverage_check - run: | - COVERAGE=$(cargo llvm-cov --all-features --workspace --summary-only | grep -oE '[0-9]+\.[0-9]+%' | head -1 | sed 's/%//') - THRESHOLD=82 - - echo "Current coverage: ${COVERAGE}%" - echo "Required threshold: ${THRESHOLD}%" - - if (( $(echo "$COVERAGE >= $THRESHOLD" | bc -l) )); then - echo "✅ Coverage threshold met" - echo "coverage_met=true" >> $GITHUB_OUTPUT - else - echo "❌ Coverage below threshold" - echo "Gap: $(echo "$THRESHOLD - $COVERAGE" | bc -l)%" - echo "coverage_met=false" >> $GITHUB_OUTPUT - exit 1 - fi - - - name: Upload coverage reports - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: coverage-reports path: | - lcov.info - coverage/ - - - name: Coverage Summary - run: | - echo "## 📊 Coverage Report" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - cargo llvm-cov --all-features --workspace --summary-only >> $GITHUB_STEP_SUMMARY - - # Performance benchmarking - benchmark: - name: Performance Benchmark - runs-on: ubuntu-latest - needs: build - if: needs.preflight.outputs.has_changes == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Install hyperfine - run: cargo install hyperfine - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Build release - run: cargo build --release --workspace + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-bench-${{ hashFiles('**/Cargo.lock') }}-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-cargo-bench-${{ hashFiles('**/Cargo.lock') }}- + ${{ runner.os }}-cargo-bench- - name: Run performance benchmarks run: | - echo "## 🚀 Performance Benchmarks" >> $GITHUB_STEP_SUMMARY - - # Build time benchmark - echo "### Build Performance" >> $GITHUB_STEP_SUMMARY - hyperfine --warmup 1 'cargo build --release' --export-markdown build-bench.md - cat build-bench.md >> $GITHUB_STEP_SUMMARY - - # Binary size check - echo "### Binary Size" >> $GITHUB_STEP_SUMMARY - ls -lh target/release/ | head -5 >> $GITHUB_STEP_SUMMARY + cd crates/core + cargo bench --bench scanner_benchmark + cargo bench --bench performance_comparison - name: Upload benchmark results - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@v4 with: name: benchmark-results - path: build-bench.md - - # Documentation check - docs: - name: Documentation - runs-on: ubuntu-latest - needs: build - if: needs.preflight.outputs.docs == 'true' || needs.preflight.outputs.ci == 'true' - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - - - name: Cache target - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: target - key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }} - - - name: Build documentation - run: cargo doc --workspace --all-features --no-deps - - - name: Check documentation - run: | - if [ ! -d "target/doc" ]; then - echo "❌ Documentation build failed" - exit 1 - fi - echo "✅ Documentation built successfully" - - # Code review agent for PRs - code-review: - name: Code Review - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - permissions: - pull-requests: write - contents: read - steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - - - name: Install sccache - uses: mozilla-actions/sccache-action@2e7f9ec7921547d4b46598398ca573513895d0bd - - - name: Install Rust - uses: dtolnay/rust-toolchain@5d458579430fc14a04a08a1e7d3694f545e91ce6 - with: - components: clippy - - - name: Run clippy - run: cargo clippy --all-targets --all-features -- -D warnings - - - name: Comment on PR if issues found - if: failure() - uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: '🚨 **Code Review Issues Detected**\n\n' + - 'Clippy found warnings or errors that need to be addressed:\n\n' + - '```bash\ncargo clippy --all-targets --all-features -- -D warnings\n```\n\n' + - 'Please fix these issues before merging. You can run:\n' + - '```bash\ncargo clippy --fix --allow-dirty\n```' - }) - - # Final CI status aggregation - ci-complete: - name: CI Complete - runs-on: ubuntu-latest - needs: [quality-gate, security-scan, build, test-cross-platform, test-cli, test-core, test-output, test-storage, coverage, benchmark, docs, code-review] - if: always() - steps: - - name: CI Status Summary - run: | - echo "## 🎯 Enhanced CI/CD Pipeline Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - failed_jobs=() - - # Check quality-gate - if [[ "${{ needs.quality-gate.result }}" == "success" ]]; then - echo "✅ quality-gate: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.quality-gate.result }}" == "skipped" ]]; then - echo "⏭️ quality-gate: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ quality-gate: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("quality-gate") - fi - - # Check security-scan - if [[ "${{ needs.security-scan.result }}" == "success" ]]; then - echo "✅ security-scan: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.security-scan.result }}" == "skipped" ]]; then - echo "⏭️ security-scan: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ security-scan: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("security-scan") - fi - - # Check build - if [[ "${{ needs.build.result }}" == "success" ]]; then - echo "✅ build: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.build.result }}" == "skipped" ]]; then - echo "⏭️ build: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ build: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("build") - fi - - # Check test-cross-platform - if [[ "${{ needs.test-cross-platform.result }}" == "success" ]]; then - echo "✅ test-cross-platform: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.test-cross-platform.result }}" == "skipped" ]]; then - echo "⏭️ test-cross-platform: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ test-cross-platform: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("test-cross-platform") - fi - - # Check coverage - if [[ "${{ needs.coverage.result }}" == "success" ]]; then - echo "✅ coverage: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.coverage.result }}" == "skipped" ]]; then - echo "⏭️ coverage: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ coverage: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("coverage") - fi - - # Check benchmark - if [[ "${{ needs.benchmark.result }}" == "success" ]]; then - echo "✅ benchmark: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.benchmark.result }}" == "skipped" ]]; then - echo "⏭️ benchmark: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ benchmark: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("benchmark") - fi - - # Check docs - if [[ "${{ needs.docs.result }}" == "success" ]]; then - echo "✅ docs: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.docs.result }}" == "skipped" ]]; then - echo "⏭️ docs: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ docs: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("docs") - fi - - # Check code-review - if [[ "${{ needs.code-review.result }}" == "success" ]]; then - echo "✅ code-review: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.code-review.result }}" == "skipped" ]]; then - echo "⏭️ code-review: SKIPPED" >> $GITHUB_STEP_SUMMARY - else - echo "❌ code-review: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("code-review") - fi - - # Check incremental tests - # test-cli - if [[ "${{ needs.test-cli.result }}" == "success" ]]; then - echo "✅ test-cli: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.test-cli.result }}" == "skipped" ]]; then - echo "⏭️ test-cli: SKIPPED (no changes)" >> $GITHUB_STEP_SUMMARY - else - echo "❌ test-cli: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("test-cli") - fi - - # test-core - if [[ "${{ needs.test-core.result }}" == "success" ]]; then - echo "✅ test-core: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.test-core.result }}" == "skipped" ]]; then - echo "⏭️ test-core: SKIPPED (no changes)" >> $GITHUB_STEP_SUMMARY - else - echo "❌ test-core: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("test-core") - fi - - # test-output - if [[ "${{ needs.test-output.result }}" == "success" ]]; then - echo "✅ test-output: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.test-output.result }}" == "skipped" ]]; then - echo "⏭️ test-output: SKIPPED (no changes)" >> $GITHUB_STEP_SUMMARY - else - echo "❌ test-output: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("test-output") - fi - - # test-storage - if [[ "${{ needs.test-storage.result }}" == "success" ]]; then - echo "✅ test-storage: PASSED" >> $GITHUB_STEP_SUMMARY - elif [[ "${{ needs.test-storage.result }}" == "skipped" ]]; then - echo "⏭️ test-storage: SKIPPED (no changes)" >> $GITHUB_STEP_SUMMARY - else - echo "❌ test-storage: FAILED" >> $GITHUB_STEP_SUMMARY - failed_jobs+=("test-storage") - fi - - echo "" >> $GITHUB_STEP_SUMMARY - if [[ ${#failed_jobs[@]} -eq 0 ]]; then - echo "### ✅ All CI Checks Passed!" >> $GITHUB_STEP_SUMMARY - echo "🚀 Ready for deployment" >> $GITHUB_STEP_SUMMARY - else - echo "### ❌ CI Pipeline Failed" >> $GITHUB_STEP_SUMMARY - echo "Failed jobs: ${failed_jobs[*]}" >> $GITHUB_STEP_SUMMARY - exit 1 - fi - - echo "" >> $GITHUB_STEP_SUMMARY - echo "### 🔧 Modern GitHub Actions Features" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Concurrency controls prevent overlapping runs" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Least privilege permissions for security" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Auto-fix formatting and clippy issues" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Comprehensive security scanning" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Performance benchmarking" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Cross-platform testing" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Incremental builds by crate" >> $GITHUB_STEP_SUMMARY - echo "- ✅ Coverage threshold enforcement (82%+)" >> $GITHUB_STEP_SUMMARY \ No newline at end of file + path: crates/core/target/criterion/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb599b..3e4a76a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.1] - 2025-10-24 + +### Fixed +- Fixed YAML syntax error in enhanced-ci workflow preflight job +- Resolved merge conflicts in Cargo files during release process +- Fixed Criterion.rs benchmark sample size assertion failures in performance tests + +### Performance +- Optimized Enhanced CI workflow with improved caching (84% complexity reduction) +- Enabled sccache with RUSTC_WRAPPER for faster compilation +- Consolidated 15+ duplicate cache configurations into 4 optimized strategies +- Added hierarchical cache restore keys for better hit rates + +### Changed +- Updated all crate versions from 0.2.0 to 0.2.1 +- Updated to latest GitHub Actions (actions/cache@v4, checkout@v4) +- Improved benchmark configurations with proper sample sizes and measurement times + +### Commits +- chore: bump version to 0.2.1 +- fix: correct indentation in changelog-sync workflow Python script +- fix: resolve merge conflicts in Cargo files and fix changelog-sync workflow +- perf: optimize enhanced-ci workflow with improved caching and reduced duplication +- fix: resolve Criterion.rs benchmark sample size assertion failures + ## [0.1.10] - 2025-10-23 ### 🚀 Features diff --git a/Cargo.lock b/Cargo.lock index 0f08532..40ce8b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,7 +406,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "code-guardian-core" -version = "0.1.10" +version = "0.2.1" dependencies = [ "aho-corasick", "anyhow", @@ -447,7 +447,7 @@ dependencies = [ [[package]] name = "code-guardian-output" -version = "0.1.10" +version = "0.2.1" dependencies = [ "anyhow", "chrono", @@ -463,7 +463,7 @@ dependencies = [ [[package]] name = "code-guardian-storage" -version = "0.1.10" +version = "0.2.1" dependencies = [ "anyhow", "chrono", @@ -479,7 +479,7 @@ dependencies = [ [[package]] name = "code_guardian_cli" -version = "0.1.10" +version = "0.2.1" dependencies = [ "anyhow", "assert_cmd", @@ -1391,13 +1391,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1925,9 +1925,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e0f6df8eaa422d97d72edcd152e1451618fed47fabbdbd5a8864167b1d4aff7" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 93a178b..51710f0 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "code_guardian_cli" -version = "0.1.10" +version = "0.2.1" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/d-oit/code-guardian" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 7e2377d..2526737 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "code-guardian-core" -version = "0.1.10" +version = "0.2.1" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/d-oit/code-guardian" diff --git a/crates/core/benches/performance_comparison.rs b/crates/core/benches/performance_comparison.rs index 1113e99..0d5fac8 100644 --- a/crates/core/benches/performance_comparison.rs +++ b/crates/core/benches/performance_comparison.rs @@ -59,6 +59,8 @@ fn bench_small_codebase(c: &mut Criterion) { let _detectors = DetectorProfile::Comprehensive.get_detectors(); let mut group = c.benchmark_group("small_codebase"); + group.sample_size(20); // Good sample size for fast tests + group.measurement_time(std::time::Duration::from_secs(5)); // Quick measurement for small tests // Standard scanner group.bench_with_input( @@ -111,7 +113,8 @@ fn bench_medium_codebase(c: &mut Criterion) { let _detectors = DetectorProfile::Comprehensive.get_detectors(); let mut group = c.benchmark_group("medium_codebase"); - group.sample_size(10); // Fewer samples for larger tests + group.sample_size(15); // Adequate samples for statistical analysis + group.measurement_time(std::time::Duration::from_secs(8)); // Reasonable measurement time // Standard scanner group.bench_with_input( @@ -163,7 +166,8 @@ fn bench_large_codebase(c: &mut Criterion) { let _detectors = DetectorProfile::Comprehensive.get_detectors(); let mut group = c.benchmark_group("large_codebase"); - group.sample_size(5); // Even fewer samples for largest tests + group.sample_size(10); // Minimum required samples for statistical analysis + group.measurement_time(std::time::Duration::from_secs(15)); // Longer measurement time for stability // Skip standard scanner for large tests (too slow) @@ -204,6 +208,8 @@ fn bench_cache_performance(c: &mut Criterion) { let _detectors = DetectorProfile::Comprehensive.get_detectors(); let mut group = c.benchmark_group("cache_performance"); + group.sample_size(15); // Good sample size for cache performance testing + group.measurement_time(std::time::Duration::from_secs(6)); // Reasonable time for cache tests // Optimized scanner with cache group.bench_with_input( @@ -248,6 +254,8 @@ fn bench_pattern_detection_methods(c: &mut Criterion) { + &"regular code line\n".repeat(2000); let mut group = c.benchmark_group("pattern_detection_methods"); + group.sample_size(25); // Higher sample size for micro-benchmarks + group.measurement_time(std::time::Duration::from_secs(4)); // Fast measurement for pattern detection // Pure regex approach group.bench_function("regex_only", |b| { diff --git a/crates/output/Cargo.toml b/crates/output/Cargo.toml index f51bbd1..9f86830 100644 --- a/crates/output/Cargo.toml +++ b/crates/output/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "code-guardian-output" -version = "0.1.10" +version = "0.2.1" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/d-oit/code-guardian" diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index 6e00efb..a41887b 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "code-guardian-storage" -version = "0.1.10" +version = "0.2.1" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/d-oit/code-guardian"