test: trigger OKP quality gate#2051
Conversation
WalkthroughChangesOKP Quality Gate
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant PullRequest
participant GitHubActions
participant GitLabAPI
PullRequest->>GitHubActions: Open, synchronize, or reopen matching PR
GitHubActions->>GitLabAPI: Trigger evaluation pipeline with PR metadata
GitLabAPI-->>GitHubActions: Return pipeline ID and URL
loop Until terminal status
GitHubActions->>GitLabAPI: Poll pipeline status
GitLabAPI-->>GitHubActions: Return pipeline status
end
GitHubActions->>GitLabAPI: Fetch stack_test regression report
GitHubActions->>PullRequest: Create or update quality gate comment
GitHubActions-->>PullRequest: Mark check failed unless status is success
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 @.github/workflows/okp-quality-gate.yaml:
- Around line 63-65: The polling loop’s curl request in the workflow can hang
indefinitely because it only uses --silent and --show-error. Update the curl
call in the pipeline polling logic to include a request timeout such as
--max-time and/or --connect-timeout, using the existing RESPONSE assignment
block that fetches the GitLab pipeline status, so stalled network calls fail
fast with clearer diagnostics.
- Around line 33-40: The `run` block in the pipeline trigger step is
interpolating attacker-controlled pull request values from
`github.event.pull_request.head.ref` and `head.repo.full_name` directly into
curl arguments, so move these expressions into intermediate environment
variables and reference only the env vars inside the shell script. Update the
`trigger` step in the workflow so the `curl` call uses safe shell variables, and
apply the same pattern to the `steps.trigger.outputs.pipeline_id` usage for
consistency and defense-in-depth.
- Around line 22-26: The okp-quality-gate job is missing an explicit
least-privilege permissions block and a concurrency setting. Update the workflow
job in okp-quality-gate to add a restrictive permissions stanza for the
GITHUB_TOKEN, and define a concurrency group keyed to the PR or branch so stale
runs are canceled when a new synchronize push arrives. Keep the change scoped to
the okp-quality-gate job and its job-level settings.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2d24c207-6cec-48a7-9496-dfbd2395c0ee
📒 Files selected for processing (2)
.github/workflows/okp-quality-gate.yamlsrc/constants.py
📜 Review details
⏰ Context from checks skipped due to timeout. (13)
- GitHub Check: unit_tests (3.13)
- GitHub Check: unit_tests (3.12)
- GitHub Check: Pylinter
- GitHub Check: build-pr
- GitHub Check: integration_tests (3.13)
- GitHub Check: integration_tests (3.12)
- GitHub Check: E2E Tests for Lightspeed Evaluation job
- GitHub Check: E2E: library mode / ci / group 3
- GitHub Check: E2E: server mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 1
- GitHub Check: E2E: server mode / ci / group 3
- GitHub Check: E2E: library mode / ci / group 2
- GitHub Check: E2E: server mode / ci / group 2
⚠️ CI failures not shown inline (6)
GitHub Actions: OKP Quality Gate / okp-quality-gate: test: trigger OKP quality gate
Conclusion: failure
##[group]Run RESPONSE=$(curl --silent --show-error --fail \
�[36;1mRESPONSE=$(curl --silent --show-error --fail \�[0m
�[36;1m --request POST \�[0m
�[36;1m --form "***REDACTED*** \�[0m
�[36;1m --form "ref=ci-trigger-test" \�[0m
�[36;1m --form "variables[PR_REPO]=alessandralanz/lightspeed-stack" \�[0m
�[36;1m --form "variables[PR_BRANCH]=test-okp-trigger" \�[0m
�[36;1m --form "variables[PR_SHA]=7324486f2f67fc197498916453a6149b13d68d4f" \�[0m
�[36;1m "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/trigger/pipeline")�[0m
�[36;1m�[0m
�[36;1mPIPELINE_ID=$(echo "$RESPONSE" | jq -r '.id')�[0m
�[36;1mPIPELINE_URL=$(echo "$RESPONSE" | jq -r '.web_url')�[0m
�[36;1m�[0m
�[36;1mif [ "$PIPELINE_ID" = "null" ] || [ -z "$PIPELINE_ID" ]; then�[0m
�[36;1m echo "Failed to trigger pipeline. Response:"�[0m
�[36;1m echo "$RESPONSE"�[0m
�[36;1m exit 1�[0m
�[36;1mfi�[0m
�[36;1m�[0m
�[36;1mecho "pipeline_id=${PIPELINE_ID}" >> "$GITHUB_OUTPUT"�[0m
�[36;1mecho "Triggered GitLab pipeline #${PIPELINE_ID}: ${PIPELINE_URL}"�[0m
shell: /usr/bin/bash -e {0}
env:
GITLAB_TRIGGER_***REDACTED***
##[endgroup]
curl: (6) Could not resolve host: gitlab.cee.redhat.com
##[error]Process completed with exit code 6.
GitHub Actions: OKP Quality Gate / 0_okp-quality-gate.txt: test: trigger OKP quality gate
Conclusion: failure
##[group]Run RESPONSE=$(curl --silent --show-error --fail \
�[36;1mRESPONSE=$(curl --silent --show-error --fail \�[0m
�[36;1m --request POST \�[0m
�[36;1m --form "***REDACTED*** \�[0m
�[36;1m --form "ref=ci-trigger-test" \�[0m
�[36;1m --form "variables[PR_REPO]=alessandralanz/lightspeed-stack" \�[0m
�[36;1m --form "variables[PR_BRANCH]=test-okp-trigger" \�[0m
�[36;1m --form "variables[PR_SHA]=7324486f2f67fc197498916453a6149b13d68d4f" \�[0m
�[36;1m "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/trigger/pipeline")�[0m
�[36;1m�[0m
�[36;1mPIPELINE_ID=$(echo "$RESPONSE" | jq -r '.id')�[0m
�[36;1mPIPELINE_URL=$(echo "$RESPONSE" | jq -r '.web_url')�[0m
�[36;1m�[0m
�[36;1mif [ "$PIPELINE_ID" = "null" ] || [ -z "$PIPELINE_ID" ]; then�[0m
�[36;1m echo "Failed to trigger pipeline. Response:"�[0m
�[36;1m echo "$RESPONSE"�[0m
�[36;1m exit 1�[0m
�[36;1mfi�[0m
�[36;1m�[0m
�[36;1mecho "pipeline_id=${PIPELINE_ID}" >> "$GITHUB_OUTPUT"�[0m
�[36;1mecho "Triggered GitLab pipeline #${PIPELINE_ID}: ${PIPELINE_URL}"�[0m
shell: /usr/bin/bash -e {0}
env:
GITLAB_TRIGGER_***REDACTED***
##[endgroup]
curl: (6) Could not resolve host: gitlab.cee.redhat.com
##[error]Process completed with exit code 6.
GitHub Actions: PR Title Checker / check: test: trigger OKP quality gate
Conclusion: failure
##[group]Run thehanimo/pr-title-checker@v1.4.3
with:
GITHUB_***REDACTED***
pass_on_octokit_error: false
configuration_path: .github/pr-title-checker-config.json
##[endgroup]
(node:2191) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Using config file .github/pr-title-checker-config.json from repo lightspeed-core/lightspeed-stack [ref: c62c782be1a566f926ced2cd8ca09ed9611a6956]
(node:2191) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.
Creating label (title needs formatting)...
Label (title needs formatting) already created.
Adding label (title needs formatting) to PR...
HttpError: Resource not accessible by integration
##[error]Failed to add label (title needs formatting) to PR
GitHub Actions: PR Title Checker / 0_check.txt: test: trigger OKP quality gate
Conclusion: failure
##[group]Run thehanimo/pr-title-checker@v1.4.3
with:
GITHUB_***REDACTED***
pass_on_octokit_error: false
configuration_path: .github/pr-title-checker-config.json
##[endgroup]
(node:2191) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Using config file .github/pr-title-checker-config.json from repo lightspeed-core/lightspeed-stack [ref: c62c782be1a566f926ced2cd8ca09ed9611a6956]
(node:2191) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.
Creating label (title needs formatting)...
Label (title needs formatting) already created.
Adding label (title needs formatting) to PR...
HttpError: Resource not accessible by integration
##[error]Failed to add label (title needs formatting) to PR
GitHub Actions: OpenAPI (Spectral) / spectral: test: trigger OKP quality gate
Conclusion: failure
##[group]Run set -euo pipefail
�[36;1mset -euo pipefail�[0m
�[36;1muv run python scripts/generate_openapi_schema.py /tmp/openapi-generated.json�[0m
�[36;1mif ! diff -u docs/openapi.json /tmp/openapi-generated.json; then�[0m
�[36;1m echo "::error::docs/openapi.json is out of date. Regenerate with: uv run scripts/generate_openapi_schema.py docs/openapi.json"�[0m
GitHub Actions: OpenAPI (Spectral) / 0_spectral.txt: test: trigger OKP quality gate
Conclusion: failure
##[group]Run set -euo pipefail
�[36;1mset -euo pipefail�[0m
�[36;1muv run python scripts/generate_openapi_schema.py /tmp/openapi-generated.json�[0m
�[36;1mif ! diff -u docs/openapi.json /tmp/openapi-generated.json; then�[0m
�[36;1m echo "::error::docs/openapi.json is out of date. Regenerate with: uv run scripts/generate_openapi_schema.py docs/openapi.json"�[0m
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.py: Use absolute imports for internal modules:from authentication import get_auth_dependency
Llama Stack imports: Usefrom llama_stack_client import AsyncLlamaStackClient
Checkconstants.pyfor shared constants before defining new ones
All modules must start with descriptive docstrings explaining purpose
Uselogger = get_logger(__name__)fromlog.pyfor module logging
All functions must have complete type annotations for parameters and return types, use modern syntax (str | int), and include descriptive docstrings
Use snake_case with descriptive, action-oriented names for functions (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying function parameters
Useasync deffor I/O operations and external API calls
Use standard log levels with clear purposes:debug()for diagnostic info,info()for program execution,warning()for unexpected events,error()for serious problems
All classes must have descriptive docstrings explaining purpose and use PascalCase with standard suffixes:Configuration,Error/Exception,Resolver,Interface
Abstract classes must use ABC with@abstractmethoddecorators
Follow Google Python docstring conventions with required sections: Parameters, Returns, Raises, and Attributes for classes
Files:
src/constants.py
src/constants.py
📄 CodeRabbit inference engine (AGENTS.md)
Use
constants.pyfor shared constants with descriptive comments and type hints usingFinal[type]
Files:
src/constants.py
🧠 Learnings (2)
📚 Learning: 2026-05-06T08:35:54.687Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 1690
File: .github/workflows/e2e_tests_providers.yaml:279-285
Timestamp: 2026-05-06T08:35:54.687Z
Learning: In .github/workflows/e2e_tests_providers.yaml and related e2e workflow files, the show_logs step should not use docker compose logs with --tail or --since (i.e., keep logs unbounded). The quick connectivity test runs once immediately after container startup, so the log output is small and a log tail limit is unnecessary. If you adjust this, add a rationale comment in the workflow explaining why unbounded logs are acceptable and ensure CI behavior remains deterministic.
Applied to files:
.github/workflows/okp-quality-gate.yaml
📚 Learning: 2026-06-24T13:45:37.249Z
Learnt from: Jdubrick
Repo: lightspeed-core/lightspeed-stack PR: 1971
File: src/utils/markdown_repair.py:31-36
Timestamp: 2026-06-24T13:45:37.249Z
Learning: In the lightspeed-stack repository, docstrings must use the section header name "Parameters:" (not "Args:") for function arguments, even if the project references Google Python docstring conventions. Ensure docstrings follow the project’s established "Parameters:" header format for any documented function parameters.
Applied to files:
src/constants.py
🪛 actionlint (1.7.12)
.github/workflows/okp-quality-gate.yaml
[error] 32-32: "github.event.pull_request.head.ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🪛 zizmor (1.26.1)
.github/workflows/okp-quality-gate.yaml
[warning] 1-89: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 37-37: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 38-38: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[warning] 39-39: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[info] 59-59: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[info] 23-23: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
[warning] 3-20: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🔇 Additional comments (2)
src/constants.py (1)
355-355: LGTM!.github/workflows/okp-quality-gate.yaml (1)
36-36: 🔒 Security & PrivacyConfirm hardcoded
ref: "ci-trigger-test"is intentional and not a leftover test value.Given the PR title ("test: trigger OKP quality gate"), this hardcoded trigger ref looks like a temporary testing artifact. Confirm this should reference the actual pipeline ref (e.g., a stable branch or tag) before this workflow is relied upon for real quality gating.
| jobs: | ||
| okp-quality-gate: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 120 | ||
| steps: |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
Add explicit least-privilege permissions and a concurrency group.
The job has no permissions: block (defaults to broad GITHUB_TOKEN scopes) and no concurrency group, so repeated pushes to the same PR (synchronize) can trigger multiple overlapping GitLab pipelines instead of canceling the stale one.
🛡️ Proposed fix
+permissions:
+ contents: read
+
+concurrency:
+ group: okp-quality-gate-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
jobs:
okp-quality-gate:
runs-on: ubuntu-latest
timeout-minutes: 120📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| jobs: | |
| okp-quality-gate: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 | |
| steps: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: okp-quality-gate-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| okp-quality-gate: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 | |
| steps: |
🧰 Tools
🪛 zizmor (1.26.1)
[info] 23-23: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 22 - 26, The
okp-quality-gate job is missing an explicit least-privilege permissions block
and a concurrency setting. Update the workflow job in okp-quality-gate to add a
restrictive permissions stanza for the GITHUB_TOKEN, and define a concurrency
group keyed to the PR or branch so stale runs are canceled when a new
synchronize push arrives. Keep the change scoped to the okp-quality-gate job and
its job-level settings.
Source: Linters/SAST tools
| RESPONSE=$(curl --silent --show-error --fail \ | ||
| --request POST \ | ||
| --form "token=${GITLAB_TRIGGER_TOKEN}" \ | ||
| --form "ref=ci-trigger-test" \ | ||
| --form "variables[PR_REPO]=${{ github.event.pull_request.head.repo.full_name }}" \ | ||
| --form "variables[PR_BRANCH]=${{ github.event.pull_request.head.ref }}" \ | ||
| --form "variables[PR_SHA]=${{ github.event.pull_request.head.sha }}" \ | ||
| "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/trigger/pipeline") |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Script injection via untrusted PR branch ref in shell run: block.
github.event.pull_request.head.ref and head.repo.full_name are attacker-controlled and are interpolated directly into a run: shell script (--form arguments). A crafted branch name (e.g. containing backticks or $(...)) can break out of the --form argument and execute arbitrary code on the runner, exposing GITLAB_TRIGGER_TOKEN/GITLAB_API_TOKEN. This matches the exact pattern flagged by both zizmor (template-injection, lines 37-39) and actionlint (untrusted expression, line 32-area). GitHub's official guidance is to pass such values through intermediate environment variables first.
The steps.trigger.outputs.pipeline_id interpolation at line 59 is lower risk (self-produced numeric output) but should follow the same pattern for consistency and defense-in-depth.
🔒 Proposed fix using intermediate env vars
- name: Trigger GitLab evaluation pipeline
id: trigger
env:
GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }}
GITLAB_PROJECT_ID: ${{ vars.GITLAB_PROJECT_ID }}
+ PR_REPO: ${{ github.event.pull_request.head.repo.full_name }}
+ PR_BRANCH: ${{ github.event.pull_request.head.ref }}
+ PR_SHA: ${{ github.event.pull_request.head.sha }}
run: |
RESPONSE=$(curl --silent --show-error --fail \
--request POST \
--form "token=${GITLAB_TRIGGER_TOKEN}" \
--form "ref=ci-trigger-test" \
- --form "variables[PR_REPO]=${{ github.event.pull_request.head.repo.full_name }}" \
- --form "variables[PR_BRANCH]=${{ github.event.pull_request.head.ref }}" \
- --form "variables[PR_SHA]=${{ github.event.pull_request.head.sha }}" \
+ --form "variables[PR_REPO]=${PR_REPO}" \
+ --form "variables[PR_BRANCH]=${PR_BRANCH}" \
+ --form "variables[PR_SHA]=${PR_SHA}" \
"https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/trigger/pipeline") - name: Wait for GitLab pipeline to complete
env:
GITLAB_API_TOKEN: ${{ secrets.GITLAB_API_TOKEN }}
GITLAB_PROJECT_ID: ${{ vars.GITLAB_PROJECT_ID }}
+ PIPELINE_ID: ${{ steps.trigger.outputs.pipeline_id }}
run: |
- PIPELINE_ID=${{ steps.trigger.outputs.pipeline_id }}
echo "Waiting for pipeline #${PIPELINE_ID}..."Also applies to: 59-59
🧰 Tools
🪛 zizmor (1.26.1)
[error] 37-37: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 38-38: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[warning] 39-39: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 33 - 40, The `run`
block in the pipeline trigger step is interpolating attacker-controlled pull
request values from `github.event.pull_request.head.ref` and
`head.repo.full_name` directly into curl arguments, so move these expressions
into intermediate environment variables and reference only the env vars inside
the shell script. Update the `trigger` step in the workflow so the `curl` call
uses safe shell variables, and apply the same pattern to the
`steps.trigger.outputs.pipeline_id` usage for consistency and defense-in-depth.
Source: Linters/SAST tools
| RESPONSE=$(curl --silent --show-error \ | ||
| --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ | ||
| "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/pipelines/${PIPELINE_ID}") |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔵 Trivial | 💤 Low value
Add a request timeout to curl calls in the polling loop.
Neither curl invocation sets --max-time/--connect-timeout. A network stall could leave a step hanging without clear diagnostics until the overall timeout-minutes: 120 kills the job.
🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 63 - 65, The polling
loop’s curl request in the workflow can hang indefinitely because it only uses
--silent and --show-error. Update the curl call in the pipeline polling logic to
include a request timeout such as --max-time and/or --connect-timeout, using the
existing RESPONSE assignment block that fetches the GitLab pipeline status, so
stalled network calls fail fast with clearer diagnostics.
…mment on PR and turn github check red if gitlab test fails
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/okp-quality-gate.yaml (1)
22-29: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winAdd a
concurrencygroup to cancel stale pipeline runs.The
permissionsblock was added (addressing part of the prior review), but theconcurrencygroup is still missing. Without it, everysynchronizepush triggers a new workflow run and a new GitLab pipeline, wasting CI resources and producing duplicate PR comments.🛡️ Proposed fix
permissions: pull-requests: write +concurrency: + group: okp-quality-gate-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: okp-quality-gate:🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 22 - 29, Add a top-level concurrency group to the workflow, using a pull-request-specific key such as the workflow name and PR number, and enable cancellation of in-progress runs so stale synchronize-triggered executions are stopped. Place this alongside the existing permissions/jobs configuration.
♻️ Duplicate comments (2)
.github/workflows/okp-quality-gate.yaml (2)
68-70: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winAdd
--max-timeto curl calls — still unfixed.The polling
curllacks--max-time/--connect-timeout. A network stall can hang the step until the 120-minute job timeout kills it. The same applies to the curl calls at lines 110-112 and 121-123.🛡️ Proposed fix
RESPONSE=$(curl --silent --show-error \ + --max-time 30 --connect-timeout 10 \ --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/pipelines/${PIPELINE_ID}")Apply the same
--max-time 30 --connect-timeout 10flags to the curl calls at lines 110 and 121.🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 68 - 70, Add --max-time 30 and --connect-timeout 10 to the polling curl command assigning RESPONSE and the other curl calls in the workflow, including the calls near lines 110 and 121, so network stalls terminate promptly.
40-42: 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick winScript injection via untrusted PR values — still unfixed.
github.event.pull_request.head.refandhead.repo.full_nameare attacker-controlled and interpolated directly into therun:shell block. A crafted branch name (e.g. containing backticks or$(...)) can execute arbitrary code on the runner, exposingGITLAB_TRIGGER_TOKEN. Thesteps.trigger.outputs.pipeline_idinterpolation at line 64 is lower risk (self-produced) but should follow the same pattern for consistency.🔒 Proposed fix using intermediate env vars
- name: Trigger GitLab evaluation pipeline id: trigger env: GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} GITLAB_PROJECT_ID: ${{ vars.GITLAB_PROJECT_ID }} + PR_REPO: ${{ github.event.pull_request.head.repo.full_name }} + PR_BRANCH: ${{ github.event.pull_request.head.ref }} + PR_SHA: ${{ github.event.pull_request.head.sha }} run: | RESPONSE=$(curl --silent --show-error --fail \ --request POST \ --form "token=${GITLAB_TRIGGER_TOKEN}" \ --form "ref=ci-trigger-test" \ - --form "variables[PR_REPO]=${{ github.event.pull_request.head.repo.full_name }}" \ - --form "variables[PR_BRANCH]=${{ github.event.pull_request.head.ref }}" \ - --form "variables[PR_SHA]=${{ github.event.pull_request.head.sha }}" \ + --form "variables[PR_REPO]=${PR_REPO}" \ + --form "variables[PR_BRANCH]=${PR_BRANCH}" \ + --form "variables[PR_SHA]=${PR_SHA}" \ "https://gitlab.cee.redhat.com/api/v4/projects/${GITLAB_PROJECT_ID}/trigger/pipeline")- name: Wait for GitLab pipeline to complete id: wait env: GITLAB_API_TOKEN: ${{ secrets.GITLAB_API_TOKEN }} GITLAB_PROJECT_ID: ${{ vars.GITLAB_PROJECT_ID }} + PIPELINE_ID: ${{ steps.trigger.outputs.pipeline_id }} run: | - PIPELINE_ID=${{ steps.trigger.outputs.pipeline_id }} echo "Waiting for pipeline #${PIPELINE_ID}..."Also applies to: 64-64
🤖 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 @.github/workflows/okp-quality-gate.yaml around lines 40 - 42, Untrusted pull-request values are interpolated directly into the shell script, enabling command injection. In the workflow step containing the PR_REPO, PR_BRANCH, and PR_SHA form arguments, pass GitHub expression values through the step’s env block and reference them as quoted shell variables; apply the same env-based pattern to steps.trigger.outputs.pipeline_id.Source: Linters/SAST tools
🤖 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 @.github/workflows/okp-quality-gate.yaml:
- Line 134: Replace the mutable actions/github-script@v7 reference in the
workflow step with a specific immutable commit SHA, retaining the existing
action version and adding a comment identifying the pinned release.
---
Outside diff comments:
In @.github/workflows/okp-quality-gate.yaml:
- Around line 22-29: Add a top-level concurrency group to the workflow, using a
pull-request-specific key such as the workflow name and PR number, and enable
cancellation of in-progress runs so stale synchronize-triggered executions are
stopped. Place this alongside the existing permissions/jobs configuration.
---
Duplicate comments:
In @.github/workflows/okp-quality-gate.yaml:
- Around line 68-70: Add --max-time 30 and --connect-timeout 10 to the polling
curl command assigning RESPONSE and the other curl calls in the workflow,
including the calls near lines 110 and 121, so network stalls terminate
promptly.
- Around line 40-42: Untrusted pull-request values are interpolated directly
into the shell script, enabling command injection. In the workflow step
containing the PR_REPO, PR_BRANCH, and PR_SHA form arguments, pass GitHub
expression values through the step’s env block and reference them as quoted
shell variables; apply the same env-based pattern to
steps.trigger.outputs.pipeline_id.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7a7e849c-1e54-48d5-a3c4-c8229f1c18cf
📒 Files selected for processing (1)
.github/workflows/okp-quality-gate.yaml
📜 Review details
⏰ Context from checks skipped due to timeout. (14)
- GitHub Check: black
- GitHub Check: spectral
- GitHub Check: integration_tests (3.12)
- GitHub Check: unit_tests (3.12)
- GitHub Check: unit_tests (3.13)
- GitHub Check: build-pr
- GitHub Check: mypy
- GitHub Check: E2E Tests for Lightspeed Evaluation job
- GitHub Check: E2E: server mode / ci / group 3
- GitHub Check: E2E: server mode / ci / group 1
- GitHub Check: E2E: server mode / ci / group 2
- GitHub Check: E2E: library mode / ci / group 2
- GitHub Check: E2E: library mode / ci / group 1
- GitHub Check: E2E: library mode / ci / group 3
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Title Checker / check: test: trigger OKP quality gate
Conclusion: failure
##[group]Run thehanimo/pr-title-checker@v1.4.3
with:
GITHUB_***REDACTED***
pass_on_octokit_error: false
configuration_path: .github/pr-title-checker-config.json
##[endgroup]
(node:1945) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
Using config file .github/pr-title-checker-config.json from repo lightspeed-core/lightspeed-stack [ref: dcbe6019825bfb6a072de032bcb1df07bba354f4]
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:1945) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.
Creating label (title needs formatting)...
Label (title needs formatting) already created.
Adding label (title needs formatting) to PR...
HttpError: Resource not accessible by integration
##[error]Failed to add label (title needs formatting) to PR
GitHub Actions: PR Title Checker / 0_check.txt: test: trigger OKP quality gate
Conclusion: failure
##[group]Run thehanimo/pr-title-checker@v1.4.3
with:
GITHUB_***REDACTED***
pass_on_octokit_error: false
configuration_path: .github/pr-title-checker-config.json
##[endgroup]
(node:1945) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
Using config file .github/pr-title-checker-config.json from repo lightspeed-core/lightspeed-stack [ref: dcbe6019825bfb6a072de032bcb1df07bba354f4]
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:1945) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.
Creating label (title needs formatting)...
Label (title needs formatting) already created.
Adding label (title needs formatting) to PR...
HttpError: Resource not accessible by integration
##[error]Failed to add label (title needs formatting) to PR
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-05-06T08:35:54.687Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 1690
File: .github/workflows/e2e_tests_providers.yaml:279-285
Timestamp: 2026-05-06T08:35:54.687Z
Learning: In .github/workflows/e2e_tests_providers.yaml and related e2e workflow files, the show_logs step should not use docker compose logs with --tail or --since (i.e., keep logs unbounded). The quick connectivity test runs once immediately after container startup, so the log output is small and a log tail limit is unnecessary. If you adjust this, add a rationale comment in the workflow explaining why unbounded logs are acceptable and ensure CI behavior remains deterministic.
Applied to files:
.github/workflows/okp-quality-gate.yaml
🪛 zizmor (1.26.1)
.github/workflows/okp-quality-gate.yaml
[error] 23-23: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level
(excessive-permissions)
[warning] 23-23: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
[info] 108-108: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[info] 185-185: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 134-134: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🔇 Additional comments (1)
.github/workflows/okp-quality-gate.yaml (1)
1-21: LGTM!Also applies to: 45-57, 72-99, 101-131, 140-181, 182-186
|
|
||
| - name: Post results to PR | ||
| if: always() && steps.wait.outputs.status != '' | ||
| uses: actions/github-script@v7 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Fetch the latest commit SHA for actions/github-script@v7
curl -s https://api.github.com/repos/actions/github-script/git/refs/tags/v7 | jq -r '.object.sha'Repository: lightspeed-core/lightspeed-stack
Length of output: 175
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow context around the reported line
nl -ba .github/workflows/okp-quality-gate.yaml | sed -n '110,155p'
# Resolve the v7 tag correctly (dereference annotated tags if needed)
python3 - <<'PY'
import json, urllib.request
repo = "actions/github-script"
ref_url = f"https://api.github.com/repos/{repo}/git/refs/tags/v7"
req = urllib.request.Request(ref_url, headers={"Accept": "application/vnd.github+json", "User-Agent": "code-rabbit"})
with urllib.request.urlopen(req) as r:
ref = json.load(r)
print("ref_object_type:", ref.get("object", {}).get("type"))
print("ref_object_sha:", ref.get("object", {}).get("sha"))
if ref.get("object", {}).get("type") == "tag":
tag_sha = ref["object"]["sha"]
tag_url = f"https://api.github.com/repos/{repo}/git/tags/{tag_sha}"
req = urllib.request.Request(tag_url, headers={"Accept": "application/vnd.github+json", "User-Agent": "code-rabbit"})
with urllib.request.urlopen(req) as r:
tag = json.load(r)
print("tag_object_type:", tag.get("object", {}).get("type"))
print("tag_commit_sha:", tag.get("object", {}).get("sha"))
PYRepository: lightspeed-core/lightspeed-stack
Length of output: 210
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the workflow context around the reported line without nl
awk 'NR>=110 && NR<=155 { print NR ":" $0 }' .github/workflows/okp-quality-gate.yaml
# Resolve actions/github-script@v7 to a commit if the API is reachable
python3 - <<'PY'
import json, urllib.request, sys
repo = "actions/github-script"
headers = {"Accept": "application/vnd.github+json", "User-Agent": "code-rabbit"}
def get(url):
req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
try:
ref = get(f"https://api.github.com/repos/{repo}/git/refs/tags/v7")
print("ref_json:", json.dumps(ref, sort_keys=True))
obj = ref.get("object", {})
if obj.get("type") == "tag":
tag = get(f"https://api.github.com/repos/{repo}/git/tags/{obj['sha']}")
print("tag_json:", json.dumps(tag, sort_keys=True))
elif obj.get("type") == "commit":
print("commit_sha:", obj.get("sha"))
except Exception as e:
print("ERROR:", type(e).__name__, e)
sys.exit(0)
PYRepository: lightspeed-core/lightspeed-stack
Length of output: 2821
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the workflow header and permissions/event context
awk 'NR>=1 && NR<=60 { print NR ":" $0 }' .github/workflows/okp-quality-gate.yamlRepository: lightspeed-core/lightspeed-stack
Length of output: 2447
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json, ssl, urllib.request, sys
repo = "actions/github-script"
headers = {"Accept": "application/vnd.github+json", "User-Agent": "code-rabbit"}
ctx = ssl._create_unverified_context()
def get(url):
req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req, context=ctx, timeout=20) as r:
return json.load(r)
ref = get(f"https://api.github.com/repos/{repo}/git/refs/tags/v7")
print("ref_type:", ref.get("object", {}).get("type"))
print("ref_sha:", ref.get("object", {}).get("sha"))
obj = ref.get("object", {})
if obj.get("type") == "tag":
tag = get(f"https://api.github.com/repos/{repo}/git/tags/{obj['sha']}")
print("tag_type:", tag.get("object", {}).get("type"))
print("commit_sha:", tag.get("object", {}).get("sha"))
else:
print("commit_sha:", obj.get("sha"))
sha = (tag.get("object", {}).get("sha") if obj.get("type") == "tag" else obj.get("sha"))
if sha:
commit = get(f"https://api.github.com/repos/{repo}/commits/{sha}")
print("commit_exists:", commit.get("sha") == sha)
PYRepository: lightspeed-core/lightspeed-stack
Length of output: 1166
Pin actions/github-script to a commit SHA .github/workflows/okp-quality-gate.yaml:134 — @v7 is mutable, and this step runs with pull-requests: write, so a moved tag could let arbitrary code post or modify PR content.
🧰 Tools
🪛 zizmor (1.26.1)
[error] 134-134: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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 @.github/workflows/okp-quality-gate.yaml at line 134, Replace the mutable
actions/github-script@v7 reference in the workflow step with a specific
immutable commit SHA, retaining the existing action version and adding a comment
identifying the pinned release.
Source: Linters/SAST tools
Description
Type of change
Tools used to create PR
Identify any AI code assistants used in this PR (for transparency and review context)
Related Tickets & Documents
Checklist before requesting a review
Testing
Summary by CodeRabbit
New Features
Bug Fixes