Release 0.9.0: security, correctness and performance hardening #544
Workflow file for this run
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 | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUSTFLAGS: "-Dwarnings" | |
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "true" | |
| DOTNET_CLI_TELEMETRY_OPTOUT: "true" | |
| DOTNET_NOLOGO: "true" | |
| jobs: | |
| # Library testing and linting - no build artifacts needed | |
| check: | |
| name: Check & Test | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Warm up .NET SDK | |
| run: | | |
| dotnet --info | |
| dotnet new console -n warmup -o ${{ runner.temp }}/warmup | |
| dotnet build ${{ runner.temp }}/warmup | |
| - name: Install Mono and Z3 (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y mono-utils libz3-dev | |
| - name: Install Mono and Z3 (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| brew install mono z3 | |
| echo "LIBRARY_PATH=$(brew --prefix z3)/lib" >> "$GITHUB_ENV" | |
| - name: Install Z3 and dotnet-ildasm tool (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| dotnet tool install --global dotnet-ildasm | |
| # Download Z3 from GitHub releases (more reliable than Chocolatey) | |
| $z3Version = "4.13.4" | |
| $z3Url = "https://github.com/Z3Prover/z3/releases/download/z3-$z3Version/z3-$z3Version-x64-win.zip" | |
| $z3Zip = "$env:RUNNER_TEMP\z3.zip" | |
| $z3Dir = "$env:RUNNER_TEMP\z3" | |
| Invoke-WebRequest -Uri $z3Url -OutFile $z3Zip | |
| Expand-Archive -Path $z3Zip -DestinationPath $z3Dir | |
| $z3Root = Get-ChildItem -Path $z3Dir -Directory | Select-Object -First 1 | |
| echo "Z3_SYS_Z3_HEADER=$(Join-Path $z3Root.FullName 'include\z3.h')" >> $env:GITHUB_ENV | |
| echo "Z3_LIBRARY_PATH_OVERRIDE=$(Join-Path $z3Root.FullName 'bin')" >> $env:GITHUB_ENV | |
| # Add Z3 bin to PATH so libz3.dll is found at runtime | |
| echo "$(Join-Path $z3Root.FullName 'bin')" >> $env:GITHUB_PATH | |
| echo "Installed Z3 $z3Version at: $($z3Root.FullName)" | |
| ls (Join-Path $z3Root.FullName 'bin') | |
| shell: pwsh | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.os }}-check | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Run clippy | |
| run: cargo clippy --workspace --all-features --all-targets -- -D warnings | |
| - name: Check compilation | |
| run: cargo check --workspace --all-features | |
| - name: Run tests (Linux - full) | |
| if: runner.os == 'Linux' | |
| run: cargo test --workspace --release --features z3 --lib --bins --tests --verbose | |
| - name: Run tests (macOS/Windows - skip expensive tests) | |
| if: runner.os != 'Linux' | |
| run: cargo test --workspace --release --features z3,skip-expensive-tests --lib --bins --tests --verbose | |
| - name: Run doc tests (Linux only) | |
| if: runner.os == 'Linux' | |
| run: cargo test --workspace --release --doc --features z3 -- --test-threads=4 | |
| - name: Check documentation | |
| env: | |
| RUSTDOCFLAGS: "-Dwarnings" | |
| run: cargo doc -p dotscope --all-features --no-deps | |
| # Compiles and tests without the legacy-crypto feature (Linux only). Pinned to the declared | |
| # MSRV so this job also guards `rust-version`; the workspace check covers the default-feature | |
| # path, which `--no-default-features` alone would not. | |
| minimal-features: | |
| name: Minimal Features & MSRV | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/[email protected] | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: minimal-features | |
| - name: Check compilation (default features, whole workspace) | |
| run: cargo check --workspace --all-targets | |
| - name: Check compilation (no default features) | |
| run: cargo check -p dotscope --no-default-features | |
| - name: Run tests (no default features) | |
| run: cargo test -p dotscope --no-default-features --release --lib --bins --tests --verbose | |
| # Fuzzing on pushes to main or PRs targeting main | |
| fuzzing: | |
| name: Quick Fuzzing | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'push' && github.ref == 'refs/heads/main') || | |
| (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') || | |
| contains(github.event.head_commit.message, '[fuzz]') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Install Rust nightly | |
| uses: dtolnay/rust-toolchain@nightly | |
| - name: Install cargo-fuzz | |
| run: cargo install cargo-fuzz | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: fuzz-quick | |
| - name: Build fuzz targets | |
| run: cargo +nightly fuzz build --release | |
| working-directory: dotscope/fuzz | |
| # Every target gets the committed crash corpus. The inputs are PE-shaped, so they are | |
| # directly meaningful to `cilobject`/`assemblyview` and act as structured starting material | |
| # for the blob and body targets rather than starting them from scratch. | |
| - name: Seed corpora from committed regressions | |
| run: | | |
| for t in cilobject assemblyview signatures customattributes methodbody emulation; do | |
| mkdir -p "dotscope/fuzz/corpus/$t" | |
| cp dotscope/tests/samples/fuzz-regressions/* "dotscope/fuzz/corpus/$t/" || true | |
| done | |
| - name: Run quick fuzz test | |
| run: | | |
| for t in cilobject assemblyview signatures customattributes methodbody emulation; do | |
| echo "::group::fuzz $t" | |
| timeout 60 cargo +nightly fuzz run "$t" --release -- \ | |
| -max_total_time=40 -timeout=25 -rss_limit_mb=2048 || true | |
| echo "::endgroup::" | |
| done | |
| working-directory: dotscope/fuzz | |
| - name: Check for crashes | |
| run: | | |
| found=0 | |
| for t in cilobject assemblyview signatures customattributes methodbody emulation; do | |
| if [ -d "dotscope/fuzz/artifacts/$t" ] && [ "$(ls -A "dotscope/fuzz/artifacts/$t")" ]; then | |
| echo "Fuzzing found crashes in $t:" | |
| ls -la "dotscope/fuzz/artifacts/$t" | |
| found=1 | |
| fi | |
| done | |
| if [ "$found" = "1" ]; then | |
| exit 1 | |
| fi | |
| # Security audit on pushes to main or PRs targeting main | |
| security: | |
| name: Security Audit | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'push' && github.ref == 'refs/heads/main') || | |
| (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-audit | |
| run: cargo install cargo-audit | |
| - name: Run security audit | |
| run: cargo audit | |
| # Code coverage | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: llvm-tools-preview | |
| - name: Setup .NET SDK | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Warm up .NET SDK | |
| run: | | |
| dotnet --info | |
| dotnet new console -n warmup -o ${{ runner.temp }}/warmup | |
| dotnet build ${{ runner.temp }}/warmup | |
| - name: Install Mono and Z3 | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y mono-utils libz3-dev | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: coverage | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Generate code coverage | |
| run: cargo llvm-cov --workspace --features z3,skip-expensive-tests --lcov --output-path lcov.info --exclude dotscope-cli | |
| - name: Upload to codecov.io | |
| uses: codecov/codecov-action@v7 | |
| with: | |
| files: lcov.info | |
| fail_ci_if_error: true | |
| token: ${{ secrets.CODECOV_TOKEN }} |