Skip to content

LCORE-2916: Slack notification for providers e2e tests#2199

Open
jrobertboos wants to merge 1 commit into
lightspeed-core:mainfrom
jrobertboos:lcore-2916
Open

LCORE-2916: Slack notification for providers e2e tests#2199
jrobertboos wants to merge 1 commit into
lightspeed-core:mainfrom
jrobertboos:lcore-2916

Conversation

@jrobertboos

@jrobertboos jrobertboos commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a consolidated Slack notification to the provider e2e test workflow so failures are reported per mode/environment combination instead of just an overall pass/fail. Each e2e_tests matrix job (2 modes × 4 environments) now captures its own behave output, extracts the Failing scenarios: block on failure, and uploads it as a result artifact. A new notify job downloads all artifacts and posts a single Slack webhook payload with one field per <mode>_<environment> key (e.g. server_azure, library_watsonx) containing that job's failing scenarios (or "None" on success, "N/A" if a job never ran), plus a run_url field linking back to the workflow run. This makes it much faster to see exactly which provider/mode combinations broke and why, straight from Slack, without digging through 8 separate CI job logs.

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement
  • Benchmarks improvement

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: Cursor (Claude Sonnet 5)
  • Generated by: N/A

Related Tickets & Documents

  • Related Issue LCORE-2916
  • Closes LCORE-2916

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • Validated the workflow YAML parses correctly.
  • Dry-ran the jq payload-construction logic locally with sample data to confirm it produces the expected {run_url, server_azure, server_vertexai, server_watsonx, server_bedrock, library_azure, library_vertexai, library_watsonx, library_bedrock} shape, including correct escaping of multi-line failing-scenario strings.
  • Verified the awk/sed extraction correctly pulls out the Failing scenarios: block from a sample behave-style log, including stripping ANSI color codes.
  • Not yet verified against a live scheduled/dispatched workflow run — recommend triggering workflow_dispatch once merged to confirm the actual Slack message renders as expected against the real Slack workflow trigger's input variables.

Summary by CodeRabbit

  • Tests
    • Improved end-to-end test reporting by capturing complete test output and identifying failing scenarios.
    • Added consolidated reporting across test modes and environments.
    • Enhanced Slack notifications with detailed failure information and fallback status details.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The E2E workflow now captures test output, extracts failing scenarios into per-matrix-job JSON artifacts, consolidates all matrix results, and posts the combined payload to Slack.

Changes

E2E reporting workflow

Layer / File(s) Summary
Capture E2E output and publish results
.github/workflows/e2e_tests_providers.yaml
The workflow streams make test-e2e output through tee, parses failing scenarios in an always() step, writes result.json, and uploads the result artifact.
Aggregate matrix results and notify Slack
.github/workflows/e2e_tests_providers.yaml
The notification job downloads all result artifacts, fills missing combinations with "N/A" fields, consolidates results by mode and environment, and posts them to the Slack webhook.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: samdoran, radofuchs

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: consolidated Slack notifications for provider e2e tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Performance And Algorithmic Complexity ✅ Passed No meaningful performance regression found: artifact download and JSON aggregation are single-pass over 8 matrix results, with no N+1, quadratic loops, or unbounded growth.
Security And Secret Handling ✅ Passed No plaintext secrets/hardcoded tokens or new auth/injection issues in the added workflow steps; Slack payload only carries test-result text.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified 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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/e2e_tests_providers.yaml:
- Around line 376-403: Update the workflow step to expose matrix.mode and
matrix.environment through environment variables alongside JOB_STATUS, then pass
those variables to jq via the existing --arg options instead of interpolating
GitHub Actions expressions inside the run script. Preserve the current
result.json fields and values.
- Around line 455-460: Update the jq invocation in the payload construction to
request compact JSON output with the -c option. Keep the existing --argjson,
--arg, and transformation logic unchanged so payload contains a single-line JSON
string before the subsequent echo.
🪄 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: f413d7e2-999c-42cc-98f1-30f07f5557ed

📥 Commits

Reviewing files that changed from the base of the PR and between 066c991 and 5b0bce5.

📒 Files selected for processing (1)
  • .github/workflows/e2e_tests_providers.yaml
📜 Review details
⏰ Context from checks skipped due to timeout. (17)
  • GitHub Check: build-pr
  • GitHub Check: mypy
  • GitHub Check: radon
  • GitHub Check: Pyright
  • GitHub Check: Pylinter
  • GitHub Check: unit_tests (3.12)
  • GitHub Check: unit_tests (3.13)
  • GitHub Check: integration_tests (3.13)
  • GitHub Check: integration_tests (3.12)
  • GitHub Check: E2E Tests for Lightspeed Evaluation job
  • GitHub Check: E2E: server mode / ci / group 2
  • GitHub Check: E2E: library mode / ci / group 2
  • GitHub Check: E2E: server mode / ci / group 1
  • GitHub Check: E2E: library mode / ci / group 3
  • GitHub Check: E2E: library mode / ci / group 1
  • GitHub Check: E2E: server mode / ci / group 3
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-0-7-on-pull-request
🧰 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/e2e_tests_providers.yaml
🪛 zizmor (1.26.1)
.github/workflows/e2e_tests_providers.yaml

[warning] 398-398: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 399-399: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 407-407: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 421-421: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

Comment on lines +376 to +403
env:
JOB_STATUS: ${{ job.status }}
run: |
mkdir -p ./e2e-result

# Extract the "Failing scenarios:" block that behave prints on failure.
FAILING_SCENARIOS=""
if [ -f e2e-test-output.log ]; then
FAILING_SCENARIOS=$(sed 's/\x1b\[[0-9;]*m//g' e2e-test-output.log \
| awk '/^Failing scenarios:/{flag=1; next} /^$/{flag=0} flag' \
| sed 's/^[[:space:]]*//')
fi

if [ -z "${FAILING_SCENARIOS}" ]; then
if [ "${JOB_STATUS}" == "success" ]; then
FAILING_SCENARIOS="None"
else
FAILING_SCENARIOS="Job ${JOB_STATUS} - no failing scenarios captured (see run logs)"
fi
fi

jq -n \
--arg mode "${{ matrix.mode }}" \
--arg environment "${{ matrix.environment }}" \
--arg status "${JOB_STATUS}" \
--arg failing_scenarios "${FAILING_SCENARIOS}" \
'{mode: $mode, environment: $environment, status: $status, failing_scenarios: $failing_scenarios}' \
> ./e2e-result/result.json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use environment variables for matrix context to prevent shell injection risks.

While the current matrix values are statically defined and safe, it is a security best practice to pass GitHub Actions expressions (like ${{ matrix... }}) into bash scripts via environment variables rather than inline template expansion. This addresses static analysis warnings and prevents potential shell injection vulnerabilities if the matrix is ever updated to use dynamic or external inputs.

♻️ Proposed refactor
         env:
           JOB_STATUS: ${{ job.status }}
+          MATRIX_MODE: ${{ matrix.mode }}
+          MATRIX_ENVIRONMENT: ${{ matrix.environment }}
         run: |
           mkdir -p ./e2e-result
 
           # Extract the "Failing scenarios:" block that behave prints on failure.
           FAILING_SCENARIOS=""
           if [ -f e2e-test-output.log ]; then
             FAILING_SCENARIOS=$(sed 's/\x1b\[[0-9;]*m//g' e2e-test-output.log \
               | awk '/^Failing scenarios:/{flag=1; next} /^$/{flag=0} flag' \
               | sed 's/^[[:space:]]*//')
           fi
 
           if [ -z "${FAILING_SCENARIOS}" ]; then
             if [ "${JOB_STATUS}" == "success" ]; then
               FAILING_SCENARIOS="None"
             else
               FAILING_SCENARIOS="Job ${JOB_STATUS} - no failing scenarios captured (see run logs)"
             fi
           fi
 
           jq -n \
-            --arg mode "${{ matrix.mode }}" \
-            --arg environment "${{ matrix.environment }}" \
+            --arg mode "${MATRIX_MODE}" \
+            --arg environment "${MATRIX_ENVIRONMENT}" \
             --arg status "${JOB_STATUS}" \
             --arg failing_scenarios "${FAILING_SCENARIOS}" \
             '{mode: $mode, environment: $environment, status: $status, failing_scenarios: $failing_scenarios}' \
             > ./e2e-result/result.json
📝 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.

Suggested change
env:
JOB_STATUS: ${{ job.status }}
run: |
mkdir -p ./e2e-result
# Extract the "Failing scenarios:" block that behave prints on failure.
FAILING_SCENARIOS=""
if [ -f e2e-test-output.log ]; then
FAILING_SCENARIOS=$(sed 's/\x1b\[[0-9;]*m//g' e2e-test-output.log \
| awk '/^Failing scenarios:/{flag=1; next} /^$/{flag=0} flag' \
| sed 's/^[[:space:]]*//')
fi
if [ -z "${FAILING_SCENARIOS}" ]; then
if [ "${JOB_STATUS}" == "success" ]; then
FAILING_SCENARIOS="None"
else
FAILING_SCENARIOS="Job ${JOB_STATUS} - no failing scenarios captured (see run logs)"
fi
fi
jq -n \
--arg mode "${{ matrix.mode }}" \
--arg environment "${{ matrix.environment }}" \
--arg status "${JOB_STATUS}" \
--arg failing_scenarios "${FAILING_SCENARIOS}" \
'{mode: $mode, environment: $environment, status: $status, failing_scenarios: $failing_scenarios}' \
> ./e2e-result/result.json
env:
JOB_STATUS: ${{ job.status }}
MATRIX_MODE: ${{ matrix.mode }}
MATRIX_ENVIRONMENT: ${{ matrix.environment }}
run: |
mkdir -p ./e2e-result
# Extract the "Failing scenarios:" block that behave prints on failure.
FAILING_SCENARIOS=""
if [ -f e2e-test-output.log ]; then
FAILING_SCENARIOS=$(sed 's/\x1b\[[0-9;]*m//g' e2e-test-output.log \
| awk '/^Failing scenarios:/{flag=1; next} /^$/{flag=0} flag' \
| sed 's/^[[:space:]]*//')
fi
if [ -z "${FAILING_SCENARIOS}" ]; then
if [ "${JOB_STATUS}" == "success" ]; then
FAILING_SCENARIOS="None"
else
FAILING_SCENARIOS="Job ${JOB_STATUS} - no failing scenarios captured (see run logs)"
fi
fi
jq -n \
--arg mode "${MATRIX_MODE}" \
--arg environment "${MATRIX_ENVIRONMENT}" \
--arg status "${JOB_STATUS}" \
--arg failing_scenarios "${FAILING_SCENARIOS}" \
'{mode: $mode, environment: $environment, status: $status, failing_scenarios: $failing_scenarios}' \
> ./e2e-result/result.json
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 398-398: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 399-399: 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/e2e_tests_providers.yaml around lines 376 - 403, Update
the workflow step to expose matrix.mode and matrix.environment through
environment variables alongside JOB_STATUS, then pass those variables to jq via
the existing --arg options instead of interpolating GitHub Actions expressions
inside the run script. Preserve the current result.json fields and values.

Source: Linters/SAST tools

Comment on lines +455 to +460
payload=$(echo "${ALL_RESULTS}" | jq \
--argjson fields "${BASE_FIELDS}" \
--arg run "${RUN_URL}" \
'{run_url: $run} + (reduce .[] as $r ($fields; . + {(($r.mode + "_" + $r.environment)): $r.failing_scenarios}))')

echo "Payload: ${payload}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use compact JSON output for the payload.

jq pretty-prints JSON by default, which introduces internal newlines into the payload bash variable. While curl generally handles multiline data properly, generating a compact JSON string using the -c flag is safer for bash variables and produces cleaner, more readable log output on the subsequent echo command.

♻️ Proposed refactor
           # Build one field per "<mode>_<environment>" key holding that job's failing scenarios.
-          payload=$(echo "${ALL_RESULTS}" | jq \
+          payload=$(echo "${ALL_RESULTS}" | jq -c \
             --argjson fields "${BASE_FIELDS}" \
             --arg run "${RUN_URL}" \
             '{run_url: $run} + (reduce .[] as $r ($fields; . + {(($r.mode + "_" + $r.environment)): $r.failing_scenarios}))')
 
           echo "Payload: ${payload}"
📝 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.

Suggested change
payload=$(echo "${ALL_RESULTS}" | jq \
--argjson fields "${BASE_FIELDS}" \
--arg run "${RUN_URL}" \
'{run_url: $run} + (reduce .[] as $r ($fields; . + {(($r.mode + "_" + $r.environment)): $r.failing_scenarios}))')
echo "Payload: ${payload}"
payload=$(echo "${ALL_RESULTS}" | jq -c \
--argjson fields "${BASE_FIELDS}" \
--arg run "${RUN_URL}" \
'{run_url: $run} + (reduce .[] as $r ($fields; . + {(($r.mode + "_" + $r.environment)): $r.failing_scenarios}))')
echo "Payload: ${payload}"
🤖 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/e2e_tests_providers.yaml around lines 455 - 460, Update
the jq invocation in the payload construction to request compact JSON output
with the -c option. Keep the existing --argjson, --arg, and transformation logic
unchanged so payload contains a single-line JSON string before the subsequent
echo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant