Skip to content

Seed redisearch-ci-common: shared Codex plumbing, CI utilities, flaky DB - #1

Merged
kei-nan merged 15 commits into
mainfrom
seed/common-codex-plumbing
Jun 24, 2026
Merged

Seed redisearch-ci-common: shared Codex plumbing, CI utilities, flaky DB#1
kei-nan merged 15 commits into
mainfrom
seed/common-codex-plumbing

Conversation

@kei-nan

@kei-nan kei-nan commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Seeds this repo with generic, reusable GitHub Actions building blocks so
RediSearch CI workflows share one implementation instead of each carrying a copy.
Each consumer keeps a thin caller; the shared logic lives here.

What this adds

Codex agent plumbing

Unit Kind Purpose
.github/actions/codex-run composite Run openai/codex-action as a step that can modify the tree (workspace-write), with the hardened posture (SHA-pinned, network-only egress, drop-sudo).
.github/actions/codex-ci-triage composite Run Codex read-only to analyze CI logs/reports; returns the summary as outputs for Slack/PR embedding. Never fails the job.
.github/workflows/codex-agent.yml reusable workflow Whole job: App-token mint → checkout caller repo → optional resolver → codex-run. For label/comment callers.
scripts/ci_common/common.py script gh / $GITHUB_OUTPUT / context-file helpers.

CI utilities

Unit Kind Purpose
.github/actions/slack-notify composite Post a payload to a Slack webhook (webhook is a caller secret).
.github/workflows/pr-size-label.yml reusable Label a PR by diff size.
.github/workflows/spellcheck.yml reusable codespell over a PR's changed files (caller supplies .codespell/).
.github/workflows/link-check.yml reusable Validate Markdown links and anchors; self-contained via bundled check_links.py.

Flaky-test DB (keyed by REPO/BRANCH)

Unit Kind Purpose
.github/workflows/flaky-mark.yml / flaky-unmark.yml reusable Mark / unmark a flaky test (consumer adds a thin workflow_dispatch caller).
.github/actions/flaky-record-results composite Record an RLTest run's failed/passed ids (if: always(), never fails the job).
scripts/ci_common/flaky_db.py script mark/unmark/fetch/filter/record CLI (no-op when REDIS_URL unset).

Self-CI.github/workflows/ci.yml lints this repo on every PR: actionlint, a strict-YAML duplicate-key check (workflows + composite actions), and compileall over the Python.

License: Redis tri-license (RSALv2 / SSPLv1 / AGPLv3).

Conventions

  • Generic only: no secrets, no repo-specific logic — callers pass those in.
  • Ported units mirror their OSS originals; they diverge only where reuse requires it (workflow_call, parameterized base/paths, bundled scripts) or where a review found a genuine bug.
  • Consumers should pin to an immutable ref (@vN tag or SHA), not @main. Suggest cutting v1 once this merges; the internal codex-agent → codex-run ref uses @main and moves to the tag per release.
  • The flaky tooling is RLTest-id-shaped (not framework-agnostic); quarantining requires each repo's test pipeline to call fetch/filter/record.

Review notes

All Cursor Bugbot findings were triaged and resolved on-thread — real bugs fixed (e.g. spellcheck spaced-paths + merge-queue base, link-check PR-context gate, flaky-DB cache race + fetch exit code, bare-URL trimming, relative-anchor validation, codex-ci-triage allow-users key + SHA pin), invalid/false-positive ones explained and matched to OSS. The codex-ci-triage allow-users duplicate-key drop and the merge-queue base handling are latent upstream too — worth mirroring back to OSS (separate, not this PR).

🤖 Generated with Claude Code


Note

Medium Risk
New CI surface touches GitHub App tokens, OpenAI keys, and shared Redis flaky state; Codex paths are hardened but still run third-party agents with outbound network on write flows.

Overview
Introduces redisearch-ci-common as a new shared library of GitHub Actions and Python helpers so RediSearch-family repos can workflow_call / composite uses: instead of duplicating CI plumbing.

Codex: Adds codex-run (workspace-write, SHA-pinned openai/codex-action, network egress + drop-sudo) and codex-ci-triage (read-only, continue-on-error, triage text via final-message outputs including JSON). Adds reusable codex-agent (App token, checkout caller repo, optional resolver, then codex-run).

Utilities: slack-notify, reusable workflows for PR size labels, spellcheck on changed files (merge-queue base + NUL-delimited paths), and Markdown link/anchor checks via bundled check_links.py. Self-CI runs actionlint, strict YAML duplicate-key lint, and compileall on scripts/.

Flaky tests: Redis-backed flaky_db.py (mark/unmark/fetch/filter/record), mark/unmark reusable workflows, and flaky-record-results (branch resolution for merge queue, never fails the job).

Also adds README, tri-license texts, and .gitignore.

Reviewed by Cursor Bugbot for commit eae790c. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread .github/workflows/codex-agent.yml Outdated
Comment thread .github/workflows/codex-agent.yml Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

1 similar comment
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Comment thread .github/workflows/codex-agent.yml
@kei-nan kei-nan self-assigned this Jun 24, 2026
Comment thread .github/workflows/link-check.yml Outdated
Comment thread .github/workflows/spellcheck.yml Outdated
Comment thread scripts/ci_common/check_links.py
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@kei-nan kei-nan changed the title Seed shared Codex CI plumbing (codex-run, codex-agent, common.py) Seed redisearch-ci-common: shared Codex plumbing + CI utilities + flaky DB Jun 24, 2026
Comment thread .github/workflows/link-check.yml Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

kei-nan and others added 2 commits June 24, 2026 14:02
Match the RediSearch project's licensing so this repo carries an explicit grant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generic, reusable GitHub Actions building blocks so RediSearch CI workflows
share one implementation instead of each carrying a copy:

- Codex plumbing: codex-run composite action (SHA-pinned openai/codex-action
  with a hardened sandbox posture), codex-agent reusable workflow (App-token
  mint + checkout + optional resolver + codex-run), and scripts/ci_common/common.py.
- CI utilities: slack-notify action; pr-size-label, spellcheck and link-check
  reusable workflows (link-check bundles scripts/ci_common/check_links.py).
- Flaky-test DB: flaky-mark / flaky-unmark reusable workflows plus
  scripts/ci_common/flaky_db.py (no-op when REDIS_URL is unset).

Everything here is generic: no secrets and no repo-specific logic — callers pass
those in as inputs and secrets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kei-nan
kei-nan force-pushed the seed/common-codex-plumbing branch from 37aa3c0 to 0275d89 Compare June 24, 2026 11:02
Comment thread .github/workflows/codex-agent.yml
Comment thread .github/workflows/spellcheck.yml Outdated
Comment thread scripts/ci_common/flaky_db.py Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@kei-nan kei-nan changed the title Seed redisearch-ci-common: shared Codex plumbing + CI utilities + flaky DB Seed shared RediSearch CI building blocks Jun 24, 2026
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Completes the shared flaky-test toolkit: a generic, self-contained action that
records an RLTest run's failed/passed test ids to the REPO/BRANCH-keyed DB via
the bundled flaky_db.py. Never fails the job (warns on DB outage); use with
if: always(). Operates purely on RLTest's <test_file>:<test_name>[variant] ids,
so it is test-framework generic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread scripts/ci_common/check_links.py
Comment thread .github/workflows/spellcheck.yml Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Correct an overclaim: the generic units (codex plumbing, slack-notify,
pr-size-label, spellcheck, link-check) are test-framework agnostic, but the
flaky toolkit expects RLTest-style test ids. Say so plainly rather than implying
universality.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Comment thread .github/workflows/spellcheck.yml Outdated
- codex-agent: omit owner/repositories so create-github-app-token scopes the
  token to the caller repo by default — robust regardless of the caller event
  payload shape (resolves the App-token-scope finding and the stale target-repo
  trio from the pre-simplification commit).
- spellcheck: guard against an empty base ref (clear error instead of
  'git fetch origin ""'); NUL-delimit the changed-file list (-z / xargs -0) so
  paths with spaces aren't split.
- link-check: drop the dead 'upload *.log' step (the bundled checker prints to
  stdout, never writes logs); gate the PR comment on github.event.pull_request.

Not changed: check_links.py thread-safety / relative-anchor checks and
flaky_db.py fetch exit code are pre-existing in the copies vendored from the
upstream RediSearch repo; fixing them here would fork those files (better fixed
upstream so the fix flows back). The link-check PR-comment gate was a false
positive (github.event_name reflects the caller event under workflow_call).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kei-nan

kei-nan commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Bugbot triage + dispositions

Thanks Bugbot — went through all findings. Summary (HEAD now at the latest push):

Fixed

  • App token scope (codex-agent) — now omit owner/repositories so create-github-app-token scopes the token to the caller repo by its built-in default, independent of the event payload shape. This also retires the earlier target-repo/owner/GH_REPO/"empty checkout" findings: those inputs were removed when the workflow was simplified to caller-repo-only.
  • Spellcheck — spaced paths — switched to git diff -z … | xargs -0 so paths with spaces aren't split.
  • Spellcheck — empty base ref — added an explicit guard that errors clearly (instead of git fetch origin "") when no base can be resolved.
  • Link-check — missing log upload — removed the dead Upload *.log step; the bundled checker prints to stdout and never writes log files.

False positive (hardened anyway)

  • Link-check — "PR comment never runs" — under workflow_call the github context (incl. event_name/event) reflects the caller's event, so the gate fires correctly when called from a pull_request workflow. I changed it to github.event.pull_request to make that unambiguous.

Deferred — vendored from upstream (intentionally not forked here)

  • check_links.py shared Session/checked_urls thread-safety, and relative-anchor fragment checking; flaky_db.py fetch returning exit 0 on Redis error. These files are copied verbatim from the upstream RediSearch repo (the canonical source). Fixing them here would fork them and cause drift; they should be fixed upstream so the fix flows back. Tracking separately.

@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

The read-only counterpart to codex-run: runs Codex with sandbox: read-only +
drop-sudo to analyze CI logs/reports (safe against prompt injection in
attacker-controlled fork-PR logs) and exposes the summary as step outputs
(triage-exists / triage-content / triage-content-json) for Slack/PR embedding.
Codex failures never fail the calling job.

This is the shared runner that triage and backport-agent workflows sit on top of.
Those workflows + their prompts stay per-repo (product-specific CI formats,
labels, file-area heuristics); only the runner is common.

Pinned openai/codex-action to a SHA (matches codex-run) and fixed a latent
duplicate allow-users key from the original by comma-joining the merge-queue
actor with the caller-supplied list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@kei-nan

kei-nan commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

@sera bypass

…divergence)

Per guidance to stay faithful to the OSS workflows (their shape is intentional),
revert behavioral 'fixes' on ported units and only keep changes genuinely needed
for reuse / self-containment / public-safety:

- codex-ci-triage: restored verbatim to the OSS action — read-only + drop-sudo,
  openai/codex-action@v1, and the intentional allow-bots/allow-users/
  allow-bot-users block (the bare github-merge-queue under allow-users AND the
  [bot] form under allow-bot-users is a needed duplication, not a bug).
- codex-agent: token step back to the OSS backport pattern (owner +
  repositories: github.event.repository.name + permission-*); added an
  allow-users input forwarded to codex-run, alongside allow-bots/allow-bot-users.
- codex-run: added the allow-users input (needed wherever allow-bots is, for the
  bare-actor form) and pass it through.
- spellcheck: reverted to OSS command (plain xargs -r codespell); kept only the
  base-ref parameterization required for a reusable workflow.
- link-check: restored the OSS upload-on-failure step and the if: failure() PR
  comment gate.

Necessary divergences retained: workflow_call conversion, base-ref/script-path
parameterization, bundled scripts, public-safe wording.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread .github/actions/codex-ci-triage/action.yml Outdated
Per guidance: keep fixes that address genuine findings, even where they diverge
from OSS. Restored:
- spellcheck: -z / xargs -0 so changed paths containing spaces aren't split.
- link-check: drop the dead *.log upload (check_links.py only reads files,
  never writes logs, so the upload is always empty — verified).

Left OSS-faithful (those findings were invalid): codex-ci-triage allow-users
duplication (needed), codex-agent owner/repositories token scope (Bugbot premise
wrong for workflow_call), link-check 'if: failure()' comment gate (false
positive — event_name reflects the caller).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread .github/actions/codex-ci-triage/action.yml Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

…te-key drop

Verified against openai/codex-action src/checkActorPermissions.ts:
- allow-users is split on ',', trimmed, lowercased, empty-filtered into a set; the
  actor is approved if the set contains it. So one comma-joined key is the
  supported form.
- The bare 'github-merge-queue' (schedule events) is NOT a [bot] actor, so it can
  only match via allow-users; 'github-merge-queue[bot]' (push/merge) matches via
  allow-bot-users. Both are required.

The OSS form declared allow-users twice (last-wins YAML), silently dropping the
bare 'github-merge-queue' — so scheduled merge-queue triage would fail the actor
gate. Combine into a single allow-users key (bare actor + caller-supplied users)
to actually allow both forms. Also SHA-pin openai/codex-action to match codex-run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

…code

- check_links.py: guard the cross-thread checked_urls cache with a threading.Lock
  (the ThreadPoolExecutor workers shared it unsynchronized). The shared
  requests.Session is only used for concurrent GETs after init, which is
  thread-safe, so it needs no lock.
- flaky_db.py: cmd_fetch now exits non-zero when a configured Redis errors,
  while keeping exit 0 for the intentional no-op cases (no URL / clean) so a
  caller can detect a real fetch failure instead of silently skipping nothing.

(The relative-anchor finding is handled separately — a correct fix needs
GitHub heading-slug matching whose edge cases could false-positive on valid
anchors, so it's pending a decision rather than rushed in.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread .github/workflows/spellcheck.yml
Comment thread .github/workflows/link-check.yml
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

kei-nan and others added 2 commits June 24, 2026 14:49
Previously _resolve_relative_path stripped the #fragment before checking, so
'other.md#bad-heading' passed as long as the file existed. Now the fragment is
preserved and, for .md/.markdown targets, validated against the target's anchors:
GitHub-style heading slugs (ATX + setext, with duplicate -N suffixes), explicit
{#custom-id}, and <a id/name=...>. Errs toward passing (skips line-number
anchors and unreadable files; only ever adds candidate anchors) so it fails only
on a genuinely-absent anchor. Verified with a 10-case self-test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both are reusable-workflow correctness fixes (these run under more triggers than
the single-trigger OSS originals):
- spellcheck: resolve the diff base from the merge-queue target
  (github.event.merge_group.base_ref) too, since github.base_ref is unset on
  merge_group events — mirroring the flaky-record-results base resolution.
- link-check: gate the failure comment on github.event.pull_request so non-PR
  callers don't hit a contextless issues.createComment that masks the real failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread .github/workflows/codex-agent.yml
Comment thread scripts/ci_common/check_links.py Outdated
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

- check_links.py: bare-URL regex (https?://\S+) swept up trailing prose
  punctuation (e.g. 'https://x.com).'), causing false broken-link reports. Trim
  a trailing set of punctuation, keeping a ')' that balances a '(' in the URL
  (wiki links). Verified with a small case set.
- Add .github/workflows/ci.yml: lints this repo on PRs/push — actionlint
  (workflow syntax/expressions/shellcheck), a strict-YAML duplicate-key check
  across workflows + composite actions (the class of bug that slipped through
  earlier), and compileall over the Python helpers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kei-nan kei-nan changed the title Seed shared RediSearch CI building blocks Seed redisearch-ci-common: shared Codex plumbing, CI utilities, flaky DB Jun 24, 2026
Comment thread scripts/ci_common/check_links.py
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Relative links resolved with Path.resolve() unbounded, so a (possibly
fork-authored) .md could reference paths outside the scanned repo — probed via
exists() and, since anchor validation was added, read via _anchor_in_markdown.
check_all_files now records the resolved scan root and _check_relative_link
rejects any relative target that resolves outside it ('Path escapes scan root')
before touching the filesystem. No false positives for whole-repo scans (our
usage). Verified with in-root/escape/absolute cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7180783. Configure here.

Comment thread scripts/ci_common/check_links.py
… pass)

Addresses the fenced-code finding and proactively fixes the same false-positive
class found while self-reviewing:
- extract_links now skips fenced code blocks (triple-backtick / ~~~), consistent
  with the anchor scanner, and strips inline code spans, so example/placeholder
  URLs shown as code aren't validated as real links.
- the [text](dest) regex now allows balanced single-level parens in the
  destination (e.g. wiki links Foo_(bar)) and drops an optional quoted title,
  instead of truncating at the first ')' or swallowing the title -- both common
  false-positive sources. Verified with a focused test suite.
- dropped a misleading 'self.root: Path = None' annotation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kei-nan
kei-nan merged commit 431bd35 into main Jun 24, 2026
2 of 3 checks passed
@jit-ci

jit-ci Bot commented Jun 24, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

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