Skip to content

[Chore][CI] Skip k3 builds when only docs/trivial files changed#2993

Merged
sammshen merged 11 commits intoLMCache:devfrom
sammshen:selective-k3-ci
Apr 13, 2026
Merged

[Chore][CI] Skip k3 builds when only docs/trivial files changed#2993
sammshen merged 11 commits intoLMCache:devfrom
sammshen:selective-k3-ci

Conversation

@sammshen
Copy link
Copy Markdown
Contributor

@sammshen sammshen commented Apr 9, 2026

Adds a path-based skip wrapper used by all 5 k3 test pipelines (correctness, integration, comprehensive, multiprocess, blend) so docs-only PRs auto-pass without spinning up GPU pods. Builds always run when any file under .github/ or .buildkite/ changes. Set K3_PATH_FILTER_DISABLE=1 to bypass.

What this PR does / why we need it:

Special notes for your reviewers:

If applicable:

  • this PR contains user facing changes - docs added
  • this PR contains unit tests

Note

Medium Risk
CI behavior changes to conditionally skip k3 GPU pipelines based on changed-path detection; misclassification or git diff edge cases could cause unintended skips and missed test coverage.

Overview
Adds a shared path-filter wrapper (common_scripts/path-filter.sh + upload-pipeline.sh) so k3 Buildkite pipelines can auto-pass without uploading pipeline.yml when all changed files are “trivial” (docs/markdown/license/etc.).

Updates the k3 test buildkite-pipeline.yml snippets to call the wrapper, and documents the behavior/overrides (never skip scheduled builds, always run when .buildkite/ changes, and allow forcing a run via the force-ci PR label).

Reviewed by Cursor Bugbot for commit 7c4b420. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds a path-based skip wrapper used by all 5 k3 test pipelines
(correctness, integration, comprehensive, multiprocess, blend) so docs-only
PRs auto-pass without spinning up GPU pods. Builds always run when any
file under .github/ or .buildkite/ changes. Set K3_PATH_FILTER_DISABLE=1
to bypass.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a path-based skip mechanism for Buildkite CI tests to avoid unnecessary runs on documentation-only changes. It adds a path-filter.sh script to detect changed files and an upload-pipeline.sh wrapper to conditionally skip pipeline uploads. Feedback includes simplifying the pull request detection logic and cleaning up redundant shell redirections in the git fetch commands.

_path_filter_get_changed_files() {
local base_branch base merge_base

if [[ "${BUILDKITE_PULL_REQUEST:-false}" != "false" && "${BUILDKITE_PULL_REQUEST:-}" != "" ]]; then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This condition to check for a pull request build is a bit complex. It can be simplified for better readability and maintainability by using the -n test to check for a non-empty string.

Suggested change
if [[ "${BUILDKITE_PULL_REQUEST:-false}" != "false" && "${BUILDKITE_PULL_REQUEST:-}" != "" ]]; then
if [[ -n "${BUILDKITE_PULL_REQUEST:-}" && "${BUILDKITE_PULL_REQUEST:-}" != "false" ]]; then

Comment on lines +61 to +62
git fetch --no-tags --depth=200 origin "$base_branch" >&2 2>/dev/null || \
git fetch --no-tags origin "$base_branch" >&2 2>/dev/null || true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The redirection >&2 2>/dev/null is a bit confusing. git fetch primarily outputs progress information to stderr. To silence it, 2>/dev/null is sufficient. The >&2 part redirects stdout to the original stderr, which is not necessary here and makes the command harder to read.

Suggested change
git fetch --no-tags --depth=200 origin "$base_branch" >&2 2>/dev/null || \
git fetch --no-tags origin "$base_branch" >&2 2>/dev/null || true
git fetch --no-tags --depth=200 origin "$base_branch" 2>/dev/null || \
git fetch --no-tags origin "$base_branch" 2>/dev/null || true

Samuel Shen added 2 commits April 9, 2026 19:07
k3 tests run on Buildkite, not GitHub Actions, so changes under .github/
(workflows, CODEOWNERS, PR templates, dependabot) have no effect on what
the k3 tests do. Move .github/* from the always-trigger list to the
trivial list. .buildkite/* stays force-trigger since it does drive the
k3 tests.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Restructure each k3 test so the path-filter logic lives entirely in the
repo. The Buildkite Web UI's upload command stays the literal
`buildkite-agent pipeline upload .buildkite/k3_tests/<test>/pipeline.yml`
it has always been -- but pipeline.yml is now a tiny one-step shim that
runs upload-pipeline.sh on steps.yml. The real test steps moved verbatim
into steps.yml.

Layout per test:
  pipeline.yml -- 1-step path-filter shim (was: full test pipeline)
  steps.yml    -- the actual test steps   (was: pipeline.yml content)

Because pipeline.yml is fetched fresh from the repo on every build,
edits to the filter / steps / shim now take effect on the next push
without anyone re-pasting anything in the Buildkite UI.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5bf35d9. Configure here.

Comment thread .buildkite/k3_tests/common_scripts/path-filter.sh
Samuel Shen added 2 commits April 10, 2026 04:44
- Never skip when BUILDKITE_SOURCE=schedule (nightly baseline builds
  with NEED_UPLOAD=true would silently not run if the latest commit
  on dev only touched docs).
- Simplify PR detection: use -n test instead of double != check.
- Remove redundant >&2 before 2>/dev/null on git fetch.

Addresses review feedback on PR LMCache#2993.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
_read_counters() iterates all metrics from the InMemoryMetricReader,
not just counters. When another library registers a histogram on the
same MeterProvider, the reader returns HistogramDataPoint objects
which lack .value (they have .sum/.count instead). Guard with hasattr.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Samuel Shen and others added 6 commits April 10, 2026 16:41
The filter step's git fetch hangs on GitHub's SSH host key verification
prompt because ephemeral K8s pods have no known_hosts entry. Set
GIT_SSH_COMMAND with StrictHostKeyChecking=accept-new so the fetch
auto-accepts new host keys without blocking.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
The pipeline.yml shim approach added an extra pod-provisioning wait to
every build. Instead, run the path filter directly in the upload step
by having buildkite-pipeline.yml call upload-pipeline.sh (which the
user pastes into the Buildkite UI once).

This restores the original 2-step flow: upload → test steps.
Skipped builds finish with just the upload pod (no GPU pod).

Requires a one-time re-paste of each test's buildkite-pipeline.yml
into the Buildkite UI Steps editor after merging.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Move one-time UI re-paste instructions to the PR description where
they belong instead of cluttering the README and BK_WEB_SETUP files.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Contributors can now add a "force-ci" label on the GitHub PR to bypass
the path filter and force a full k3 CI run. This replaces the
K3_PATH_FILTER_DISABLE env var which required access to the Buildkite
UI. Buildkite exposes PR labels via BUILDKITE_PULL_REQUEST_LABELS.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Copy link
Copy Markdown
Contributor

@ApostaC ApostaC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ApostaC ApostaC added the full Run comprehensive tests on this PR label Apr 11, 2026
@sammshen sammshen merged commit 6450c74 into LMCache:dev Apr 13, 2026
35 checks passed
@sammshen
Copy link
Copy Markdown
Contributor Author

this works now

fcczzz pushed a commit to fcczzz/LMCache that referenced this pull request Apr 13, 2026
…che#2993)

* [CI] Skip k3 builds when only docs/trivial files changed

Adds a path-based skip wrapper used by all 5 k3 test pipelines
(correctness, integration, comprehensive, multiprocess, blend) so docs-only
PRs auto-pass without spinning up GPU pods. Builds always run when any
file under .github/ or .buildkite/ changes. Set K3_PATH_FILTER_DISABLE=1
to bypass.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Treat .github/ as trivial in k3 path filter

k3 tests run on Buildkite, not GitHub Actions, so changes under .github/
(workflows, CODEOWNERS, PR templates, dependabot) have no effect on what
the k3 tests do. Move .github/* from the always-trigger list to the
trivial list. .buildkite/* stays force-trigger since it does drive the
k3 tests.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Move k3 path filter into pipeline.yml shim (no UI changes needed)

Restructure each k3 test so the path-filter logic lives entirely in the
repo. The Buildkite Web UI's upload command stays the literal
`buildkite-agent pipeline upload .buildkite/k3_tests/<test>/pipeline.yml`
it has always been -- but pipeline.yml is now a tiny one-step shim that
runs upload-pipeline.sh on steps.yml. The real test steps moved verbatim
into steps.yml.

Layout per test:
  pipeline.yml -- 1-step path-filter shim (was: full test pipeline)
  steps.yml    -- the actual test steps   (was: pipeline.yml content)

Because pipeline.yml is fetched fresh from the repo on every build,
edits to the filter / steps / shim now take effect on the next push
without anyone re-pasting anything in the Buildkite UI.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Fix path filter: never skip scheduled builds, clean up shell

- Never skip when BUILDKITE_SOURCE=schedule (nightly baseline builds
  with NEED_UPLOAD=true would silently not run if the latest commit
  on dev only touched docs).
- Simplify PR detection: use -n test instead of double != check.
- Remove redundant >&2 before 2>/dev/null on git fetch.

Addresses review feedback on PR LMCache#2993.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [BugFix] Fix test_l2 crash on HistogramDataPoint without .value

_read_counters() iterates all metrics from the InMemoryMetricReader,
not just counters. When another library registers a histogram on the
same MeterProvider, the reader returns HistogramDataPoint objects
which lack .value (they have .sum/.count instead). Guard with hasattr.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* Revert "[BugFix] Fix test_l2 crash on HistogramDataPoint without .value"

This reverts commit 7c3c32b.

* [CI] Fix path filter SSH host key prompt in ephemeral pods

The filter step's git fetch hangs on GitHub's SSH host key verification
prompt because ephemeral K8s pods have no known_hosts entry. Set
GIT_SSH_COMMAND with StrictHostKeyChecking=accept-new so the fetch
auto-accepts new host keys without blocking.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Run path filter in upload step, drop pipeline.yml shim

The pipeline.yml shim approach added an extra pod-provisioning wait to
every build. Instead, run the path filter directly in the upload step
by having buildkite-pipeline.yml call upload-pipeline.sh (which the
user pastes into the Buildkite UI once).

This restores the original 2-step flow: upload → test steps.
Skipped builds finish with just the upload pod (no GPU pod).

Requires a one-time re-paste of each test's buildkite-pipeline.yml
into the Buildkite UI Steps editor after merging.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Remove migration notes from permanent docs

Move one-time UI re-paste instructions to the PR description where
they belong instead of cluttering the README and BK_WEB_SETUP files.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Replace K3_PATH_FILTER_DISABLE env var with force-ci PR label

Contributors can now add a "force-ci" label on the GitHub PR to bypass
the path filter and force a full k3 CI run. This replaces the
K3_PATH_FILTER_DISABLE env var which required access to the Buildkite
UI. Buildkite exposes PR labels via BUILDKITE_PULL_REQUEST_LABELS.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

---------

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Co-authored-by: Samuel Shen <slshen@uchciago.edu>
Signed-off-by: fangchizheng <fangchizheng@mail.ustc.edu.cn>
Oasis-Git pushed a commit to Oasis-Git/LMCache that referenced this pull request Apr 13, 2026
…che#2993)

* [CI] Skip k3 builds when only docs/trivial files changed

Adds a path-based skip wrapper used by all 5 k3 test pipelines
(correctness, integration, comprehensive, multiprocess, blend) so docs-only
PRs auto-pass without spinning up GPU pods. Builds always run when any
file under .github/ or .buildkite/ changes. Set K3_PATH_FILTER_DISABLE=1
to bypass.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Treat .github/ as trivial in k3 path filter

k3 tests run on Buildkite, not GitHub Actions, so changes under .github/
(workflows, CODEOWNERS, PR templates, dependabot) have no effect on what
the k3 tests do. Move .github/* from the always-trigger list to the
trivial list. .buildkite/* stays force-trigger since it does drive the
k3 tests.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Move k3 path filter into pipeline.yml shim (no UI changes needed)

Restructure each k3 test so the path-filter logic lives entirely in the
repo. The Buildkite Web UI's upload command stays the literal
`buildkite-agent pipeline upload .buildkite/k3_tests/<test>/pipeline.yml`
it has always been -- but pipeline.yml is now a tiny one-step shim that
runs upload-pipeline.sh on steps.yml. The real test steps moved verbatim
into steps.yml.

Layout per test:
  pipeline.yml -- 1-step path-filter shim (was: full test pipeline)
  steps.yml    -- the actual test steps   (was: pipeline.yml content)

Because pipeline.yml is fetched fresh from the repo on every build,
edits to the filter / steps / shim now take effect on the next push
without anyone re-pasting anything in the Buildkite UI.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Fix path filter: never skip scheduled builds, clean up shell

- Never skip when BUILDKITE_SOURCE=schedule (nightly baseline builds
  with NEED_UPLOAD=true would silently not run if the latest commit
  on dev only touched docs).
- Simplify PR detection: use -n test instead of double != check.
- Remove redundant >&2 before 2>/dev/null on git fetch.

Addresses review feedback on PR LMCache#2993.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [BugFix] Fix test_l2 crash on HistogramDataPoint without .value

_read_counters() iterates all metrics from the InMemoryMetricReader,
not just counters. When another library registers a histogram on the
same MeterProvider, the reader returns HistogramDataPoint objects
which lack .value (they have .sum/.count instead). Guard with hasattr.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* Revert "[BugFix] Fix test_l2 crash on HistogramDataPoint without .value"

This reverts commit 7c3c32b.

* [CI] Fix path filter SSH host key prompt in ephemeral pods

The filter step's git fetch hangs on GitHub's SSH host key verification
prompt because ephemeral K8s pods have no known_hosts entry. Set
GIT_SSH_COMMAND with StrictHostKeyChecking=accept-new so the fetch
auto-accepts new host keys without blocking.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Run path filter in upload step, drop pipeline.yml shim

The pipeline.yml shim approach added an extra pod-provisioning wait to
every build. Instead, run the path filter directly in the upload step
by having buildkite-pipeline.yml call upload-pipeline.sh (which the
user pastes into the Buildkite UI once).

This restores the original 2-step flow: upload → test steps.
Skipped builds finish with just the upload pod (no GPU pod).

Requires a one-time re-paste of each test's buildkite-pipeline.yml
into the Buildkite UI Steps editor after merging.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Remove migration notes from permanent docs

Move one-time UI re-paste instructions to the PR description where
they belong instead of cluttering the README and BK_WEB_SETUP files.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Replace K3_PATH_FILTER_DISABLE env var with force-ci PR label

Contributors can now add a "force-ci" label on the GitHub PR to bypass
the path filter and force a full k3 CI run. This replaces the
K3_PATH_FILTER_DISABLE env var which required access to the Buildkite
UI. Buildkite exposes PR labels via BUILDKITE_PULL_REQUEST_LABELS.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

---------

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Co-authored-by: Samuel Shen <slshen@uchciago.edu>
ftian1 pushed a commit to ftian1/LMCache that referenced this pull request Apr 20, 2026
…che#2993)

* [CI] Skip k3 builds when only docs/trivial files changed

Adds a path-based skip wrapper used by all 5 k3 test pipelines
(correctness, integration, comprehensive, multiprocess, blend) so docs-only
PRs auto-pass without spinning up GPU pods. Builds always run when any
file under .github/ or .buildkite/ changes. Set K3_PATH_FILTER_DISABLE=1
to bypass.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Treat .github/ as trivial in k3 path filter

k3 tests run on Buildkite, not GitHub Actions, so changes under .github/
(workflows, CODEOWNERS, PR templates, dependabot) have no effect on what
the k3 tests do. Move .github/* from the always-trigger list to the
trivial list. .buildkite/* stays force-trigger since it does drive the
k3 tests.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Move k3 path filter into pipeline.yml shim (no UI changes needed)

Restructure each k3 test so the path-filter logic lives entirely in the
repo. The Buildkite Web UI's upload command stays the literal
`buildkite-agent pipeline upload .buildkite/k3_tests/<test>/pipeline.yml`
it has always been -- but pipeline.yml is now a tiny one-step shim that
runs upload-pipeline.sh on steps.yml. The real test steps moved verbatim
into steps.yml.

Layout per test:
  pipeline.yml -- 1-step path-filter shim (was: full test pipeline)
  steps.yml    -- the actual test steps   (was: pipeline.yml content)

Because pipeline.yml is fetched fresh from the repo on every build,
edits to the filter / steps / shim now take effect on the next push
without anyone re-pasting anything in the Buildkite UI.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Fix path filter: never skip scheduled builds, clean up shell

- Never skip when BUILDKITE_SOURCE=schedule (nightly baseline builds
  with NEED_UPLOAD=true would silently not run if the latest commit
  on dev only touched docs).
- Simplify PR detection: use -n test instead of double != check.
- Remove redundant >&2 before 2>/dev/null on git fetch.

Addresses review feedback on PR LMCache#2993.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [BugFix] Fix test_l2 crash on HistogramDataPoint without .value

_read_counters() iterates all metrics from the InMemoryMetricReader,
not just counters. When another library registers a histogram on the
same MeterProvider, the reader returns HistogramDataPoint objects
which lack .value (they have .sum/.count instead). Guard with hasattr.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* Revert "[BugFix] Fix test_l2 crash on HistogramDataPoint without .value"

This reverts commit 7c3c32b.

* [CI] Fix path filter SSH host key prompt in ephemeral pods

The filter step's git fetch hangs on GitHub's SSH host key verification
prompt because ephemeral K8s pods have no known_hosts entry. Set
GIT_SSH_COMMAND with StrictHostKeyChecking=accept-new so the fetch
auto-accepts new host keys without blocking.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Run path filter in upload step, drop pipeline.yml shim

The pipeline.yml shim approach added an extra pod-provisioning wait to
every build. Instead, run the path filter directly in the upload step
by having buildkite-pipeline.yml call upload-pipeline.sh (which the
user pastes into the Buildkite UI once).

This restores the original 2-step flow: upload → test steps.
Skipped builds finish with just the upload pod (no GPU pod).

Requires a one-time re-paste of each test's buildkite-pipeline.yml
into the Buildkite UI Steps editor after merging.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Remove migration notes from permanent docs

Move one-time UI re-paste instructions to the PR description where
they belong instead of cluttering the README and BK_WEB_SETUP files.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

* [CI] Replace K3_PATH_FILTER_DISABLE env var with force-ci PR label

Contributors can now add a "force-ci" label on the GitHub PR to bypass
the path filter and force a full k3 CI run. This replaces the
K3_PATH_FILTER_DISABLE env var which required access to the Buildkite
UI. Buildkite exposes PR labels via BUILDKITE_PULL_REQUEST_LABELS.

Signed-off-by: Samuel Shen <slshen@uchciago.edu>

---------

Signed-off-by: Samuel Shen <slshen@uchciago.edu>
Co-authored-by: Samuel Shen <slshen@uchciago.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full Run comprehensive tests on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants