From 7d4651997a57bc3ed5ad49e0e96baf41020979c8 Mon Sep 17 00:00:00 2001 From: Zhewen Li Date: Thu, 11 Sep 2025 15:34:36 -0700 Subject: [PATCH] [CI/Build] Add bc-linter to vLLM CI (#21234) Signed-off-by: zhewenli --- .github/.bc-linter.yml | 24 ++++++++++++++ .github/workflows/bc-lint.yml | 27 ++++++++++++++++ vllm/__init__.py | 6 ++++ vllm/_bc_linter.py | 59 +++++++++++++++++++++++++++++++++++ vllm/v1/core/sched/output.py | 5 +++ 5 files changed, 121 insertions(+) create mode 100644 .github/.bc-linter.yml create mode 100644 .github/workflows/bc-lint.yml create mode 100644 vllm/_bc_linter.py diff --git a/.github/.bc-linter.yml b/.github/.bc-linter.yml new file mode 100644 index 000000000000..443dfa45af22 --- /dev/null +++ b/.github/.bc-linter.yml @@ -0,0 +1,24 @@ +# doc: https://github.com/pytorch/test-infra/blob/main/tools/stronghold/docs/bc_linter_config.md +version: 1 +paths: +# We temporarily disable globally, and will only enable with `annotations.include` +# include: +# - "vllm/v1/attetion/*.py" +# - "vllm/v1/core/*.py" +exclude: + - "**/*.py" + +scan: + functions: true # check free functions and methods + classes: true # check classes/dataclasses + public_only: true # ignore names starting with "_" at any level + +annotations: + include: # decorators that force‑include a symbol + - name: "bc_linter_include" # matched by simple name or dotted suffix + propagate_to_members: false # for classes, include methods/inner classes + exclude: # decorators that force‑exclude a symbol + - name: "bc_linter_skip" # matched by simple name or dotted suffix + propagate_to_members: true # for classes, exclude methods/inner classes + +excluded_violations: [] # e.g. ["ParameterRenamed", "FieldTypeChanged"] diff --git a/.github/workflows/bc-lint.yml b/.github/workflows/bc-lint.yml new file mode 100644 index 000000000000..3795b046d780 --- /dev/null +++ b/.github/workflows/bc-lint.yml @@ -0,0 +1,27 @@ +name: BC Lint + +on: + pull_request: + types: + - opened + - synchronize + - reopened + +jobs: + bc_lint: + if: github.repository_owner == 'vllm-project' + runs-on: ubuntu-latest + steps: + - name: Run BC Lint Action + uses: pytorch/test-infra/.github/actions/bc-lint@main + with: + repo: ${{ github.event.pull_request.head.repo.full_name }} + base_sha: ${{ github.event.pull_request.base.sha }} + head_sha: ${{ github.event.pull_request.head.sha }} + suppression: ${{ contains(github.event.pull_request.labels.*.name, 'suppress-bc-linter') }} + docs_link: 'https://github.com/pytorch/test-infra/wiki/BC-Linter' + config_dir: .github + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true diff --git a/vllm/__init__.py b/vllm/__init__.py index 7b90fd3a241b..3a5c1b1ce0da 100644 --- a/vllm/__init__.py +++ b/vllm/__init__.py @@ -14,6 +14,8 @@ import typing import vllm.env_override # noqa: F401 MODULE_ATTRS = { + "bc_linter_skip": "._bc_linter:bc_linter_skip", + "bc_linter_include": "._bc_linter:bc_linter_include", "AsyncEngineArgs": ".engine.arg_utils:AsyncEngineArgs", "EngineArgs": ".engine.arg_utils:EngineArgs", "AsyncLLMEngine": ".engine.async_llm_engine:AsyncLLMEngine", @@ -54,6 +56,8 @@ if typing.TYPE_CHECKING: ScoringRequestOutput) from vllm.pooling_params import PoolingParams from vllm.sampling_params import SamplingParams + + from ._bc_linter import bc_linter_include, bc_linter_skip else: def __getattr__(name: str) -> typing.Any: @@ -70,6 +74,8 @@ else: __all__ = [ "__version__", + "bc_linter_skip", + "bc_linter_include", "__version_tuple__", "LLM", "ModelRegistry", diff --git a/vllm/_bc_linter.py b/vllm/_bc_linter.py new file mode 100644 index 000000000000..52a95dbee186 --- /dev/null +++ b/vllm/_bc_linter.py @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project +# vllm/_bc_linter.py +from __future__ import annotations + +from typing import Any, Callable, TypeVar, overload + +T = TypeVar("T") + + +@overload +def bc_linter_skip(obj: T) -> T: + ... + + +@overload +def bc_linter_skip(*, reason: str | None = ...) -> Callable[[T], T]: + ... + + +def bc_linter_skip(obj: Any = None, *, reason: str | None = None): + """ + No-op decorator to mark symbols/files for BC-linter suppression. + + Usage: + @bc_linter_skip + def legacy_api(...): ... + """ + + def _wrap(x: T) -> T: + return x + + return _wrap if obj is None else obj + + +@overload +def bc_linter_include(obj: T) -> T: + ... + + +@overload +def bc_linter_include(*, reason: str | None = ...) -> Callable[[T], T]: + ... + + +def bc_linter_include(obj: Any = None, *, reason: str | None = None): + """ + Usage: + @bc_linter_include + def public_api(...): ... + """ + + def _wrap(x: T) -> T: + return x + + return _wrap if obj is None else obj + + +__all__ = ["bc_linter_skip", "bc_linter_include"] diff --git a/vllm/v1/core/sched/output.py b/vllm/v1/core/sched/output.py index b5cd6c5c8af5..9888f2573575 100644 --- a/vllm/v1/core/sched/output.py +++ b/vllm/v1/core/sched/output.py @@ -6,6 +6,8 @@ from __future__ import annotations from dataclasses import dataclass from typing import TYPE_CHECKING, Optional +from vllm import bc_linter_include + if TYPE_CHECKING: import numpy as np import numpy.typing as npt @@ -19,6 +21,7 @@ if TYPE_CHECKING: from vllm.v1.request import Request +@bc_linter_include @dataclass class NewRequestData: @@ -80,6 +83,7 @@ class NewRequestData: ")") +@bc_linter_include @dataclass class CachedRequestData: @@ -109,6 +113,7 @@ class CachedRequestData: ) +@bc_linter_include @dataclass class SchedulerOutput: