ci: emit per-shard rows for UI runs (ci_test_runs_shards) — e2e per-shard dashboards (#12919)

Gives the **e2e/UI tabs** the same per-shard breakdown that Regression
already has (Slowest Shards / Shard Duration over time / Per-Module
Health).

`o2-run-report.sh` already sees every `e2e /` shard job in `THIS_JOBS`;
this also flattens them to one row per shard in
**`ci_test_runs_shards`** (mirrors `ci_regression_shards`). API runs
have no `e2e /` jobs → no-op. `_timestamp` unset → ingest time (aligned
with the run doc). bash + jq verified locally.

Pairs with the same-branch ENT PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Shrinath Rao
2026-06-29 03:06:50 +00:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 99b3093c2f
commit 0a2cbdb387
2 changed files with 26 additions and 2 deletions
+7 -2
View File
@@ -33,14 +33,19 @@ if [ ! -s "$PAYLOAD" ]; then
exit 0
fi
# OpenObserve's _json endpoint accepts a single object or an array; wrap to an array.
# Stream the body from a temp file (mktemp → unique per invocation, no shared-/tmp races,
# no whole-payload-in-a-shell-var).
URL="${O2_REPORTING_INGEST_BASE%/}/${STREAM}/_json"
BODY_FILE=$(mktemp "${TMPDIR:-/tmp}/o2_report_body.XXXXXX")
RESP_FILE=$(mktemp "${TMPDIR:-/tmp}/o2_report_resp.XXXXXX")
trap 'rm -f "$BODY_FILE" "$RESP_FILE"' EXIT
{ printf '['; cat "$PAYLOAD"; printf ']'; } > "$BODY_FILE"
# _json accepts a single object OR an array. Wrap a bare object in [ ]; pass an existing array
# through unchanged so multi-row callers (e.g. per-shard rows) aren't double-wrapped into [[...]].
if [ "$(tr -d '[:space:]' < "$PAYLOAD" | cut -c1)" = "[" ]; then
cat "$PAYLOAD" > "$BODY_FILE"
else
{ printf '['; cat "$PAYLOAD"; printf ']'; } > "$BODY_FILE"
fi
INSECURE=""
[ "${O2_REPORTING_INSECURE:-}" = "true" ] && INSECURE="-k"
+19
View File
@@ -107,3 +107,22 @@ if [ -n "${EXTRA_JSON:-}" ] && printf '%s' "$EXTRA_JSON" | jq -e . >/dev/null 2>
fi
bash "$(dirname "$0")/o2-report.sh" "$STREAM" "$PAYLOAD_FILE"
# For runs with e2e shard jobs (UI), also emit one row per shard to <STREAM>_shards so dashboards
# can break down per-shard duration / slowest shard / per-module health (mirrors ci_regression_shards).
# API runs have no "e2e /" jobs, so this is a no-op there. Row schema:
# run_id, repo, suite, workflow, ingest_source, shard_name, module (shard minus "e2e / "),
# conclusion, duration_sec. _timestamp left unset -> ingest time (aligned with the run doc).
# Notes: THIS_JOBS is the jobs API object {jobs:[...]}, piped in (so .jobs[]); workflow:"test" is
# fixed to match the run doc's tag; duration clamped to >=0 to guard against runner clock skew.
SHARD_FILE=$(mktemp "${TMPDIR:-/tmp}/o2_shards.XXXXXX")
shard_rows=$(printf '%s' "$THIS_JOBS" | jq -c --arg repo "$GITHUB_REPOSITORY" --arg run_id "$GITHUB_RUN_ID" --arg suite "$SUITE" \
'[.jobs[]? | select(.name|startswith("e2e /")) | {
run_id:$run_id, repo:$repo, suite:$suite, workflow:"test", ingest_source:"live",
shard_name:.name, module:(.name|sub("^e2e / ";"")), conclusion:.conclusion,
duration_sec: (if (.completed_at and .started_at) then ([((.completed_at|fromdateiso8601)-(.started_at|fromdateiso8601)|floor), 0] | max) else null end)
}]' 2>/dev/null) && printf '%s' "$shard_rows" > "$SHARD_FILE" || { echo '[]' > "$SHARD_FILE"; echo "::warning::shard-row extraction failed — skipping ${STREAM}_shards"; }
if [ "$(jq 'length' "$SHARD_FILE" 2>/dev/null || echo 0)" -gt 0 ]; then
bash "$(dirname "$0")/o2-report.sh" "${STREAM}_shards" "$SHARD_FILE"
fi
rm -f "$SHARD_FILE"