feat: upstream drift tracker (issue mgmt, cron, SHA validator)#59
Conversation
…dator)
Bundled Phase 2 (rolling issue + weekly cron + failure tracking) and
Phase 3 (SHA consistency validator) in one PR so the version bump
covers a feature-complete drift tracker.
Phase 2 — issue management
- scripts/lib/upstream-drift.js: pure helpers
pickActiveIssue (defensive 0/1/N handling)
decideAction ({deltaCount, openIssue} → noop|close|create|update)
extractCommitsForBody (flattens compare API shape)
- scripts/upstream/check-upstream-drift.js: rewritten main flow
list open 🔄 Upstream Sync issues
decide action
execute via gh issue create|edit|close (execFileSync, no shell)
- .github/workflows/upstream-drift.yml
schedule: cron '0 21 * * 0' (Sun 21:00 UTC = Mon 06:00 KST)
permissions: contents: read + issues: write
if: failure() step that maintains a separate
"⚠ Upstream Sync Failure" rolling issue so the action's own
health is visible the same way drift is
- .github/labels.yml
🔄 Upstream Sync (green)
⚠ Upstream Sync Failure (red)
Sync to GitHub via scripts/setup-labels.sh.
- tests/lib/upstream-drift.test.js: +11 unit tests for the new pure
functions (30 total in this file).
Phase 3 — SHA consistency validator
- scripts/ci/validate-upstream-sync.js
Parses the "Last-synced upstream commit" SHA out of
upstream/README.md, compares with upstream/.upstream-sync.json,
exits 1 with a specific diff message on mismatch.
Paths are env-overridable (EGC_UPSTREAM_JSON_PATH /
EGC_UPSTREAM_README_PATH) so tests can point at fixtures.
- .github/workflows/reusable-validate.yml: wires the validator into
the existing 5-step validation chain (now 6).
- tests/ci/validate-upstream-sync.test.js: 9 tests
extractReadmeSha (happy, link wrapper, missing phrase, far-away
SHA), end-to-end via subprocess (match, mismatch, missing line,
malformed JSON, malformed SHA).
- tests/run-all.js: registers the new test file.
Docs
- upstream/{README,ko-KR/README,zh-CN/README}.md: updated to
present-tense for both the Action and the validator (was "will
add" / "planned" — now both have landed).
Local verification
- npm run lint clean
- npm test 261/261 pass (+19 since Phase 1)
- node scripts/ci/validate-upstream-sync.js → "OK — both files
reference 9db9867"
Out of scope (separate concern, larger context)
- Bumping actions/checkout@v4 + actions/setup-node@v4 to a Node 24
variant. The deprecation cutoff is 2026-09-16. Better as a
repo-wide refactor than a per-workflow change.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (12)
✨ 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 |
There was a problem hiding this comment.
2 issues found across 12 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/lib/upstream-drift.js">
<violation number="1" location="scripts/lib/upstream-drift.js:186">
P2: Fallbacking to `commit.author.name` populates `author` with non-login values, but the issue body always prefixes `@`, resulting in invalid/misleading pseudo-mentions like `(@Jane Doe)`.</violation>
</file>
<file name=".github/workflows/upstream-drift.yml">
<violation number="1" location=".github/workflows/upstream-drift.yml:52">
P2: The failure tracker updates only the first open issue and never cleans up additional open failure issues, so it can drift away from the intended single rolling issue behavior.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
P2 — extractCommitsForBody: drop raw-name fallback (cubic, line 186) When a commit's author has no GitHub login, the previous code fell back to `commit.author.name` (raw git author name). The issue body prefixes `@`, so that produced misleading pseudo-mentions like `(@jane Doe)`. Author is now populated ONLY from `c.author.login`; without it, the body skips the `(@...)` segment entirely. P2 — failure tracker: clean up extras (cubic, line 52) The `if: failure()` step looked at only the first open `⚠ Upstream Sync Failure` issue. If two ever ended up open (race, manual creation, etc.), the second would linger forever. The step now lists ALL open ones, keeps the first as the rolling tracker, edits it, and closes the rest with a "Superseded by #N" comment. Matches cubic's suggested diff. Tests: updated `extractCommitsForBody flattens the compare API shape` to assert the new behavior (commits with only a raw author name now yield `author === ''`). Lint clean. 261/261.
Summary
Bundles of the upstream-drift tracker plan from #58. log-only detection shipped already this PR brings the tracker to feature-complete.
🔄 Upstream Sync), weekly cron (Mon 06:00 KST = Sun 21:00 UTC), recursive failure tracking (⚠ Upstream Sync Failure), new labels in the manifestupstream/README.mdagrees withupstream/.upstream-sync.json; wired intoreusable-validate.ymlNet behaviour:
File-by-file
Library (pure, fully unit-tested)
scripts/lib/upstream-drift.js— addspickActiveIssue,decideAction,extractCommitsForBody.Entry script
scripts/upstream/check-upstream-drift.js— rewritten main flow. Lists open🔄 Upstream Syncissues, decidesnoop | close | create | update, executes viagh issue …(execFileSync, argv array — no shell).Workflow
.github/workflows/upstream-drift.ymlschedule: cron '0 21 * * 0'permissions: { contents: read, issues: write }if: failure()step that ensures a single⚠ Upstream Sync Failureissue points at the failing run URL.Labels
.github/labels.yml— adds🔄 Upstream Sync(green) and⚠ Upstream Sync Failure(red). Sync to GitHub withscripts/setup-labels.sh.Phase 3 validator
scripts/ci/validate-upstream-sync.js— env-overridable paths so tests can point at fixtures. Specific error message on mismatch (prints both SHAs side by side)..github/workflows/reusable-validate.yml— adds a sixth validation step.Tests (+19 new, 261 total)
tests/lib/upstream-drift.test.js— +11 tests for the new pure functions (action matrix, defensive multi-issue handling, compare-API flattening).tests/ci/validate-upstream-sync.test.js— 9 tests covering the pure function and end-to-end (match, mismatch, missing line, malformed JSON, malformed SHA).tests/run-all.js— registers the new test file.Docs
upstream/{README,ko-KR/README,zh-CN/README}.md— references to the Action and the validator switched from "planned / will add" to present tense (both have now landed).Test plan
npm run lint— cleannpm test— 261/261node scripts/ci/validate-upstream-sync.jsagainst the real repo state — passes ("OK — both files reference 9db9867")scripts/setup-labels.shso the new labels exist on GitHub before the cron fires🔄 Upstream Syncissue (delta is currently 1519+).upstream-sync.jsonon a throwaway branch fails CI viavalidate-upstream-syncOut of scope (separate concern)
actions/checkout@v4+actions/setup-node@v4to a Node 24 variant. Deprecation cutoff is 2026-09-16; better as a repo-wide refactor than a per-workflow change here.After this lands, the next step is the discussion-#1343 reply on the upstream ECC repo, with concrete links to the live workflow + tracker issue.