Add CI workflows and multi-session PR guard#33
Conversation
- .github/workflows/ci.yml: wait for corresponding pgxntool-test PR CI to pass before running tests; falls back to pgxntool-test/master after 5 minutes if no test PR exists (requires no-test-pr label override) - .github/workflows/protect-label.yml: enforce write-access-only on the no-test-pr label; handles non-collaborator 404, bot loop prevention, and org team membership edge cases - .claude/CLAUDE.md: warn before touching existing PRs not opened in this session (multiple concurrent Claude sessions are common) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
git subtree add refuses to work with shallow clones; fails with "shallow roots are not allowed to be updated" which looks like a remote/ref problem rather than a depth issue. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- gem install asciidoctor instead of apt ruby-asciidoctor (same fix as pgxntool-test) - Print '=== BRANCHES: ===' line at the start of each test job so both the pgxntool and pgxntool-test refs are visible in CI logs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub Actions workflows are development infrastructure and should not be included in PGXN distribution packages. Without this exclusion, `make dist` (which uses `git archive`) includes .github/workflows/, causing the dist test to fail: not ok 22 distribution contains exact expected files # ERROR: Distribution contents differ from expected manifest # > pgxntool/.github/ # > pgxntool/.github/workflows/ # > pgxntool/.github/workflows/ci.yml # > pgxntool/.github/workflows/protect-label.yml The .gitattributes `export-ignore` attribute controls what `git archive` excludes. Adding `.github/ export-ignore` ensures CI workflow files are stripped from distributions, matching the existing treatment of .claude/, .gitattributes, and documentation files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Key changes: 1. Replace 5-minute polling 'resolve-test-ref' job with a fast 'check-test-pr' job (seconds, not minutes). The test PR must exist when you push — no waiting. 2. When a paired pgxntool-test PR is found, pgxntool CI passes immediately without running tests. Tests run in the test PR's own CI — no duplication. 3. When no paired test PR exists and no override label is present, CI fails immediately with an actionable error message pointing to the README docs. 4. Rename 'no-test-pr' label to 'commit-with-no-tests'. This name better conveys that it's a merge-time decision (not just a CI skip), and that it's unusual and maintainer-only. 5. Add 'Pre-install pgtap' step to the test job (only runs in the commit-with-no-tests case). Prevents a concurrent-install race condition in concurrent-make-test.bats. 6. Update protect-label.yml to guard the new label name. The failure message now links to README#ci-and-contributing which explains branch naming requirements and how to request the label. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a paired pgxntool-test PR is found, verify: 1. CI has run for the exact current HEAD SHA (no stale runs from old commits) 2. All check runs completed successfully 3. The most recent passing run is within 7 days Each failure case provides URLs for both the test PR and the pgxntool re-run check, making it clear what to fix and how to re-trigger. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…est-PR conflict - Fork matching: require test PR to come from the same owner as the pgxntool PR; never fall back to a random contributor's fork - Race condition: poll (30s intervals, 20min max) instead of immediately failing when the paired test PR's CI hasn't started or is still running - Label conflict: fail if commit-with-no-tests label is set but a paired test PR also exists — that combination is contradictory - Label name: define as NO_TEST_LABEL const in ci.yml and LABEL const in protect-label.yml; replace all literals with those consts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eck; add sync warning - Multiple matching test PRs from same owner: error+fail rather than warning (if we can't tell which one to use, that's a hard error) - Remove the 7-day recency check: since we already validate the exact SHA, forcing a re-run of test CI just to satisfy a time window adds friction (e.g. manual re-runs of pgxntool CI shouldn't require re-running test CI) - Add big-fat WARNING comment on the duplicated test job directing maintainers to keep it in sync with pgxntool-test/ci.yml; includes TODO for reusable workflow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the 88-line duplicated test job (with its WARNING comment) with a 7-line call to Postgres-Extensions/pgxntool-test/.github/workflows/run-tests.yml. Single source of truth; no more risk of the two copies drifting apart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub Actions does not support ${{ }} expressions in the uses: field.
The test job only runs in the commit-with-no-tests path, which always
sets test-ref=master, so @master is always correct here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
run-tests.yml doesn't exist on pgxntool-test/master yet (it's on add-ci). GitHub validates uses: references upfront even for skipped jobs, so the entire workflow fails if the file isn't found. Use @add-ci while developing; change to @master when pgxntool-test/add-ci merges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@coderabbitai please review |
🧩 Analysis chain🏁 Script executed: Length of output: 23205
|
| Severity | Issue |
|---|---|
| 🔴 Critical | Label name mismatch: PR description says no-test-pr, code uses commit-with-no-tests |
| 🔴 Critical | @add-ci hardcoded ref is a post-merge time bomb |
| 🔴 Critical | test-ref output computed but never consumed in test job |
| 🟡 High | Setup instructions reference non-existent check name resolve-test-ref |
| 🟡 High | Inaccurate comment in test job |
| 🟡 Medium | per_page: 100 can silently miss PRs |
| 🟢 Nit | pgxntool-ref vs pgxntool-branch worth documenting |
| 🟢 Nit | stale conclusion value not handled in check-run filter |
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
|
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:
📝 WalkthroughWalkthroughThis PR adds coordinated CI controls: label protection for Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SourcePR as pgxntool PR
participant CI as ci.yml
participant TestRepo as pgxntool-test
participant Checks as GitHub Checks
CI->>TestRepo: list open PRs matching branch and fork owner
alt exactly one paired PR
CI->>Checks: poll paired head SHA check runs
Checks-->>CI: return completed conclusions
else no paired PR
CI->>SourcePR: re-fetch labels
alt commit-with-no-tests is present
CI->>TestRepo: invoke tests against master
else
CI-->>SourcePR: report missing paired test PR or label
end
end
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Document the cross-repo reusable workflow tradeoffs, the @add-ci→@master transition requirement, and merge order constraints. Expand the comment on the uses: line to make the temporary nature explicit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/ci.yml:
- Around line 41-47: The early return for branch === 'master' should only apply
when the PR's head is from this repository (not a fork); update the logic that
uses branch to also check the pull request head repo identity (e.g., compare
pull_request.head.repo.full_name or head.repo.name against the current
repository) before calling core.setOutput('run_tests','true') and
core.setOutput('test_ref','master'); ensure forked PRs with head repo different
from this repo skip this shortcut so the paired pgxntool-test requirement still
applies.
- Line 25: The workflow uses mutable refs—update both occurrences (the
`actions/github-script@v7` usage and the reusable workflow call
`run-tests.yml@add-ci`) to immutable commit SHAs or a stable branch tag; locate
the `uses: actions/github-script@v7` line and replace the ref with the
corresponding commit SHA for v7 (or a stable branch/tag), and locate the
reusable workflow reference `run-tests.yml@add-ci` and replace `add-ci` with
either the merge target stable ref (e.g., `@master` or a release tag) or the
commit SHA of that branch so the workflow won't break when the feature branch is
deleted.
- Around line 61-66: The current github.rest.pulls.list call (the pulls.list
invocation that assigns const { data: prs }) only fetches up to 100 PRs and can
miss matches; update the logic to either paginate through all pages (use
page/per_page in a loop or Octokit pagination helpers to aggregate all PRs) or
narrow the server-side query by using the head filter format
`${prOwner}:${branch}` in the pulls.list parameters to return only PRs from that
head; ensure you update the code that reads `prs` to handle an array aggregated
from multiple pages if you choose pagination.
In @.github/workflows/protect-label.yml:
- Line 33: Replace the mutable tag on the GitHub Action with an immutable commit
SHA: change the uses line that currently reads `uses: actions/github-script@v7`
to `uses: actions/github-script@<full-commit-sha>` (a full 40-character commit
SHA from the actions/github-script repo) so the workflow always runs the exact
commit; ensure you paste the full SHA for the commit you want to pin.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: f2df7230-456b-4373-b6f7-2cb9cfbc8e02
📒 Files selected for processing (4)
.claude/CLAUDE.md.gitattributes.github/workflows/ci.yml.github/workflows/protect-label.yml
There was a problem hiding this comment.
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/ci.yml:
- Around line 3-10: Add a top-level GitHub Actions concurrency block to the
workflow to cancel overlapping runs for the same PR: add a concurrency key at
the root of the YAML with a group that uniquely identifies the PR (e.g. group:
"check-test-pr-${{ github.event.pull_request.number }}" or "ci-${{ github.ref
}}") and set cancel-in-progress: true so rapid pushes cancel prior
`check-test-pr` polling jobs; update the workflow root (where `on:
pull_request:` is defined) rather than per-step and ensure the concurrency group
name matches the `check-test-pr` job scope.
- Around line 1-17: Add an explicit top-level permissions block to the workflow
to restrict GITHUB_TOKEN to least privilege: declare permissions: pull-requests:
read and checks: read (instead of relying on repository defaults or read-all).
Edit the YAML at the top-level of the CI workflow (the existing "name: CI"
workflow) and insert a permissions mapping so only the pull-requests and checks
scopes are granted to the GITHUB_TOKEN.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4e49725f-3307-4315-8aa3-546a91108bef
📒 Files selected for processing (2)
.github/workflows/CLAUDE.md.github/workflows/ci.yml
|
@coderabbitai is there a way to configure you to post individual review comments using Github's Review Changes feature? |
|
Tip For best results, initiate chat on the files or code changes.
Automatic reviews (triggered when new commits are pushed to the PR) — inline review comments appear on specific lines of code where CodeRabbit identifies potential issues, improvements, or suggestions. Each comment includes a description of the issue, an explanation of why it matters, and often a suggested code fix. These are posted using GitHub's formal "Review Changes" mechanism, so they appear as grouped inline comments on the diff. Command-triggered reviews (like Currently, there is no configuration option to force command-triggered reviews to use GitHub's inline "Review Changes" format instead of a consolidated comment. The closest you can get to the inline experience is to:
If you'd like to see this as a feature (command-triggered reviews using GitHub's formal review format with inline comments), I'd suggest opening a feature request on the CodeRabbit feedback/support channels. |
- Add explicit permissions block (pull-requests: read, checks: read)
for least-privilege GITHUB_TOKEN access.
- Add concurrency block to cancel stale polling jobs on re-push.
Without this, rapid pushes stack up redundant 20-min polling runs.
- Warn (via core.warning annotation) when a fork PR's branch is named
'master'. Almost certainly a contributor mistake; we don't block it
but make it visible. Can't post a PR comment here — pull_request
trigger gives a read-only token for fork PRs.
- Paginate pulls.list with github.paginate() instead of a bare
per_page:100 call. Handles >100 open PRs correctly.
- Paginate checks.listForRef similarly; uses a map fn since that
endpoint wraps results in {check_runs:[]} rather than a plain array.
- Collapse redundant pgxntool-ref + pgxntool-branch inputs into just
pgxntool-branch. They were always the same value in every caller;
the distinction (ref could be SHA) was forward-looking but unused.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
github.paginate() + a map function on listForRef (which returns
{check_runs:[], total_count:N} rather than a plain array) produces
undefined elements in the result, crashing the filter step.
A single commit will not have 100+ CI check runs, so per_page:100
is correct and safe without pagination. A comment explains why we
don't use paginate() here (unlike pulls.list above, which does).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
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/ci.yml:
- Around line 264-283: The top-level GitHub Actions permissions are too
restrictive for the reusable workflow run-tests.yml which invokes
actions/checkout@v4; update the workflow-level permissions block to include
contents: read (or alternatively move narrow scopes to the check-test-pr job and
give the test job broader scopes) so that the test job (uses:
Postgres-Extensions/pgxntool-test/.github/workflows/run-tests.yml@add-ci) can
successfully run actions/checkout; ensure permissions includes contents: read
for the caller or grant the test job the required scopes.
- Around line 254-256: Update the CI failure guidance string that currently
reads "To resolve:\n 1. Open a PR in pgxntool-test from a branch ALSO named
'${branch}'..." to also require the same fork/owner as the head of the current
PR; explicitly state that the PR must be opened from the same repository owner
(head) as this PR in pgxntool-test so branch-name matching alone won't be
accepted. Locate and modify the template string containing `To resolve:\n 1.
Open a PR in pgxntool-test from a branch ALSO named '${branch}'` and append a
clear sentence like "The PR must be created from the same fork/owner (head) as
this PR" to ensure both branch name and owner requirements are communicated.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2bafd4ce-83a4-4ddd-81e0-a2458b985a2f
📒 Files selected for processing (1)
.github/workflows/ci.yml
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/ci.yml:
- Around line 42-57: The current gate only checks the head branch variable
(branch / context.payload.pull_request.head.ref) and treats any PR with head
'master' as a master-to-master bypass; change this to require both head and base
be 'master' by reading context.payload.pull_request.base.ref into a variable
(e.g., base) and update the if condition from if (branch === 'master') to if
(branch === 'master' && base === 'master') so the NO_TEST_LABEL / paired-test
logic only applies to true master-to-master PRs.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 29652f65-b886-4b82-abdf-7935a00375a9
📒 Files selected for processing (1)
.github/workflows/ci.yml
- Add `contents: read` so the reusable test workflow's checkout has access - Pin actions/github-script to an immutable SHA (ci.yml and protect-label.yml) - Gate the master shortcut on the base branch too (master-to-master only) - Note the same-owner pairing requirement in the failure guidance Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pgxntool-test/CLAUDE.md already mandates monitoring CI after each push via the /ci skill; add the same requirement here, noting the monitor script lives in the pgxntool-test checkout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)
292-292: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winPass the computed test ref to the reusable workflow.
check-test-prpublishestest-ref, but this job hard-codesmaster. Current successful test paths happen to usemaster, but passing the output preserves the cross-job contract and prevents future non-master refs from being ignored.Proposed fix
- pgxntool-test-ref: master + pgxntool-test-ref: ${{ needs.check-test-pr.outputs.test-ref }}🤖 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/ci.yml at line 292, Update the pgxntool test job’s ref input from the hard-coded master value to the test-ref output published by check-test-pr, preserving the existing cross-job output contract and allowing non-master refs to propagate.
🤖 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.
Outside diff comments:
In @.github/workflows/ci.yml:
- Line 292: Update the pgxntool test job’s ref input from the hard-coded master
value to the test-ref output published by check-test-pr, preserving the existing
cross-job output contract and allowing non-master refs to propagate.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fcb6fd08-fa3a-4afe-a391-f060337d05d7
📒 Files selected for processing (3)
.github/workflows/ci.yml.github/workflows/protect-label.ymlCLAUDE.md
#33 merged with the ref still at @add-ci (the flip landed after the merge). pgxntool-test's run-tests.yml is now on master (#22), so point the cross-repo reusable-workflow ref at @master — the production ref. Left at @add-ci it would break once the add-ci branch is deleted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements the cross-repo CI design from pgxntool-test#15.
What's added
.github/workflows/ci.yml— main CI workflow:no-test-prlabel is set by a maintainer.github/workflows/protect-label.yml— label protection:pull_request_targetso it has write access from fork PRsno-test-prif added by a non-writer; re-adds it if removed by a non-writer.claude/CLAUDE.md— asks for confirmation before touching any existing PR not opened in this session (multiple concurrent Claude sessions are common across these repos)Setup required after merge
no-test-prlabel in this repo (Settings → Labels)resolve-test-refas a required status check on themasterbranch protection rulePairs with: Postgres-Extensions/pgxntool-test#20
🤖 Generated with Claude Code