Skip to content

feat(report): redesign evidence workbench and playground #66

feat(report): redesign evidence workbench and playground

feat(report): redesign evidence workbench and playground #66

Workflow file for this run

name: CI
on:
pull_request:
push:
branches:
- main
- master
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
report-app:
name: report app
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Node.js
uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
cache-dependency-path: web/report-app/package-lock.json
- name: Install dependencies
working-directory: web/report-app
run: npm ci
- name: Run report app tests
working-directory: web/report-app
run: npm test
- name: Build report app
working-directory: web/report-app
run: npm run build
- name: Check embedded assets
run: git diff --exit-code -- assets/report-app.js assets/report-app.css crates/reforge-output/assets/report-app.js crates/reforge-output/assets/report-app.css
- name: Install Playwright Chromium
working-directory: web/report-app
run: npx playwright install --with-deps chromium
- name: Run report app browser tests
working-directory: web/report-app
run: npm run test:e2e
- name: Upload browser test report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
with:
name: report-app-playwright
path: |
web/report-app/playwright-report
target/playwright/test-results
if-no-files-found: ignore
retention-days: 7
documentation:
name: documentation
runs-on: ubuntu-latest
env:
MDBOOK_VERSION: 0.5.4
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Test agent workflow distribution
run: sh scripts/test-install-agent-workflow.sh
- name: Test verified Unix installer
run: sh scripts/test-install.sh
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo
uses: Swatinem/rust-cache@v2
- name: Install mdBook
run: cargo install mdbook --version "$MDBOOK_VERSION" --locked
- name: Build documentation and sample
run: sh scripts/build-docs.sh target/docs-site
lint:
name: fmt and clippy
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache Cargo
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
package:
name: crates.io packages
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo
uses: Swatinem/rust-cache@v2
- name: Package core crates
run: |
cargo package --locked -p reforge-schema
cargo package --locked --list -p reforge-output > target/reforge-output-package-files.txt
cargo package --locked --list -p reforge-engine > target/reforge-engine-package-files.txt
cargo package --locked --list -p reforge-cli > target/reforge-cli-package-files.txt
grep -Fx assets/report-app.css target/reforge-output-package-files.txt
grep -Fx assets/report-app.js target/reforge-output-package-files.txt
grep -Fx build.rs target/reforge-engine-package-files.txt
grep -Fx src/main.rs target/reforge-cli-package-files.txt
test:
name: test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo
uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test --locked --workspace --all-targets --all-features
- name: Test PowerShell agent workflow distribution
if: runner.os == 'Windows'
shell: pwsh
run: .\scripts\test-install-agent-workflow.ps1
- name: Build
run: cargo build --locked --workspace
- name: Test verified PowerShell installer
if: runner.os == 'Windows'
shell: pwsh
run: .\scripts\test-install.ps1
- name: Smoke test analyses
shell: pwsh
run: |
cargo run --locked -p reforge-cli -- analyze . --output json --output-file target/codebase.json --metrics-output target/metrics.json --reproducible
cargo run --locked -p reforge-cli -- analyze . --analysis dataflow --output json --output-file target/dataflow.json --flow-ir-output target/flow-ir.json --reproducible
cargo run --locked -p reforge-cli -- analyze . --analysis codebase --analysis dataflow --output json --output-file target/combined.json --reproducible
$codebase = Get-Content target/codebase.json -Raw | ConvertFrom-Json
$report = Get-Content target/combined.json -Raw | ConvertFrom-Json
if ($codebase.schema_version -ne 27) { throw "unexpected report schema" }
if ($codebase.provenance.identity_scheme -ne "reforge-identity-v7") { throw "unexpected identity scheme" }
if (-not $codebase.coverage.codebase.rules) { throw "missing Codebase rule coverage" }
if (-not $report.coverage.dataflow.languages) { throw "missing Dataflow language coverage" }
if ($report.producer.name -ne "reforge.analyze") { throw "unexpected report producer" }
self-audit:
name: full-rule self audit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo
uses: Swatinem/rust-cache@v2
- name: Build release analyzer
run: cargo build --locked --release -p reforge-cli
- name: Run isolated and combined self analyses twice
run: |
mkdir -p target/self-audit
target/release/reforge analyze . --analysis codebase --output json --output-file target/self-audit/codebase.json --metrics-output target/self-audit/metrics.json --reproducible
target/release/reforge analyze . --analysis codebase --output json --output-file target/self-audit/codebase-repeat.json --metrics-output target/self-audit/metrics-repeat.json --reproducible
target/release/reforge analyze . --analysis dataflow --output json --output-file target/self-audit/dataflow.json --flow-ir-output target/self-audit/flow-ir.json --reproducible
target/release/reforge analyze . --analysis dataflow --output json --output-file target/self-audit/dataflow-repeat.json --flow-ir-output target/self-audit/flow-ir-repeat.json --reproducible
target/release/reforge analyze . --analysis codebase --analysis dataflow --output json --output-file target/self-audit/combined.json --reproducible
target/release/reforge analyze . --analysis codebase --analysis dataflow --output json --output-file target/self-audit/combined-repeat.json --reproducible
- name: Verify self-audit policy
shell: bash
run: |
cmp target/self-audit/codebase.json target/self-audit/codebase-repeat.json
cmp target/self-audit/dataflow.json target/self-audit/dataflow-repeat.json
cmp target/self-audit/combined.json target/self-audit/combined-repeat.json
cmp target/self-audit/metrics.json target/self-audit/metrics-repeat.json
cmp target/self-audit/flow-ir.json target/self-audit/flow-ir-repeat.json
test "$(jq '.schema_version' target/self-audit/codebase.json)" = "27"
test "$(jq '.summary.issue_count' target/self-audit/codebase.json)" = "0"
jq -S '[.issues[] | {id, content_fingerprint}] | sort_by(.id)' target/self-audit/codebase.json > target/self-audit/codebase-issues.json
jq -S '[.issues[] | {id, content_fingerprint}] | sort_by(.id)' target/self-audit/dataflow.json > target/self-audit/dataflow-issues.json
jq -S -s 'add | sort_by(.id)' target/self-audit/codebase-issues.json target/self-audit/dataflow-issues.json > target/self-audit/isolated-union.json
jq -S '[.issues[] | {id, content_fingerprint}] | sort_by(.id)' target/self-audit/combined.json > target/self-audit/combined-issues.json
cmp target/self-audit/isolated-union.json target/self-audit/combined-issues.json
jq -s -e '.[0].coverage.codebase == .[1].coverage.codebase' target/self-audit/codebase.json target/self-audit/combined.json
jq -s -e '.[0].coverage.dataflow == .[1].coverage.dataflow' target/self-audit/dataflow.json target/self-audit/combined.json
jq -e '
.coverage.dataflow.status as $status
| ($status == "observed" or $status == "partial")
and (if $status == "partial" then (.coverage.dataflow.limitations | length) > 0 else true end)
and all(
.coverage.dataflow.languages[];
if .status == "unsupported" then (.limitations | length) > 0 else true end
)
' target/self-audit/dataflow.json
- name: Upload self-audit evidence
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
with:
name: reforge-self-audit
path: target/self-audit
retention-days: 7