CI/CD Pipeline #126
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main, develop] | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: [main, develop] | |
| schedule: | |
| - cron: '0 0 * * 0' | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| RUSTFLAGS: -D warnings | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| check: | |
| name: Code Quality Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "check" | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Run clippy (without YARA) | |
| run: cargo clippy --workspace --all-targets --no-default-features -- -D warnings | |
| - name: Check documentation | |
| run: cargo doc --workspace --no-deps --no-default-features | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| test-linux: | |
| name: Test - Linux | |
| runs-on: ubuntu-latest | |
| needs: check | |
| strategy: | |
| matrix: | |
| rust: [stable, beta, nightly] | |
| features: ['', '--features yara-scanning', '--no-default-features'] | |
| continue-on-error: ${{ matrix.rust == 'nightly' }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install YARA | |
| if: contains(matrix.features, 'yara-scanning') | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libyara-dev pkg-config | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "test-linux-${{ matrix.rust }}-${{ matrix.features }}" | |
| - name: Build | |
| run: cargo build --workspace --verbose ${{ matrix.features }} | |
| - name: Run tests | |
| run: cargo test --workspace --verbose ${{ matrix.features }} | |
| - name: Run doc tests | |
| run: cargo test --workspace --doc ${{ matrix.features }} | |
| test-windows: | |
| name: Test - Windows | |
| runs-on: windows-latest | |
| needs: check | |
| strategy: | |
| matrix: | |
| rust: [stable] | |
| features: ['', '--no-default-features'] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "test-windows-${{ matrix.rust }}" | |
| - name: Build | |
| run: cargo build --workspace --verbose ${{ matrix.features }} | |
| - name: Run tests | |
| run: cargo test --workspace --verbose ${{ matrix.features }} | |
| test-macos: | |
| name: Test - macOS | |
| runs-on: macos-latest | |
| needs: check | |
| strategy: | |
| matrix: | |
| rust: [stable] | |
| features: ['', '--no-default-features'] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "test-macos-${{ matrix.rust }}" | |
| - name: Build | |
| run: cargo build --workspace --verbose ${{ matrix.features }} | |
| - name: Run tests | |
| run: cargo test --workspace --verbose ${{ matrix.features }} | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ubuntu-latest | |
| needs: check | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Generate coverage | |
| run: cargo llvm-cov --workspace --no-default-features --lcov --output-path lcov.info | |
| - name: Upload to codecov.io | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| files: lcov.info | |
| fail_ci_if_error: false | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| security-audit: | |
| name: Security Audit | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Run cargo-audit | |
| uses: rustsec/audit-check@v1 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| ignore: RUSTSEC-2024-0436,RUSTSEC-2025-0134 | |
| dependency-review: | |
| name: Dependency Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@v4 | |
| build-release: | |
| name: Build Release - ${{ matrix.target }} | |
| runs-on: ${{ matrix.os }} | |
| needs: [test-linux, test-windows, test-macos] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| strategy: | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "release-${{ matrix.target }}" | |
| - name: Install musl tools | |
| if: matrix.target == 'x86_64-unknown-linux-musl' | |
| run: sudo apt-get install -y musl-tools | |
| - name: Build release (musl) | |
| if: matrix.target == 'x86_64-unknown-linux-musl' | |
| run: cargo build --release --target ${{ matrix.target }} --no-default-features --features vendored-openssl | |
| - name: Build release (non-musl) | |
| if: matrix.target != 'x86_64-unknown-linux-musl' | |
| run: cargo build --release --target ${{ matrix.target }} --no-default-features | |
| - name: Create archive | |
| shell: bash | |
| run: | | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| if [[ "${{ matrix.os }}" == "windows-latest" ]]; then | |
| ARCHIVE="ghost-${VERSION}-${{ matrix.target }}.zip" | |
| 7z a "${ARCHIVE}" ./target/${{ matrix.target }}/release/ghost-cli.exe ./target/${{ matrix.target }}/release/ghost-tui.exe | |
| else | |
| ARCHIVE="ghost-${VERSION}-${{ matrix.target }}.tar.gz" | |
| tar czf "${ARCHIVE}" -C ./target/${{ matrix.target }}/release ghost-cli ghost-tui | |
| fi | |
| echo "ARCHIVE=${ARCHIVE}" >> $GITHUB_ENV | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ghost-${{ matrix.target }} | |
| path: ${{ env.ARCHIVE }} | |
| release: | |
| name: Create Release | |
| runs-on: ubuntu-latest | |
| needs: build-release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| draft: false | |
| prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }} | |
| generate_release_notes: true | |
| files: artifacts/**/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| benchmark: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Run benchmarks | |
| run: cargo bench --no-default-features --no-fail-fast | |
| continue-on-error: true | |
| - name: Store benchmark result | |
| continue-on-error: true | |
| if: hashFiles('target/criterion/**/estimates.json') != '' | |
| uses: benchmark-action/github-action-benchmark@v1 | |
| with: | |
| tool: 'cargo' | |
| output-file-path: target/criterion/detection_performance/base/estimates.json | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| auto-push: true | |
| alert-threshold: '200%' | |
| comment-on-alert: true | |
| fail-on-alert: false | |
| all-checks-pass: | |
| name: All Checks Pass | |
| runs-on: ubuntu-latest | |
| needs: [check, test-linux, test-windows, test-macos, coverage, security-audit] | |
| if: always() | |
| steps: | |
| - name: Check job results | |
| run: | | |
| if [[ "${{ needs.check.result }}" != "success" ]] || \ | |
| [[ "${{ needs.test-linux.result }}" != "success" ]] || \ | |
| [[ "${{ needs.test-windows.result }}" != "success" ]] || \ | |
| [[ "${{ needs.test-macos.result }}" != "success" ]] || \ | |
| [[ "${{ needs.coverage.result }}" != "success" ]] || \ | |
| [[ "${{ needs.security-audit.result }}" != "success" ]]; then | |
| echo "One or more required checks failed" | |
| exit 1 | |
| fi | |
| echo "All required checks passed" |