Repository navigation
fix: repair red main, and ship nothing main's CI has not passed - #3448
Conversation
Tested 1 flow, found no issues. What we tested
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
CI evidence and version-bump verdict scripts/require_green_ci.py |
The script checks for a successful matching CI run on a main push. For pending or missing CI, it permits a qualifying single-parent version bump only when the parent’s CI succeeded. |
CLI and API handling scripts/require_green_ci.py |
The CLI validates its ref, reports the verdict, and returns an exit code. GitHub API requests retry server errors and network failures up to three times. |
Release-path gating and tests .github/workflows/build-binaries.yml, .github/workflows/docker-publish.yml, .github/workflows/publish.yml, scripts/release.sh, codebase_rag/tests/test_require_green_ci.py |
The release workflows and release script run the gate before shipping steps. Tests cover verdicts, version-bump qualification, CLI results, and workflow wiring. |
SQL DDL source scanning
| Layer / File(s) | Summary |
|---|---|
Source retention and DDL scanning codebase_rag/parsers/definition_processor.py, codebase_rag/graph_updater.py, codebase_rag/parsers/factory.py, codebase_rag/parsers/call_processor.py, codebase_rag/tests/test_sql_ddl_routine_references.py |
SQL processing retains source bytes when parsed text differs from the source slice. DDL scanning uses the retained bytes when available and falls back to the parsed root text otherwise. Tests cover edits between parsing and scanning, leading whitespace and comments, and cache eviction. |
Priority:
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant ReleaseWorkflow
participant require_green_ci.py
participant GitHubAPI
participant PublishJobs
ReleaseWorkflow->>require_green_ci.py: pass tag or commit SHA
require_green_ci.py->>GitHubAPI: resolve commit and query matching CI runs
GitHubAPI-->>require_green_ci.py: return commit, run status, and changed-file data
require_green_ci.py-->>ReleaseWorkflow: return gate verdict
ReleaseWorkflow->>PublishJobs: run jobs after gate success
Possibly related PRs
- vitali87/code-graph-rag#3439: Changes the SQL source used for DDL routine references, which is also changed here.
- vitali87/code-graph-rag#3447: Changes the same SQL DDL source helper and covers related fallback cases.
- vitali87/code-graph-rag#3254: Adds SQL statement blanking and a lost-function warning in code paths changed here.
Suggested labels: bug
Suggested reviewers: claude
Merge Risk: 
Minimal · up to 993c0
-
No actionable issue is established; the change is mergeable after normal checks.
Pre-merge checks: 
4
Finishing Touches
-
📝 Generate docstrings
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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 @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98c2989c89
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
[High impact] The PR appears safe to merge; no new blocking issues were found. SummaryThe PR restores SQL routine references and adds CI checks before publishing releases.
Reviews (3) · Last reviewed commit: "fix(sql): scan the whole file a recovere..." · Reviewed by Greptile |
… re-parse main has been red since #3251 merged on top of #3254: 12 tests in test_sql_ddl_routine_references.py fail on every unit-test shard 1/2 and in the SonarCloud job's copy of the suite. #3254 re-parses a SQL file from a copy in which each statement the grammar cannot read on its own is blanked, and the returned tree's text is that copy. #3251 scans `root_node.text` for the routines DDL names, and the statements it reads (CREATE AGGREGATE, CAST, OPERATOR, EVENT TRIGGER, FOREIGN DATA WRAPPER) are exactly the ones the copy blanks, so their edges vanished. Each PR was green against its own base; #3251 was never re-tested after #3254 landed two minutes earlier. The scan now reads the file as the grammar read it (grammar_bytes over the file's bytes). The copy keeps every offset, so the sites still line up with the tree. The tree's text remains the fallback when the file is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
version-bump.yml checks CI before the tag it pushes, but that was the only check. publish.yml (PyPI), docker-publish.yml (GHCR) and the release uploads in build-binaries.yml also run on a tag pushed by hand, a release created by hand and a dispatch, with no CI check at all, and so does `make release`. v0.3.10 and v0.3.11 tag today's red main: creating a release on either would have shipped it. scripts/require_green_ci.py now runs in each of them against the exact commit it builds, and fails closed. A commit passes when CI's push run on main concluded success. A version bump whose own run has not concluded passes on its parent's run, because version-bump.yml ships the bump before CI on it can finish; the bump may change only code-graph-rag's version lines in pyproject.toml, uv.lock and server.json. publish.yml checks out the SHA the gate passed in every later job, so a tag moved mid-run cannot swap the commit. A test fails when any workflow using a publishing action does not run the gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
…s output CodeQL reports a checkout whose ref comes from another job's output as untrusted code run in a privileged workflow (cache poisoning, high), and flagged rust-wheels' `ref: needs.ci-gate.outputs.sha`. Every job checks out the tag again, as before this branch; the gate still has to pass first. A tag moved mid-run is the tag ruleset's to stop. The script no longer writes the SHA it checked, which nothing reads now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
…urce The call pass re-read the SQL file for its DDL, so an edit landing after the parse (a sync racing the editor, or before an evicted tree is reloaded from disk) put the new text's routine names at the old tree's offsets. `is_parsed_from` checks the file against the tree in hand: the statement-isolated copy keeps the length, every newline and every byte it does not blank, hollow or turn into a placeholder, so any other difference means the file changed, and the call pass then reads the tree's own text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
4dcdab3 to
491b1e3
Compare
version-bump.yml commits NEWS.md and the README re-rendered from it with the version whenever a release has highlights, and an empty bump when the version was set by hand. The gate admitted only version lines, so it would refuse every such release while the bump's own CI was still running, and the tag-triggered uploads do not retry. Both docs now pass on the parent's run; neither is built into anything that ships (the package readme is PYPI_README.md). A test keeps the admitted files in step with the files version-bump.yml adds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
There was a problem hiding this comment.
🔇 Additional comments: 1
codebase_rag/parsers/sql_recovery.py-165-167: 1
165-167:Major · Data Integrity & Integration · Quick win
⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.Compare against the original source bytes before reading current DDL.
If recovery blanked a statement, a same-length edit anywhere in that statement can pass
is_parsed_from: each parsed space accepts any source byte except newline. For example, changing only_WIRING’sSFUNC = first_sfunc,toSFUNC = first_fin ,can makeCallProcessor._sql_source_as_writtenscan the edited DDL against the old tree and emit an incorrect routine edge. The same check also accepts edits to an underscore in an otherwise unchanged tree. Retain the original grammar bytes from parsing and compare them exactly with the current file before using it. The same-length test incodebase_rag/tests/test_sql_ddl_routine_references.pyalso changesCREATE TABLE, so it does not isolate an edit within the blanked statement. As per path instructions: “Only comment on critical, major, or high-severity issues: logic errors, security vulnerabilities, race conditions, data loss or corruption, and breaking API changes.”Source: Path instructions

Review info
-
Run configuration-
- Source mode: Auto
- Repository: vitali87/code-graph-rag
- Branch: claude/stoic-pascal-oeon7h
- File: .coderabbit.yaml
- Commit: 491b1e3
- Layers: Repository YAML
- Review profile: QUIET
- Plan: Advanced
- Run ID:
5fe895ae-7282-4a6c-997a-28e5642f0aa1
Files selected for processing: 7-
.github/workflows/publish.ymlcodebase_rag/parsers/call_processor.pycodebase_rag/parsers/sql_recovery.pycodebase_rag/tests/test_require_green_ci.pycodebase_rag/tests/test_sql_ddl_routine_references.pycodebase_rag/tests/test_sql_statement_isolation.pyscripts/require_green_ci.py
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 5 remain after this review.
-
The call pass re-read the file and accepted it when it matched the statement-isolated copy outside the blanked text. That let a same-length edit inside a blanked statement through, and any edit to a real `_`, and it compared the whole file with the root's text, which starts after a leading blank line or comment, so such a file lost its DDL edges again. The definition processor now keeps the bytes each SQL tree was parsed from when its text is the isolated copy, and an evicted tree's reload from disk replaces them, so they always belong to the tree the call pass walks. The call pass cuts the root's span from them and reads no file. A SQL file is read once, before its parse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
|
@coderabbitai Your
Each fails without its fix. Generated by Claude Code |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain
The three regression cases cover same-length edits in blanked statements, leading whitespace and comments, and edited-file reloads. I inspected the test assertions but did not run the tests.
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! You are interacting with an AI system. |
The read-once and keep-the-parsed-bytes branches raised process_file's cognitive complexity from 14 to 17, past SonarCloud's 15 (python:S3776), which fails the Sonar Zero Issues Gate. They move into _read_sql_once and _settle_sql_file, and process_file is back at 14. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
|
@greptile review |
When recovery blanks a statement that opens or closes the file, such as an EVENT TRIGGER whose ERROR swallowed the function after it, that statement lies outside the recovered root's span. The call pass cut the saved bytes to that span, and keep_sql_source compared only inside it and dropped the bytes, so the trigger's routine got no edge and looked dead. The bytes are now kept whenever anything but whitespace lies outside the root, and the scan reads them whole from the file's origin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
|
|
@greptile review |
main now carries its own fix for the DDL scan reading the statement-isolated re-parse (#3448: _sql_source_as_written reads the bytes the tree was parsed from), which supersedes the copy this branch ported in to get CI green (_sql_source_text). call_processor.py and test_sql_ddl_routine_references.py take main's version, so they leave this PR's diff. The frozen-clock fix for test_seconds_left_follows_the_running_deadline is not on main and stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q1Edv3KWZrD3dN9qUQGD3u
Main's #3448 fixes the SQL DDL scan by keeping the parsed source bytes, superseding the port of #3447 carried here; both SQL files take main's version, so this branch no longer changes them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CHdvTdmrf7eEpdgLCmvRR
Brings in the repair of red main (#3448). The one conflict, the seconds-left deadline test, takes main's frozen-clock version, which replaces this branch's rounding tolerance for the same Windows flake. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
Brings in the repair of red main (#3448) through the updated pr-4 base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
Brings in the repair of red main (#3448) through the updated pr-5 base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
Brings in the repair of red main (#3448) through the updated pr-6 base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
Brings in the repair of red main (#3448) through the updated pr-7 base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
Brings in the repair of red main (#3448) through the updated pr-8 base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVdycfDFvbqaoyHWVWHJ1N
call_processor.py and test_sql_ddl_routine_references.py: took main's. Main's own fix for the DDL scan of a recovered SQL parse (_sql_source_as_written, #3448) supersedes the stopgap this branch had cherry-picked (_sql_source_text), so the branch no longer touches either file.



Summary
root_node.text, so the CREATE AGGREGATE / CAST / OPERATOR / EVENT TRIGGER / FDW clauses it looks for were gone. 12 tests intest_sql_ddl_routine_references.pyfailed on every unit shard 1/2 and in SonarCloud's copy of the suite.sql_sources), and_load_ast_from_diskreplaces them when it reloads an evicted tree. The bytes always belong to the tree the call pass walks.version-bump.ymlchecked CI, before the tag it pushes.publish.yml(PyPI),docker-publish.yml(GHCR) and the release uploads inbuild-binaries.ymlalso run on a hand-pushed tag, a hand-created release and a dispatch, with no check.make releasehad none either.v0.3.10andv0.3.11tag today's red main, so a release created on either would have shipped it. Newscripts/require_green_ci.pyruns in each of them against the commit being shipped, and fails closed:success;version-bump.ymlcommits: code-graph-rag's version lines inpyproject.toml,uv.lockandserver.json, the release'sNEWS.mdandREADME.md, or nothing at all (a hand-set version);publish.ymlwaits for it.Demo
No user-visible change: the SQL commits restore DDL edges the tests already assert, and the release commits change release workflows only.
Type of Change
Related Issues
Related to #3251 and #3254 (their combination turned main red). #3447 fixes the same SQL breakage with a file re-read; only one of the two SQL fixes should land.
Test Plan
Unit tests pass: full
pytest -n auto -m "not integration"locally on the final head gives 23,576 passed. 4 tests failed only because this machine has Go 1.24.7 (CI installs >=1.27.2) and no .NET SDK; all 4 are green in CI.New tests added
Integration tests pass (
make test-integration, requires Docker)Manual testing (describe below)
SQL fix: the 12 failures reproduced on main exactly as CI shows them, and are green with the fix. New tests, each mutation-checked (each fails when its guard is removed):
test_ddl_edited_after_the_parse_is_not_read_against_the_old_tree, which editswiring.sqlbetween the passes three ways: shorter, same length, and same length inside a blanked statement only;test_an_evicted_tree_reloaded_from_an_edited_file_reads_the_reload, with a one-entry AST cache;test_ddl_after_a_leading_blank_line_and_comment_references_its_routine.Release gate:
test_require_green_ci.py, 44 tests:v0.3.11bump patch as the fixture. Today'sv0.3.11is refused; a fresh bump of a green commit passes, with or without its news, and so does an empty bump; a dependency version line inuv.lockis not a bump; foreign runs (another workflow, branch, event or fork) are not evidence; an incomplete reply refuses.git addline inversion-bump.yml; everypublish.ymljob needs the gate and checks out the release tag, never a job output (CodeQL reads that as cache poisoning); Docker gates before pushing; binaries need it on tags;release.shasks beforetwine upload.uv.lockname check disabled, own-run failure ignored, apublish.ymlcheckout ref changed, news files refused, the empty bump refused.ruff, ruff format, ty, check-yaml clean.
Settings this cannot cover (repository/PyPI settings, owner's call):
pypienvironment tov*tags, and add av*tag ruleset.Checklist
!in the title and its release notes inchanges/breaking/<PR number>.md(see Breaking changes)make pre-commit): ruff, ruff format, ty, check-yaml run on the changed files# type: ignore,cast(),Any, orobjecttype hints: the gate script and its test type GitHub's JSON replies asAnyand checkobjectvalues withisinstance🤖 Generated with Claude Code
https://claude.ai/code/session_01Y4AFQuVg5X5cRio73QgHXV
Summary by CodeRabbit
Release Reliability
Bug Fixes