docs: delegate DCO validation to CI (#955) #3
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: | |
| pull_request: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| - ready_for_review | |
| - converted_to_draft | |
| push: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| dco: | |
| if: github.event_name == 'pull_request' | |
| name: DCO sign-off | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Plain API check instead of KineticCafe/actions-dco: that action decodes | |
| # the full commit *comparison*, whose file entries carry | |
| # `blob_url: null` for submodule bumps, and its strict decoder rejects | |
| # the whole payload — so any PR touching a submodule can never pass. | |
| # A DCO check only needs the commit list. | |
| - name: Check commit sign-offs | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR: ${{ github.event.pull_request.number }} | |
| run: | | |
| set -euo pipefail | |
| unsigned=$(gh api --paginate \ | |
| "repos/${GITHUB_REPOSITORY}/pulls/${PR}/commits?per_page=100" \ | |
| --jq '.[] | |
| | select(.commit.message | test("(?m)^Signed-off-by: .+ <.+@.+>") | not) | |
| | .sha[0:10] + " " + (.commit.message | split("\n")[0])') | |
| if [ -n "$unsigned" ]; then | |
| echo "$unsigned" | while read -r line; do | |
| echo "::error::no Signed-off-by trailer on commit $line" | |
| done | |
| echo '::error::add sign-offs with: git rebase --signoff origin/main' | |
| exit 1 | |
| fi | |
| echo "all commits carry a Signed-off-by trailer" | |
| attribution-script: | |
| name: Attribution script checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Lint attribution scripts | |
| run: shellcheck .github/scripts/attribution-notice.sh .github/scripts/attribution-notice-test.sh | |
| - name: Run attribution behavior tests | |
| run: bash .github/scripts/attribution-notice-test.sh | |
| rust-format: | |
| name: Rust formatting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --all --check | |
| cargo-metadata: | |
| name: Locked Cargo metadata | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| - name: Check locked Cargo metadata | |
| run: cargo metadata --locked --no-deps --format-version 1 | |
| cpu-unit-tests: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: CPU unit tests (${{ matrix.package }}) | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - package: pegainfer-build | |
| needs_protobuf: false | |
| - package: pegainfer-frontend | |
| needs_protobuf: true | |
| - package: pegainfer-sim | |
| needs_protobuf: true | |
| - package: kvbm-logical | |
| needs_protobuf: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install protobuf compiler | |
| if: matrix.needs_protobuf | |
| run: sudo apt-get update && sudo apt-get install -y protobuf-compiler | |
| - name: Run unit tests | |
| run: cargo test --release --locked -p ${{ matrix.package }} --lib | |
| cpu-clippy: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: CPU Clippy | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| components: clippy | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install protobuf compiler | |
| run: sudo apt-get update && sudo apt-get install -y protobuf-compiler | |
| - name: Run CPU Clippy | |
| run: >- | |
| cargo clippy --release --locked | |
| -p pegainfer-build | |
| -p pegainfer-frontend | |
| -p pegainfer-sim | |
| -p kvbm-logical | |
| --all-targets -- -D warnings | |
| simulated-frontend-e2e: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: Simulated frontend E2E | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install protobuf compiler | |
| run: sudo apt-get update && sudo apt-get install -y protobuf-compiler | |
| - name: Run simulated frontend E2E tests | |
| run: cargo test --release --locked -p pegainfer-sim --test frontend_e2e | |
| qwen3-cuda-compile: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: Qwen3 CUDA compile (sm_80) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install CUDA toolkit | |
| uses: Jimver/cuda-toolkit@v0.2.35 | |
| with: | |
| cuda: "13.0.2" | |
| linux-local-args: '["--toolkit"]' | |
| method: network | |
| sub-packages: '["nvcc", "nvrtc-dev", "cudart-dev"]' | |
| non-cuda-sub-packages: '["libcublas-dev", "libcurand-dev"]' | |
| - name: Install build dependencies | |
| run: sudo apt-get update && sudo apt-get install -y protobuf-compiler libibverbs-dev | |
| - name: Compile default Qwen3 targets | |
| run: cargo check --release --locked -p pegainfer-server --all-targets | |
| env: | |
| CUDA_PATH: /usr/local/cuda | |
| PEGAINFER_CUDA_SM: "80" | |
| PEGAINFER_NVCC_JOBS: "2" | |
| qwen3-cuda-clippy: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: Qwen3 CUDA Clippy (sm_80) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| components: clippy | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install CUDA toolkit | |
| uses: Jimver/cuda-toolkit@v0.2.35 | |
| with: | |
| cuda: "13.0.2" | |
| linux-local-args: '["--toolkit"]' | |
| method: network | |
| sub-packages: '["nvcc", "nvrtc-dev", "cudart-dev"]' | |
| non-cuda-sub-packages: '["libcublas-dev", "libcurand-dev"]' | |
| - name: Install build dependencies | |
| run: sudo apt-get update && sudo apt-get install -y protobuf-compiler libibverbs-dev | |
| # Clippy lints only the packages named here; dependencies are compiled, not linted. | |
| # pegainfer-cupti is out: building it needs CUPTI headers the toolkit above omits. | |
| - name: Run Qwen3 CUDA Clippy | |
| run: >- | |
| cargo clippy --release --locked | |
| -p pegainfer-server | |
| -p pegainfer-qwen3 | |
| -p pegainfer-core | |
| -p pegainfer-kernels | |
| -p pegainfer-kv-cache | |
| -p pegainfer-kv-offload | |
| -p pegainfer-sample | |
| -p pegainfer-bench | |
| --all-targets -- -D warnings | |
| env: | |
| CUDA_PATH: /usr/local/cuda | |
| PEGAINFER_CUDA_SM: "80" | |
| PEGAINFER_NVCC_JOBS: "2" | |
| qwen35-cuda: | |
| if: github.event_name == 'push' || github.event.pull_request.draft == false | |
| name: Qwen3.5 CUDA ${{ matrix.gate }} (sm_80) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - gate: Compile | |
| cargo_command: check | |
| trailing_args: "" | |
| - gate: Clippy | |
| cargo_command: clippy | |
| trailing_args: "-- -D warnings" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: nightly-2026-07-10 | |
| components: clippy | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| with: | |
| version: "v0.16.0" | |
| - name: Install CUDA toolkit | |
| uses: Jimver/cuda-toolkit@v0.2.35 | |
| with: | |
| cuda: "13.0.2" | |
| linux-local-args: '["--toolkit"]' | |
| method: network | |
| sub-packages: '["nvcc", "nvrtc-dev", "cudart-dev"]' | |
| non-cuda-sub-packages: '["libcublas-dev", "libcurand-dev"]' | |
| - name: Install Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.10" | |
| - name: Install Qwen3.5 build dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler libibverbs-dev | |
| python -m pip install "triton==3.7.1" | |
| - name: Run Qwen3.5 ${{ matrix.gate }} | |
| run: >- | |
| cargo ${{ matrix.cargo_command }} --release --locked | |
| -p pegainfer-qwen35 --features qwen35 --all-targets | |
| ${{ matrix.trailing_args }} | |
| env: | |
| CUDA_PATH: /usr/local/cuda | |
| PEGAINFER_CUDA_SM: "80" | |
| PEGAINFER_NVCC_JOBS: "2" | |
| PEGAINFER_TRITON_PYTHON: python |