mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-03 16:10:21 +00:00
Follow-up tooling to [#12946](https://github.com/openobserve/openobserve/pull/12946). Pairs with the [ENT MCP-fixes PR](https://github.com/openobserve/o2-enterprise/pull/2072) to complete the loop from "engine works on one issue" → "batch of 100 fires in parallel and lands verdicts in a reviewable table." ## Summary - **`scripts/test-assist-ci-batch.sh`** — POSIX bash script that dispatches the test-assist engine (in o2-enterprise) for a list of OSS issues. Reads issue numbers from stdin or positional args. Supports `--dry-run`, `--write-mode`, `--throttle`. Uses `gh workflow run` under the maintainer's local `gh auth`. Each dispatch is fire-and-forget; the engine's own concurrency group (`source_repo+issue`) enforces one-run-per-issue-at-a-time. - **`qa-reports/test-assist-ci-backlog-sweep.md`** — Roll-up table where verdicts land after each batch. Documents the tier structure of the priority-100 list, the verdict-to-action map (FIXED / STILL_PRESENT / INCONCLUSIVE / SKIP), and the tier queries used to build the list. Table starts empty; batches append rows. ## Usage ```bash # One-shot: dispatch for a single issue ./scripts/test-assist-ci-batch.sh 12452 # Batch: dispatch for many issues in parallel (from stdin) gh issue list --repo openobserve/openobserve --label "☢️ Bug" --label "Retested-Failed" --state open --limit 30 \ --json number --jq '.[].number' \ | ./scripts/test-assist-ci-batch.sh # Dry-run to see what would fire (no dispatches) ./scripts/test-assist-ci-batch.sh --dry-run 12452 11700 12647 # Explicitly enable label+comment writes (only after soak calibration) ./scripts/test-assist-ci-batch.sh --write-mode < /tmp/batch.txt ``` ## Interaction with the `Test-Assist-CI-Verified` label The ENT engine ([PR #2072](https://github.com/openobserve/o2-enterprise/pull/2072)) applies the `Test-Assist-CI-Verified` label to each processed issue as factual metadata (independent of `write_mode`). After a batch: - [Filter checked issues](https://github.com/openobserve/openobserve/issues?q=is%3Aissue+label%3A%22Test-Assist-CI-Verified%22) → the ones we've processed - [Filter unchecked issues](https://github.com/openobserve/openobserve/issues?q=is%3Aissue+is%3Aopen+label%3A%22%E2%98%A2%EF%B8%8F+Bug%22+-label%3A%22Test-Assist-CI-Verified%22) → the untouched backlog ## Test plan - [ ] `bash -n scripts/test-assist-ci-batch.sh` — script parses (verified locally) - [ ] `./scripts/test-assist-ci-batch.sh --dry-run 12452` — prints "DRY: would dispatch #12452" - [ ] After ENT PR #2072 merges: fire a single-issue dispatch via the script → confirm run appears in o2-enterprise Actions - [ ] Fire the 100-issue batch → confirm verdicts populate the sweep markdown 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
167 lines
5.4 KiB
Bash
Executable File
167 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# scripts/test-assist-ci-batch.sh — batch dispatcher for the Test-Assist CI engine.
|
|
#
|
|
# Fires the `test-assist.yml` engine (in o2-enterprise) in parallel for a list of OSS issues.
|
|
# Each engine run is its own concurrency group (keyed on source_repo+issue), so GitHub Actions
|
|
# runs them in parallel up to the runner cap.
|
|
#
|
|
# Usage:
|
|
# ./scripts/test-assist-ci-batch.sh < issue-numbers.txt # one number per line (stdin)
|
|
# ./scripts/test-assist-ci-batch.sh 12452 11700 12647 # positional args
|
|
# echo "12452 11700 12647" | tr ' ' '\n' | ./scripts/test-assist-ci-batch.sh
|
|
#
|
|
# Requires: `gh` authenticated with a token that has Actions:write on openobserve/o2-enterprise
|
|
# (typically the maintainer's PAT — `gh auth login` interactively works).
|
|
#
|
|
# Options:
|
|
# --repo-engine REPO Override the engine repo (default: openobserve/o2-enterprise).
|
|
# Restricted to an allowlist to prevent redirecting dispatches.
|
|
# --source-repo NAME Override the source repo short name (default: openobserve).
|
|
# --write-mode Set write_mode=true (default: false — no GitHub verdict writes).
|
|
# --max-parallel N Cap concurrent dispatches (default: 20). Waits when at cap.
|
|
# --throttle SECS Sleep between dispatches (default: 2). Reduces API burst.
|
|
# --dry-run Print what would be dispatched; don't call gh.
|
|
#
|
|
set -euo pipefail
|
|
|
|
REPO_ENGINE="openobserve/o2-enterprise"
|
|
SOURCE_REPO="openobserve"
|
|
WORKFLOW="test-assist.yml"
|
|
WRITE_MODE="false"
|
|
THROTTLE="2"
|
|
MAX_PARALLEL="20"
|
|
DRY_RUN=""
|
|
|
|
# Allowlist of accepted engine-repos. Prevents an accidental (or malicious) override from
|
|
# redirecting maintainer-PAT dispatches to an unrelated repo.
|
|
ALLOWED_ENGINES=("openobserve/o2-enterprise")
|
|
|
|
is_allowed_engine() {
|
|
local candidate="$1"
|
|
for e in "${ALLOWED_ENGINES[@]}"; do
|
|
[ "$candidate" = "$e" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Parse flags.
|
|
args=()
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--repo-engine) REPO_ENGINE="$2"; shift 2;;
|
|
--source-repo) SOURCE_REPO="$2"; shift 2;;
|
|
--write-mode) WRITE_MODE="true"; shift;;
|
|
--max-parallel) MAX_PARALLEL="$2"; shift 2;;
|
|
--throttle) THROTTLE="$2"; shift 2;;
|
|
--dry-run) DRY_RUN="1"; shift;;
|
|
-h|--help) grep -E '^# ' "$0" | sed 's/^# //'; exit 0;;
|
|
*) args+=("$1"); shift;;
|
|
esac
|
|
done
|
|
|
|
# Validate the engine target BEFORE reading any input.
|
|
if ! is_allowed_engine "$REPO_ENGINE"; then
|
|
echo "::error::--repo-engine \"$REPO_ENGINE\" is not in the allowlist (${ALLOWED_ENGINES[*]})" >&2
|
|
echo "::error::Extend ALLOWED_ENGINES in this script if you need a new target." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Read issue list from positional args, or stdin if no args.
|
|
if [ "${#args[@]}" -eq 0 ]; then
|
|
mapfile -t NUMS < <(grep -E '^[0-9]+$')
|
|
else
|
|
NUMS=("${args[@]}")
|
|
fi
|
|
|
|
[ "${#NUMS[@]}" -gt 0 ] || { echo "::error::no issue numbers provided" >&2; exit 1; }
|
|
|
|
echo "==========================================="
|
|
echo "Test-Assist CI — batch dispatch"
|
|
echo " engine: $REPO_ENGINE (workflow: $WORKFLOW)"
|
|
echo " source: $SOURCE_REPO"
|
|
echo " count: ${#NUMS[@]}"
|
|
echo " max_parallel: $MAX_PARALLEL"
|
|
echo " throttle: ${THROTTLE}s"
|
|
echo " write_mode: $WRITE_MODE"
|
|
[ -n "$DRY_RUN" ] && echo " (DRY RUN — no dispatches)"
|
|
echo "==========================================="
|
|
|
|
# Pre-flight: verify gh auth works and can hit the workflow.
|
|
if [ -z "$DRY_RUN" ]; then
|
|
gh workflow view "$WORKFLOW" --repo "$REPO_ENGINE" >/dev/null 2>&1 \
|
|
|| { echo "::error::cannot access workflow $WORKFLOW on $REPO_ENGINE — check gh auth + PAT scopes"; exit 1; }
|
|
fi
|
|
|
|
# Track results properly (previous version silently swallowed backgrounded failures).
|
|
TMPDIR=$(mktemp -d)
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
PID_TO_ISSUE="$TMPDIR/pid-to-issue"
|
|
: > "$PID_TO_ISSUE"
|
|
DISPATCHED=0
|
|
FAILED=0
|
|
SKIPPED=0
|
|
ACTIVE=0
|
|
|
|
for N in "${NUMS[@]}"; do
|
|
if ! [[ "$N" =~ ^[0-9]+$ ]]; then
|
|
echo " skip non-numeric: $N" >&2
|
|
SKIPPED=$(( SKIPPED + 1 ))
|
|
continue
|
|
fi
|
|
|
|
# Bounded parallelism: wait for a slot before firing the next dispatch.
|
|
while [ "$ACTIVE" -ge "$MAX_PARALLEL" ]; do
|
|
wait -n
|
|
ACTIVE=$(( ACTIVE - 1 ))
|
|
done
|
|
|
|
if [ -n "$DRY_RUN" ]; then
|
|
echo " DRY: would dispatch #$N"
|
|
DISPATCHED=$(( DISPATCHED + 1 ))
|
|
continue
|
|
fi
|
|
|
|
echo " dispatch #$N"
|
|
gh workflow run "$WORKFLOW" \
|
|
--repo "$REPO_ENGINE" \
|
|
--ref main \
|
|
-f source_repo="$SOURCE_REPO" \
|
|
-f issue_number="$N" \
|
|
-f fixture_mode=false \
|
|
-f write_mode="$WRITE_MODE" \
|
|
>/dev/null 2>>"$TMPDIR/errors.log" &
|
|
echo "$! $N" >> "$PID_TO_ISSUE"
|
|
ACTIVE=$(( ACTIVE + 1 ))
|
|
sleep "$THROTTLE"
|
|
done
|
|
|
|
# Wait for the remaining background jobs, tallying failures.
|
|
while read -r pid issue; do
|
|
if ! wait "$pid" 2>/dev/null; then
|
|
echo " FAILED: dispatch for #$issue" >&2
|
|
FAILED=$(( FAILED + 1 ))
|
|
else
|
|
DISPATCHED=$(( DISPATCHED + 1 ))
|
|
fi
|
|
done < "$PID_TO_ISSUE"
|
|
|
|
echo ""
|
|
echo "==========================================="
|
|
echo "Done."
|
|
echo " Dispatched: $DISPATCHED"
|
|
echo " Failed: $FAILED"
|
|
echo " Skipped: $SKIPPED (non-numeric input)"
|
|
if [ "$FAILED" -gt 0 ]; then
|
|
echo ""
|
|
echo "See errors:"
|
|
head -30 "$TMPDIR/errors.log" 2>/dev/null || true
|
|
fi
|
|
echo ""
|
|
echo "Track progress:"
|
|
echo " https://github.com/${REPO_ENGINE}/actions/workflows/${WORKFLOW}"
|
|
echo "==========================================="
|
|
|
|
# Non-zero exit if any dispatches failed — lets CI-invoked callers detect.
|
|
[ "$FAILED" -eq 0 ]
|