Skip to content

feat: Add llm-d release profiles - #72

Merged
openshift-merge-bot[bot] merged 23 commits into
openshift-psap:mainfrom
albertoperdomo2:feat/add-release-profiles
Jun 26, 2026
Merged

openshift-merge-bot[bot] merged 23 commits into
openshift-psap:mainfrom
albertoperdomo2:feat/add-release-profiles

Conversation

@albertoperdomo2

@albertoperdomo2 albertoperdomo2 commented Jun 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Add common llm_d release profiles and extend the shared GuideLLM launcher to support rate-dependent benchmark expansions.

This PR adapts the common Benchflow deployment and benchmark profiles to the current Forge llm_d shape instead of copying Benchflow definitions literally.

llm_d profiles

  • Add deployment-oriented presets:
    • deployment-approximate-prefix-cache
    • deployment-precise-prefix-cache
    • deployment-distributed-default
  • Factor shared smoke settings into smoke-base
  • Keep smoke presets explicit about their scheduler source while avoiding duplication

llm_d benchmark workloads

  • Add heavy-heterogeneous
  • Add multi-turn
  • Keep concurrent-1k-1k
  • Model these as workloads.benchmarks.* entries in Forge config

Shared GuideLLM launcher

  • Move build_guidellm_args(...) into shared guidellm utils
  • Support list-valued benchmark args such as rates: [...]
  • Support rate-aware expansion only when a benchmark argument contains {rate}, {N*rate}, or {rate*N}
  • Keep plain --rates=... benchmarks as a single GuideLLM invocation
  • Run one GuideLLM benchmark per rate only for rate-dependent workloads such as:
    • prefix_count={2*rate}
    • max_requests={10*rate}

Documentation and tests

  • Update the llm_d README to reflect the current orchestration entrypoints and multi-rate {rate} expansion behavior
  • Add unit coverage for:
    • rate expansion
    • job rendering behavior
    • CLI argument building
    • orchestration preset/profile validation

Behavior notes

  • Benchmark configuration resolution merges workload defaults with benchmark-specific settings
  • Plain multi-rate workloads remain a single GuideLLM run
  • Rate-dependent workloads expand into one run per rate and write per-run result artifacts

Summary by CodeRabbit

Release Notes

  • New Features
    • Added rate-based benchmark expansion for GuideLLM, including {rate} expression substitution and per-rate job execution.
    • GuideLLM results are now collected per expanded run with an index manifest.
    • Introduced new LLM-D deployment profiles for approximate/precise prefix caching and distributed default scaling.
    • Improved LLM-D orchestration to run per resolved run-spec (model/profile combinations) with scoped artifacts.
  • Documentation
    • Updated LLM-D orchestration docs for run-spec workflow and rate expansion.
  • Tests
    • Added extensive unit and end-to-end tests covering rate expansion, job rendering, and rate-split result parsing.
  • Chores
    • Updated Caliper export configuration with a dedicated workspace setting.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds per-rate benchmark expansion to GuideLLM and refactors LLM_D orchestration around deployment profiles and run-spec loops, updating KServe rendering, runtime resolution, prepare/test/cleanup phases, presets, workloads, tests, and docs. Caliper only updates the resolve_visualize_config signature.

Changes

GuideLLM Multi-Rate Benchmark Expansion

Layer / File(s) Summary
GuideLLM rate expansion utilities
projects/guidellm/toolbox/run_guidellm_benchmark/utils.py, projects/guidellm/toolbox/run_guidellm_benchmark/__init__.py, projects/guidellm/tests/test_run_guidellm_benchmark.py
Introduces GuideLLMRun, rate-expression expansion, CLI arg building, public export of build_guidellm_args, and tests for per-rate substitution, passthrough multi-rate inputs, and list-valued rate rendering.
GuideLLM job rendering and result collection
projects/guidellm/toolbox/run_guidellm_benchmark/main.py, projects/guidellm/toolbox/run_guidellm_benchmark/templates/guidellm_job.yaml.j2
render_guidellm_job_from_parts now chooses direct or shell-based multi-run execution; the template drops its hardcoded command block. The runner accepts a full image reference, stores expanded runs, and writes per-run result files plus an index manifest.
GuideLLM parser support for split artifacts
projects/guidellm/postprocess/guidellm/parsing/parsers.py, projects/guidellm/tests/test_postprocess_parser.py
GuideLLMParser now matches benchmarks-rate-*.json, sorts artifacts before parsing, and the test covers parsing multiple split benchmark files into separate records.

LLM_D Profile-Driven Deployment and RunSpec Orchestration

Layer / File(s) Summary
Deployment profiles, workloads, and presets
projects/llm_d/orchestration/config.d/deployments.yaml, projects/llm_d/orchestration/config.d/runtime.yaml, projects/llm_d/orchestration/config.d/workloads.yaml, projects/llm_d/orchestration/presets.d/presets.yaml
Adds deployment profiles, rewrites runtime defaults to model_name and deployment_profile, reorganizes workloads around top-level job metadata and multi-rate benchmarks, and rewrites presets around reusable deployment presets and benchmark lists.
Runtime config and RunSpec resolution
projects/llm_d/orchestration/runtime_config.py
Adds RunSpec, normalizes list-like runtime inputs, rejects legacy runtime.model_key, resolves model/benchmark helpers from the new config layout, computes benchmark job names, and activates per-run runtime state.
Inference service rendering from deployment profiles
projects/kserve/toolbox/deploy_llmisvc/utils.py
render_inference_service_from_parts now consumes model_name, model_slug, and deployment_profile, derives source URI and cache naming from the model name, and builds serving resources, vLLM args, and router scheduler config from deployment profile data.
Prepare and test flow per run spec
projects/llm_d/orchestration/prepare_sequence.py, projects/llm_d/orchestration/prepare_phase.py, projects/llm_d/orchestration/test_phase.py
Prepare and test phases now loop over run specs, scope artifacts per run, derive model cache inputs from runtime helpers, render inference manifests from deployment profiles, compute test labels from runtime values, run smoke and benchmark phases per active run, and clean benchmark resources by resolved job names.
CI initialization, cleanup, and PR directive handling
projects/llm_d/orchestration/ci.py, projects/llm_d/orchestration/cleanup_phase.py, projects/llm_d/orchestration/pr_args.py
CI initialization preserves overrides across preset expansion, cleanup iterates across activated run specs and benchmark job names, and llm_d PR directive parsing now returns empty supported directives and empty parse results.
Runtime, rendering, and preset validation
projects/llm_d/tests/test_profiles.py, projects/llm_d/tests/test_pr_args.py, projects/llm_d/README.md
Tests cover deployment preset resolution, workload and benchmark merging, run-spec matrix handling, processor argument preservation, scheduler and model URI rendering, benchmark job-name deduplication, and namespace-managed state. README documents the revised runtime and benchmark selection flow.
Caliper visualize typing
projects/caliper/engine/visualize.py
resolve_visualize_config now explicitly types base_dir, explicit_path, and its optional dictionary return value.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • openshift-psap/forge#68: Reworks the GuideLLM benchmark runner with the same rate-expansion and result-extraction flow.
  • openshift-psap/forge#74: Uses GuideLLMParser, so the new benchmarks-rate-*.json handling is directly relevant.

Suggested labels

lgtm

Poem

🐇 Hop hop, the runs now split by rate,
Each bench and label finds its fate.
Profiles guide the pods today,
And RunSpecs hop the long way.
With JSON trails and cache-lit glow,
The rabbit grins at work below.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding llm-d release profiles and related benchmark support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@albertoperdomo2 albertoperdomo2 changed the title Add release profiles feat: Add release profiles Jun 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
projects/guidellm/tests/test_run_guidellm_benchmark.py (1)

10-83: ⚡ Quick win

Add a regression test for empty --rates with rate expressions.

Please add a negative-case test so the new validation path is locked and doesn’t regress.

Suggested test addition
+import pytest
+
@@
 def test_expand_guidellm_runs_keeps_plain_multi_rate_benchmark_as_single_run() -> None:
@@
     assert runs[0].args == [
         "--backend-type=openai_http",
         "--rate-type=concurrent",
         "--rates=300,200,100",
         "--data=prompt_tokens=1000,output_tokens=1000",
         "--max-seconds=600",
     ]
+
+
+def test_expand_guidellm_runs_rejects_empty_rates_with_rate_expressions() -> None:
+    with pytest.raises(ValueError, match="--rates"):
+        expand_guidellm_runs(
+            [
+                "--backend-type=openai_http",
+                "--rate-type=concurrent",
+                "--rates= , ",
+                "--max-requests={rate}",
+            ]
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/guidellm/tests/test_run_guidellm_benchmark.py` around lines 10 - 83,
Add a negative test in projects/guidellm/tests/test_run_guidellm_benchmark.py
that calls expand_guidellm_runs with an empty "--rates=" plus arguments that
include rate expressions (e.g., "--data=prefix_count={2*rate}" or
"--max-requests={rate}") and assert that expand_guidellm_runs raises a
ValueError (or the same validation exception used elsewhere) to lock in the new
validation path; name the test something like
test_expand_guidellm_runs_rejects_empty_rates_with_expressions and reference
expand_guidellm_runs in the assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/guidellm/toolbox/run_guidellm_benchmark/utils.py`:
- Around line 75-95: The parsing of rate_values from rates_arg can produce an
empty list and silently return zero runs; validate and fail fast by checking
after computing rate_values (the variable rate_values derived from rates_arg)
and if rates_arg contains "--rates=" or similar but rate_values is empty, raise
a clear exception (e.g., ValueError) so the caller fails rather than returning
an empty runs list; add this check before the for rate in rate_values loop that
constructs runs and reference GuideLLMRun, _substitute_rate_expressions,
_sanitize_rate_label and guidellm_args when locating the relevant code.

In `@projects/llm_d/README.md`:
- Around line 61-63: The docs currently imply all multi-rate workloads expand
into separate GuideLLM runs; update the bullet list to clarify that plain
"rates" remain a single GuideLLM invocation unless another argument contains a
"{rate}" (or other "{...*rate}" expression), in which case the workload is
expanded into one GuideLLM run per rate; mention that expressions like
"{2*rate}" and "{10*rate}" are resolved per run only when expansion occurs and
keep the note that Benchflow-specific features are not modeled yet, referencing
the "rates" key and "{rate}" expressions and the GuideLLM invocation behavior.

In `@projects/llm_d/tests/test_profiles.py`:
- Around line 40-55: The test
test_smoke_presets_inherit_deployment_scheduler_modes reuses the same config
across multiple core_config.project.apply_preset calls which can mask state
leakage; update the test to isolate each preset assertion by reinitializing the
project config (call _init_project_config or otherwise reset
core_config/project/runtime_config) before each apply_preset, then call
core_config.project.apply_preset("<preset>") and assert
runtime_config.get_scheduler_profile_key(), runtime_config.get_model_key() and
runtime_config.get_benchmark_config() for that single preset to ensure earlier
presets don't influence later checks.

---

Nitpick comments:
In `@projects/guidellm/tests/test_run_guidellm_benchmark.py`:
- Around line 10-83: Add a negative test in
projects/guidellm/tests/test_run_guidellm_benchmark.py that calls
expand_guidellm_runs with an empty "--rates=" plus arguments that include rate
expressions (e.g., "--data=prefix_count={2*rate}" or "--max-requests={rate}")
and assert that expand_guidellm_runs raises a ValueError (or the same validation
exception used elsewhere) to lock in the new validation path; name the test
something like test_expand_guidellm_runs_rejects_empty_rates_with_expressions
and reference expand_guidellm_runs in the assertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40e0a76a-0776-4973-b711-8f466c28599f

📥 Commits

Reviewing files that changed from the base of the PR and between 4326065 and 4ed7e73.

📒 Files selected for processing (11)
  • projects/caliper/engine/visualize.py
  • projects/guidellm/tests/test_run_guidellm_benchmark.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/main.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/templates/guidellm_job.yaml.j2
  • projects/guidellm/toolbox/run_guidellm_benchmark/utils.py
  • projects/llm_d/README.md
  • projects/llm_d/orchestration/config.d/workloads.yaml
  • projects/llm_d/orchestration/presets.d/presets.yaml
  • projects/llm_d/orchestration/scheduler_profiles/precise.yaml
  • projects/llm_d/orchestration/test_phase.py
  • projects/llm_d/tests/test_profiles.py
💤 Files with no reviewable changes (1)
  • projects/caliper/engine/visualize.py

Comment thread projects/guidellm/toolbox/run_guidellm_benchmark/utils.py Outdated
Comment thread projects/llm_d/README.md Outdated
Comment thread projects/llm_d/tests/test_profiles.py Outdated
@albertoperdomo2 albertoperdomo2 changed the title feat: Add release profiles WIP - feat: Add release profiles Jun 12, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 12, 2026
@albertoperdomo2 albertoperdomo2 changed the title WIP - feat: Add release profiles feat: Add llm-d release profiles Jun 15, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 15, 2026
Comment thread projects/llm_d/orchestration/test_phase.py Outdated
Comment thread projects/llm_d/orchestration/config.d/workloads.yaml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/llm_d/orchestration/runtime_config.py`:
- Line 118: The benchmark name is being accessed using dot notation in the
JSONPath string passed to config.project.get_config(), but benchmark names like
concurrent-1k-1k and multi-turn contain hyphens which are not reliably
accessible via dot notation. Change the string from
f"workloads.benchmarks.{benchmark_name}" to
f"workloads.benchmarks['{benchmark_name}']" to use bracket notation, which
properly handles hyphenated keys in JSONPath.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f882457-054d-4230-aa3f-b1e3bdd33298

📥 Commits

Reviewing files that changed from the base of the PR and between 4ed7e73 and cf4f6c5.

📒 Files selected for processing (11)
  • projects/guidellm/tests/test_run_guidellm_benchmark.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/__init__.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/main.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/templates/guidellm_job.yaml.j2
  • projects/guidellm/toolbox/run_guidellm_benchmark/utils.py
  • projects/llm_d/README.md
  • projects/llm_d/orchestration/config.d/workloads.yaml
  • projects/llm_d/orchestration/presets.d/presets.yaml
  • projects/llm_d/orchestration/runtime_config.py
  • projects/llm_d/orchestration/test_phase.py
  • projects/llm_d/tests/test_profiles.py
✅ Files skipped from review due to trivial changes (2)
  • projects/guidellm/toolbox/run_guidellm_benchmark/init.py
  • projects/llm_d/README.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • projects/guidellm/toolbox/run_guidellm_benchmark/templates/guidellm_job.yaml.j2
  • projects/llm_d/orchestration/presets.d/presets.yaml
  • projects/guidellm/tests/test_run_guidellm_benchmark.py
  • projects/llm_d/orchestration/test_phase.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/utils.py
  • projects/guidellm/toolbox/run_guidellm_benchmark/main.py

Comment thread projects/llm_d/orchestration/runtime_config.py Outdated
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'llm_d test' failed after 00 hours 05 minutes 10 seconds 🔴

• Link to the test results.

• Caliper postprocess completed but no reports generated.

Test configuration:

ci_job.cluster: athena-fire
ci_job.exclusive: true
ci_job.fjob: forge-llm-d-20260623-133137
ci_job.name: llm_d
ci_job.owner: albertoperdomo2
project.args: []
project.name: llm_d
runtime.benchmark_key: multi-turn
runtime.default_preset: gpt-oss-120b-inference-scheduling-release

• Failure indicator:

## /workspace/artifacts/000__test/001__llmd_run/004__benchmark_multi-turn/000__run_guidellm_benchmark/FAILURE 
GuideLLM benchmark job 'guidellm-benchmark' failed.

Check the job logs for detailed error information:
  artifacts/guidellm_benchmark_job.logs

## /workspace/artifacts/000__test/FAILURE 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
~~ projects/guidellm/toolbox/run_guidellm_benchmark/main.py:147
~~ TASK: wait_guidellm_benchmark_task: Wait for the GuideLLM benchmark job to complete
~~ ARTIFACT_DIR: /workspace/artifacts/000__test/001__llmd_run/004__benchmark_multi-turn/000__run_guidellm_benchmark
~~ LOG_FILE: /workspace/artifacts/000__test/001__llmd_run/004__benchmark_multi-turn/000__run_guidellm_benchmark/task.log
~~ ARGS:
~~     endpoint_url: https://inference-gateway.apps.psap-fire-athena.ibm.rhperfscale.org/forge-llm-d/llm-d
~~     name: guidellm-benchmark
~~     namespace: forge-llm-d
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~     timeout: 3600
~~     pvc_size: 1Gi
~~     guidellm_args:
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rates=32,64,128,256,512
~~     - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count={2*rate}
~~     - --max-requests={10*rate}
~~     - --outputs=json
~~     artifact_dir: /workspace/artifacts/000__test/001__llmd_run/004__benchmark_multi-turn/000__run_guidellm_benchmark
~~ CONTEXT:
~~     guidellm_args:
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rates=32,64,128,256,512
~~     - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count={2*rate}
~~     - --max-requests={10*rate}
~~     - --outputs=json
~~     guidellm_runs:
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: '32'
~~       label: rate-32
~~       args:
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=32
~~       - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count=64
~~       - --max-requests=320
~~       - --outputs=json
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: '64'
~~       label: rate-64
~~       args:
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=64
~~       - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count=128
~~       - --max-requests=640
~~       - --outputs=json
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: '128'
~~       label: rate-128
~~       args:
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=128
~~       - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count=256
~~       - --max-requests=1280
~~       - --outputs=json
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: '256'
~~       label: rate-256
~~       args:
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=256
~~       - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count=512
~~       - --max-requests=2560
~~       - --outputs=json
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: '512'
~~       label: rate-512
~~       args:
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=512
~~       - --data=prompt_tokens=128,output_tokens=128,turns=5,prefix_tokens=10000,prefix_count=1024
~~       - --max-requests=5120
~~       - --outputs=json
~~     target_namespace: forge-llm-d
~~     benchmark_name: guidellm-benchmark
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~
~~ EXCEPTION: RuntimeError
~~     GuideLLM job guidellm-benchmark failed
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


[...]

• Execution logs

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 06 minutes 31 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'llm_d test' failed after 00 hours 01 minutes 36 seconds 🔴

• Link to the test results.

• Caliper postprocess completed but no reports generated.

Test configuration:

ci_job.cluster: athena-fire
ci_job.exclusive: true
ci_job.fjob: forge-llm-d-20260623-135836
ci_job.name: llm_d
ci_job.owner: albertoperdomo2
project.args: []
project.name: llm_d
runtime.benchmark_key: multi-turn
runtime.default_preset: gpt-oss-120b-inference-scheduling-release

• Failure indicator:

## /workspace/artifacts/000__test/FAILURE 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
~~ projects/kserve/toolbox/prepare_hf_model_cache/main.py:299
~~ TASK: wait_for_download: Wait for the download job to complete
~~ ARTIFACT_DIR: /workspace/artifacts/000__test/001__llmd_run/001__prepare_hf_model_cache
~~ LOG_FILE: /workspace/artifacts/000__test/001__llmd_run/001__prepare_hf_model_cache/task.log
~~ ARGS:
~~     namespace: forge-llm-d
~~     namespace_is_managed: false
~~     model_key: openai-gpt-oss-120b
~~     model_uri: hf://openai/gpt-oss-120b
~~     pvc_size: 15Gi
~~     access_mode: ReadWriteOnce
~~     storage_class_name: null
~~     pvc_name_prefix: llm-d-model
~~     model_directory_name: model
~~     marker_filename: cached.marker
~~     wait_timeout_seconds: 3600
~~     poll_interval_seconds: 30
~~     downloader_image: registry.access.redhat.com/ubi9/python-311
~~     hf_token_file_path: /var/run/secrets/fournos/psap-forge-hf/hf_token
~~     pod_image_pull_policy: IfNotPresent
~~     artifact_dir: /workspace/artifacts/000__test/001__llmd_run/001__prepare_hf_model_cache
~~ CONTEXT:
~~     cache_spec:
~~       source_uri: hf://openai/gpt-oss-120b
~~       source_scheme: hf
~~       cache_key: 7ab79ddecd
~~       namespace: forge-llm-d
~~       pvc_name: llm-d-model-openai-gpt-oss-120b-7ab79ddecd
~~       pvc_size: 15Gi
~~       access_mode: ReadWriteOnce
~~       storage_class_name: null
~~       model_path: model
~~       model_uri: pvc://llm-d-model-openai-gpt-oss-120b-7ab79ddecd/model
~~       marker_filename: cached.marker
~~       marker_path: /cache/model/cached.marker
~~       download_job_name: llm-d-model-openai-gpt-oss-120b-7ab79ddecd-download
~~       hf_token_secret_name: null
~~       hf_token_secret_key: token
~~       oci_image_path: null
~~       oci_registry_auth_secret_name: null
~~       oci_registry_auth_secret_key: null
~~     hf_secret_created: true
~~     hf_secret_name: llm-d-model-openai-gpt-oss-120b-7ab79ddecd-hf-token
~~     pvc_exists: true
~~     cache_ready: false
~~
~~ EXCEPTION: RuntimeError
~~     job/llm-d-model-openai-gpt-oss-120b-7ab79ddecd-download failed after 1 attempt(s)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


[...]

• Execution logs

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 02 minutes 58 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 22 minutes 09 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'llm_d test' failed after 00 hours 09 minutes 44 seconds 🔴

• Link to the test results.

• Caliper postprocess completed but no reports generated.

Test configuration:

ci_job.cluster: athena-fire
ci_job.exclusive: true
ci_job.fjob: forge-llm-d-20260623-143125
ci_job.name: llm_d
ci_job.owner: albertoperdomo2
model_cache.pvc.size: 300Gi
project.args: []
project.name: llm_d
runtime.benchmark_key: multi-turn
runtime.default_preset: gpt-oss-120b-inference-scheduling-release

• Failure indicator:

## /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark/FAILURE 
GuideLLM benchmark job 'guidellm-benchmark' failed.

Check the job logs for detailed error information:
  artifacts/guidellm_benchmark_job.logs

## /workspace/artifacts/000__test/FAILURE 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
~~ projects/guidellm/toolbox/run_guidellm_benchmark/main.py:147
~~ TASK: wait_guidellm_benchmark_task: Wait for the GuideLLM benchmark job to complete
~~ ARTIFACT_DIR: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark
~~ LOG_FILE: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark/task.log
~~ ARGS:
~~     endpoint_url: https://inference-gateway.apps.psap-fire-athena.ibm.rhperfscale.org/forge-llm-d/llm-d
~~     name: guidellm-benchmark
~~     namespace: forge-llm-d
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~     timeout: 3600
~~     pvc_size: 1Gi
~~     guidellm_args:
~~     - --request-type=text_completions
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rates=300,200,100,50,1
~~     - --data=prompt_tokens=1000,output_tokens=1000
~~     - --max-seconds=600
~~     - --outputs=json
~~     artifact_dir: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark
~~ CONTEXT:
~~     guidellm_args:
~~     - --request-type=text_completions
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rates=300,200,100,50,1
~~     - --data=prompt_tokens=1000,output_tokens=1000
~~     - --max-seconds=600
~~     - --outputs=json
~~     guidellm_runs:
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: null
~~       label: default
~~       args:
~~       - --request-type=text_completions
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rates=300,200,100,50,1
~~       - --data=prompt_tokens=1000,output_tokens=1000
~~       - --max-seconds=600
~~       - --outputs=json
~~     target_namespace: forge-llm-d
~~     benchmark_name: guidellm-benchmark
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~
~~ EXCEPTION: RuntimeError
~~     GuideLLM job guidellm-benchmark failed
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


[...]

• Execution logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
projects/llm_d/orchestration/prepare_phase.py (1)

309-360: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Handle oci:// model URIs consistently with cache rendering.

runtime_config.get_model_uri() can now return oci://..., and the KServe renderer builds a cache-backed PVC spec for non-PVC model URIs, but this path still raises ValueError for anything except hf://. With model cache enabled, OCI-backed runs fail during prepare/test or render a PVC reference that this phase never populates. Please either add the OCI cache preparation path here or skip/disable cache for OCI in both prepare and render until that downloader exists.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/llm_d/orchestration/prepare_phase.py` around lines 309 - 360, The
code currently raises a ValueError for any model URI scheme that is not hf://,
but runtime_config.get_model_uri() can now return oci:// URIs which causes
prepare phase failures. Add handling for oci:// model URIs by either inserting a
skip condition early in the function (similar to the existing PVC check that
returns early) to skip cache preparation for oci:// URIs, or add an elif branch
before the final ValueError that checks for oci:// and logs a message before
returning, preventing the unsupported scheme error from being raised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/kserve/toolbox/deploy_llmisvc/utils.py`:
- Around line 60-77: The model URI resolution logic at the beginning of the
function only explicitly preserves oci:// and hf:// prefixes, causing pvc:// and
pvc+hf:// URIs to be incorrectly rewritten to hf://, which breaks the cache-skip
logic later. Add explicit handling for pvc:// and pvc+hf:// prefixed URIs in the
if-elif-else block (before the final else clause that defaults to hf://) so
these PVC-based model URIs are passed through unchanged with their scheme
preserved as "pvc" or "pvc+hf" respectively.

In `@projects/llm_d/orchestration/runtime_config.py`:
- Around line 306-335: The issue is that when creating multiple RunSpec objects
in the loop over combinations, synthesized namespaces inherit the base
namespace's managed state instead of being marked as managed. For
multi-combination cases where a new namespace is synthesized (when
len(combinations) != 1), the RunSpec should have namespace_is_managed set to
True instead of the base namespace_is_managed value to ensure proper preparation
and cleanup. Additionally, the truncate_k8s_name call needs to reserve
sufficient space for the unique model_slug and profile_slug components before
truncation to prevent different matrix runs from sharing the same namespace due
to suffix truncation. Modify the RunSpec instantiation logic to conditionally
set namespace_is_managed based on whether a custom namespace was synthesized,
and ensure the truncation preserves the uniqueness of the model and profile
identifiers.

---

Outside diff comments:
In `@projects/llm_d/orchestration/prepare_phase.py`:
- Around line 309-360: The code currently raises a ValueError for any model URI
scheme that is not hf://, but runtime_config.get_model_uri() can now return
oci:// URIs which causes prepare phase failures. Add handling for oci:// model
URIs by either inserting a skip condition early in the function (similar to the
existing PVC check that returns early) to skip cache preparation for oci://
URIs, or add an elif branch before the final ValueError that checks for oci://
and logs a message before returning, preventing the unsupported scheme error
from being raised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 00d992ad-a49b-4115-b212-e4ac86eecaa8

📥 Commits

Reviewing files that changed from the base of the PR and between cf4f6c5 and 36c9dbf.

📒 Files selected for processing (17)
  • projects/kserve/toolbox/deploy_llmisvc/utils.py
  • projects/llm_d/README.md
  • projects/llm_d/orchestration/ci.py
  • projects/llm_d/orchestration/cleanup_phase.py
  • projects/llm_d/orchestration/config.d/deployments.yaml
  • projects/llm_d/orchestration/config.d/models.yaml
  • projects/llm_d/orchestration/config.d/runtime.yaml
  • projects/llm_d/orchestration/config.d/scheduler_profiles.yaml
  • projects/llm_d/orchestration/config.d/workloads.yaml
  • projects/llm_d/orchestration/prepare_phase.py
  • projects/llm_d/orchestration/prepare_sequence.py
  • projects/llm_d/orchestration/presets.d/presets.yaml
  • projects/llm_d/orchestration/runtime_config.py
  • projects/llm_d/orchestration/scheduler_profiles/approximate.yaml
  • projects/llm_d/orchestration/scheduler_profiles/precise.yaml
  • projects/llm_d/orchestration/test_phase.py
  • projects/llm_d/tests/test_profiles.py
💤 Files with no reviewable changes (4)
  • projects/llm_d/orchestration/config.d/models.yaml
  • projects/llm_d/orchestration/scheduler_profiles/precise.yaml
  • projects/llm_d/orchestration/config.d/scheduler_profiles.yaml
  • projects/llm_d/orchestration/scheduler_profiles/approximate.yaml
✅ Files skipped from review due to trivial changes (1)
  • projects/llm_d/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • projects/llm_d/orchestration/config.d/workloads.yaml

Comment thread projects/kserve/toolbox/deploy_llmisvc/utils.py Outdated
Comment thread projects/llm_d/orchestration/runtime_config.py
@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 11 minutes 04 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2
albertoperdomo2 force-pushed the feat/add-release-profiles branch from 2c822c8 to 4e5d3df Compare June 23, 2026 14:51
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'llm_d test' failed after 00 hours 09 minutes 40 seconds 🔴

• Link to the test results.

• Caliper postprocess completed but no reports generated.

Test configuration:

ci_job.cluster: athena-fire
ci_job.exclusive: true
ci_job.fjob: forge-llm-d-20260623-145238
ci_job.name: llm_d
ci_job.owner: albertoperdomo2
model_cache.pvc.size: 300Gi
project.args: []
project.name: llm_d
runtime.benchmark_key: multi-turn
runtime.default_preset: gpt-oss-120b-inference-scheduling-release

• Failure indicator:

## /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark/FAILURE 
GuideLLM benchmark job 'guidellm-benchmark' failed.

Check the job logs for detailed error information:
  artifacts/guidellm_benchmark_job.logs

## /workspace/artifacts/000__test/FAILURE 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
~~ projects/guidellm/toolbox/run_guidellm_benchmark/main.py:147
~~ TASK: wait_guidellm_benchmark_task: Wait for the GuideLLM benchmark job to complete
~~ ARTIFACT_DIR: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark
~~ LOG_FILE: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark/task.log
~~ ARGS:
~~     endpoint_url: https://inference-gateway.apps.psap-fire-athena.ibm.rhperfscale.org/forge-llm-d/llm-d
~~     name: guidellm-benchmark
~~     namespace: forge-llm-d
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~     timeout: 3600
~~     pvc_size: 1Gi
~~     guidellm_args:
~~     - --request-type=text_completions
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rate=300,200,100,50,1
~~     - --data=prompt_tokens=1000,output_tokens=1000
~~     - --max-seconds=600
~~     - --outputs=json
~~     artifact_dir: /workspace/artifacts/000__test/001__llmd_run/003__benchmark_concurrent-1k-1k/000__run_guidellm_benchmark
~~ CONTEXT:
~~     guidellm_args:
~~     - --request-type=text_completions
~~     - --backend-type=openai_http
~~     - --rate-type=concurrent
~~     - --rate=300,200,100,50,1
~~     - --data=prompt_tokens=1000,output_tokens=1000
~~     - --max-seconds=600
~~     - --outputs=json
~~     guidellm_runs:
~~     - !!python/object:projects.guidellm.toolbox.run_guidellm_benchmark.utils.GuideLLMRun
~~       rate: null
~~       label: default
~~       args:
~~       - --request-type=text_completions
~~       - --backend-type=openai_http
~~       - --rate-type=concurrent
~~       - --rate=300,200,100,50,1
~~       - --data=prompt_tokens=1000,output_tokens=1000
~~       - --max-seconds=600
~~       - --outputs=json
~~     target_namespace: forge-llm-d
~~     benchmark_name: guidellm-benchmark
~~     image: ghcr.io/vllm-project/guidellm:v0.5.4
~~
~~ EXCEPTION: RuntimeError
~~     GuideLLM job guidellm-benchmark failed
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


[...]

• Execution logs

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 10 minutes 55 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi

@psap-forge-bot

Copy link
Copy Markdown

🔴 Test of 'fournos_launcher submit' failed after 00 hours 22 minutes 08 seconds 🔴

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/var model_cache.pvc.size: 300Gi
/cluster athena-fire
/test fournos llm_d gpt-oss-120b-inference-scheduling-release

• Failure indicator: Empty.
• Execution logs

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2
albertoperdomo2 force-pushed the feat/add-release-profiles branch from 158bbdf to bff5855 Compare June 25, 2026 12:20
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Comment thread projects/llm_d/orchestration/config.d/deployments.yaml Outdated
Comment thread projects/llm_d/orchestration/ci.py Outdated
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/cluster athena-fire
/var runtime.benchmark_key: multi-turn

@psap-forge-bot

Copy link
Copy Markdown

🟢 Test of 'llm_d test' succeeded after 00 hours 19 minutes 46 seconds 🟢

• Link to the test results.

• Generated 1 Caliper report(s):

  • report_00_guidellm_performance_analysis.html

Test configuration:

ci_job.cluster: athena-fire
ci_job.exclusive: true
ci_job.fjob: forge-llm-d-20260626-075029
ci_job.name: llm_d gpt-oss-120b-inference-scheduling-release
ci_job.owner: albertoperdomo2
project.args:
- gpt-oss-120b-inference-scheduling-release
project.name: llm_d
runtime.benchmark_key: multi-turn

• Execution logs

@psap-forge-bot

Copy link
Copy Markdown

🟢 Test of 'fournos_launcher submit' succeeded after 00 hours 21 minutes 05 seconds 🟢

• Link to the test results.

• No reports generated...

Test configuration:

/test fournos llm_d gpt-oss-120b-inference-scheduling-release
/var runtime.benchmark_key: multi-turn
/cluster athena-fire

• Execution logs

@kpouget

kpouget commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

nice, great work @albertoperdomo2 , let's merge this
/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 26, 2026
@kpouget

kpouget commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

/approve

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kpouget

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 26, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 9988c90 into openshift-psap:main Jun 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants