test: trigger OKP quality gate#2051
Conversation
WalkthroughThis PR adds a new GitHub Actions workflow ( ChangesOKP Quality Gate
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Contributor
participant GitHubActions
participant GitLabAPI
Contributor->>GitHubActions: Open/update pull request
GitHubActions->>GitLabAPI: POST trigger pipeline (repo, branch, sha)
GitLabAPI-->>GitHubActions: pipeline_id, pipeline_url
loop until terminal status
GitHubActions->>GitLabAPI: GET pipeline status
GitLabAPI-->>GitHubActions: status
GitHubActions->>GitHubActions: sleep 60s if in-progress
end
alt success
GitHubActions-->>Contributor: Job succeeds
else failed or canceled
GitHubActions-->>Contributor: Job fails
end
Related PRs: None identified. Suggested labels: ci, github-actions Suggested reviewers: None identified. Poem 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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.
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
Chores