Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/actions/macos/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: macos dependencies
description: installs dependencies required to compile quantus-cli on macos

runs:
using: composite
steps:
- name: rust compilation prerequisites (macos)
run: |
brew update
OK=0
for i in 1 2 3; do
if brew install protobuf llvm; then OK=1; break; fi
echo "brew install attempt $i failed (often transient ghcr.io), retrying in 15s..."
sleep 15
done
if [ "$OK" -ne 1 ]; then echo "::error::brew install protobuf llvm failed after 3 attempts"; exit 1; fi
curl https://sh.rustup.rs -sSf | sh -s -- -y
brew uninstall cmake
set +e
brew install openssl cmake 2>&1 | sed '/already installed and up-to-date/d'
brew_status=${PIPESTATUS[0]}
set -e

if [ "$brew_status" -ne 0 ]; then
exit "$brew_status"
fi

rustup toolchain install
rustup target add wasm32-unknown-unknown
rustup component add rustfmt --toolchain nightly
rustup component add clippy rust-src
shell: bash
- name: Set LIBCLANG_PATH for clang-sys (bindgen/rocksdb etc.)
run: |
# Homebrew LLVM provides libclang.dylib; clang-sys looks for libclang.dylib.
# ARM (Apple Silicon): /opt/homebrew/opt/llvm/lib
# x86 (Intel): /usr/local/opt/llvm/lib
DIR=
if command -v brew >/dev/null 2>&1; then
PREFIX="$(brew --prefix llvm 2>/dev/null)"
[ -n "$PREFIX" ] && [ -d "$PREFIX/lib" ] && ls "$PREFIX/lib"/libclang*.dylib 1>/dev/null 2>&1 && DIR="$PREFIX/lib"
fi
if [ -z "$DIR" ] && [ -d /usr/local/opt/llvm/lib ] && ls /usr/local/opt/llvm/lib/libclang*.dylib 1>/dev/null 2>&1; then
DIR=/usr/local/opt/llvm/lib
fi
if [ -z "$DIR" ] && [ -d /opt/homebrew/opt/llvm/lib ] && ls /opt/homebrew/opt/llvm/lib/libclang*.dylib 1>/dev/null 2>&1; then
DIR=/opt/homebrew/opt/llvm/lib
fi
if [ -n "$DIR" ]; then
echo "LIBCLANG_PATH=$DIR" >> $GITHUB_ENV
fi
echo "LIBCLANG_PATH=${LIBCLANG_PATH:-not set}"
shell: bash
51 changes: 51 additions & 0 deletions .github/actions/ubuntu/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: ubuntu dependencies
description: installs dependencies required to compile quantus-cli on ubuntu

runs:
using: composite
steps:
- name: rust compilation prerequisites (ubuntu)
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo rm -f /etc/apt/sources.list.d/azure-cli.list
sudo apt-get update -yqq
sudo apt-get install -yqq --no-install-recommends \
libclang-dev \
clang \
protobuf-compiler
# Unconditionally install the toolchain pinned in rust-toolchain.toml
# (rustup >=1.28 no longer auto-installs the active toolchain, and
# `rustup update` only refreshes already-installed toolchains).
# This installs the channel + every component/target listed in the file.
rustup toolchain install
rustup target add wasm32-unknown-unknown
rustup component add rustfmt --toolchain nightly
rustup component add clippy rust-src
shell: bash
- name: Set LIBCLANG_PATH for clang-sys (bindgen/rocksdb etc.)
run: |
# Runner may set wrong LIBCLANG_PATH; use known dirs then find then llvm-config.
DIR=
for ver in 18 17 16 15 14; do
D="/usr/lib/llvm-$ver/lib"
if [ -d "$D" ] && ls "$D"/libclang*.so* 1>/dev/null 2>&1; then
DIR=$D
break
fi
done
if [ -z "$DIR" ]; then
LIB=$(find /usr -name 'libclang.so*' \( -type f -o -type l \) 2>/dev/null | head -1)
[ -n "$LIB" ] && DIR=$(dirname "$LIB")
fi
if [ -z "$DIR" ] && command -v llvm-config >/dev/null 2>&1; then
D=$(llvm-config --libdir 2>/dev/null)
if [ -n "$D" ] && [ -d "$D" ] && ls "$D"/libclang*.so* 1>/dev/null 2>&1; then
DIR=$D
fi
fi
if [ -n "$DIR" ] && [ "$DIR" != "." ]; then
echo "LIBCLANG_PATH=$DIR" >> $GITHUB_ENV
fi
echo "LIBCLANG_PATH=${LIBCLANG_PATH:-not set}"
shell: bash
118 changes: 67 additions & 51 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# Principle of least privilege: all jobs only read the repo (checkout + cargo).
# Per-job override is unnecessary because no job pushes, creates releases or PRs.
permissions:
contents: read

env:
CARGO_INCREMENTAL: 0
CARGO_TERM_COLOR: always
CARGO_NET_RETRY: 10
CARGO_NET_TIMEOUT: 60

jobs:
fast-checks:
name: 🏁 Fast Checks (Format)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install required components
run: rustup component add rustfmt --toolchain nightly
- uses: actions/checkout@v5
- uses: ./.github/actions/ubuntu
- name: Install taplo
run: cargo install taplo-cli --locked
- name: Run format checks
Expand All @@ -42,33 +49,31 @@ jobs:
name: 🛠️ Build & Test Matrix
needs: fast-checks
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: true
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
rust:
- stable
steps:
- uses: actions/checkout@v4
- name: Install Rust ${{ matrix.rust }}
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- name: Install dependencies (Ubuntu)
- uses: actions/checkout@v5
- name: Setup Ubuntu
if: matrix.os == 'ubuntu-latest'
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo rm -f /etc/apt/sources.list.d/azure-cli.list
sudo apt-get update -yqq
sudo apt-get install -yqq --no-install-recommends \
libclang-dev \
protobuf-compiler
- name: Install dependencies (macOS)
uses: ./.github/actions/ubuntu
- name: Setup macOS
if: matrix.os == 'macos-latest'
run: |
brew install protobuf
uses: ./.github/actions/macos
- name: Cache cargo registry & target
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }}
restore-keys: |
${{ runner.os }}-cargo-build-
- name: Build (all targets)
run: cargo build --locked
- name: Build (library only)
Expand All @@ -80,20 +85,20 @@ jobs:
name: 🤖 Analysis (Clippy & Doc)
needs: fast-checks
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v5
- uses: ./.github/actions/ubuntu
- name: Cache cargo registry & target
uses: actions/cache@v5
with:
components: clippy, rust-src
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo rm -f /etc/apt/sources.list.d/azure-cli.list
sudo apt-get update -yqq
sudo apt-get install -yqq --no-install-recommends \
libclang-dev \
protobuf-compiler
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-analysis-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }}
restore-keys: |
${{ runner.os }}-cargo-analysis-
- name: Run clippy (all targets)
run: SKIP_CIRCUIT_BUILD=1 cargo clippy --all-targets --locked -- -D warnings
- name: Run clippy (library only)
Expand All @@ -104,35 +109,46 @@ jobs:
run: SKIP_CIRCUIT_BUILD=1 cargo doc --locked --no-deps --document-private-items

security-audit:
name: 🔒 Security Audit
name: 🔐 Security Audit (non-blocking)
needs: fast-checks
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Cache cargo-audit binary
uses: actions/cache@v5
with:
path: ~/.cargo/bin/cargo-audit
key: cargo-audit-bin-${{ runner.os }}-0.22.1
- name: Cache RustSec advisory database
uses: actions/cache@v5
with:
path: ~/.cargo/advisory-db
key: cargo-advisory-db-${{ runner.os }}-${{ github.run_id }}
restore-keys: |
cargo-advisory-db-${{ runner.os }}-
- name: Install cargo-audit
run: cargo install cargo-audit --locked
- name: Run security audit
run: |
if ! command -v cargo-audit >/dev/null 2>&1; then
cargo install cargo-audit --locked --version 0.22.1
fi
- name: Run cargo audit (informational only)
# Only this step is non-blocking — every other step in this job
# (checkout, caches, cargo-audit install) must fail loudly so we
# don't silently skip the audit.
continue-on-error: true
run: cargo audit

examples:
name: 📚 Examples
needs: fast-checks
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo rm -f /etc/apt/sources.list.d/azure-cli.list
sudo apt-get update -yqq
sudo apt-get install -yqq --no-install-recommends \
libclang-dev \
protobuf-compiler
- uses: actions/checkout@v5
- uses: ./.github/actions/ubuntu
- name: Build examples
run: |
cargo build --examples --locked
run: cargo build --examples --locked
- name: Check example compilation
run: |
for example in examples/*.rs; do
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: CodeQL

on:
push:
branches: [main]
pull_request:
branches: [main]

# No scheduled scans by design: every code change reaches main via push or PR,
# both of which trigger this workflow. Security advisories for Rust dependencies
# are independently caught by `cargo audit` in ci.yml.

permissions:
contents: read
security-events: write
actions: read

jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
# `actions` covers GitHub Actions workflow hygiene (e.g. the
# `actions/missing-workflow-permissions` rule).
- language: actions
build-mode: none
# `rust` is GA since Oct 2025 and supports build-mode `none`,
# so we get source-level analysis without compiling the crate.
# Note: `cargo audit` in ci.yml stays as the authoritative source
# for known CVEs in dependencies; CodeQL adds taint/quality checks
# on our own source.
- language: rust
build-mode: none
steps:
- uses: actions/checkout@v5
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
queries: security-and-quality
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
Loading
Loading