Skip to content

feat: upstream drift tracker (issue mgmt, cron, SHA validator)#59

Merged
Jamkris merged 2 commits into
mainfrom
feat/upstream-drift-phase-2-3
May 12, 2026
Merged

feat: upstream drift tracker (issue mgmt, cron, SHA validator)#59
Jamkris merged 2 commits into
mainfrom
feat/upstream-drift-phase-2-3

Conversation

@Jamkris
Copy link
Copy Markdown
Owner

@Jamkris Jamkris commented May 12, 2026

Summary

Bundles of the upstream-drift tracker plan from #58. log-only detection shipped already this PR brings the tracker to feature-complete.

Phase Adds
2 Rolling tracking issue (🔄 Upstream Sync), weekly cron (Mon 06:00 KST = Sun 21:00 UTC), recursive failure tracking (⚠ Upstream Sync Failure), new labels in the manifest
3 CI validator asserting that the SHA in upstream/README.md agrees with upstream/.upstream-sync.json; wired into reusable-validate.yml

Net behaviour:

  • Drift becomes a number on an open issue, refreshed weekly.
  • When the maintainer advances the baseline SHA, the tracker closes the issue automatically on the next run.
  • If the workflow itself errors, a separate rolling issue surfaces that fact (same trick recursively applied).
  • A SHA typo in either file fails CI on PR review.

File-by-file

Library (pure, fully unit-tested)

  • scripts/lib/upstream-drift.js — adds pickActiveIssue, decideAction, extractCommitsForBody.

Entry script

  • scripts/upstream/check-upstream-drift.js — rewritten main flow. Lists open 🔄 Upstream Sync issues, decides noop | close | create | update, executes via gh issue … (execFileSync, argv array — no shell).

Workflow

  • .github/workflows/upstream-drift.yml
    • schedule: cron '0 21 * * 0'
    • permissions: { contents: read, issues: write }
    • if: failure() step that ensures a single ⚠ Upstream Sync Failure issue points at the failing run URL.

Labels

  • .github/labels.yml — adds 🔄 Upstream Sync (green) and ⚠ Upstream Sync Failure (red). Sync to GitHub with scripts/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 — clean
  • npm test — 261/261
  • node scripts/ci/validate-upstream-sync.js against the real repo state — passes ("OK — both files reference 9db9867")
  • Module loads cleanly: all expected exports present on the entry script
  • Post-merge: run scripts/setup-labels.sh so the new labels exist on GitHub before the cron fires
  • Post-merge: manually dispatch the workflow once to confirm it creates exactly one 🔄 Upstream Sync issue (delta is currently 1519+)
  • Post-merge: verify a forced bad-SHA in .upstream-sync.json on a throwaway branch fails CI via validate-upstream-sync

Out of scope (separate concern)

  • Bumping actions/checkout@v4 + actions/setup-node@v4 to 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.

…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.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Warning

Rate limit exceeded

@Jamkris has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 7 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 94f76de3-c801-460a-bad0-f2490e5625af

📥 Commits

Reviewing files that changed from the base of the PR and between 724341e and 2f451e0.

📒 Files selected for processing (12)
  • .github/labels.yml
  • .github/workflows/reusable-validate.yml
  • .github/workflows/upstream-drift.yml
  • scripts/ci/validate-upstream-sync.js
  • scripts/lib/upstream-drift.js
  • scripts/upstream/check-upstream-drift.js
  • tests/ci/validate-upstream-sync.test.js
  • tests/lib/upstream-drift.test.js
  • tests/run-all.js
  • upstream/README.md
  • upstream/ko-KR/README.md
  • upstream/zh-CN/README.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/upstream-drift-phase-2-3

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jamkris Jamkris changed the title feat: upstream drift tracker Phases 2 + 3 (issue mgmt, cron, SHA validator) feat: upstream drift tracker (issue mgmt, cron, SHA validator) May 12, 2026
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment thread scripts/lib/upstream-drift.js Outdated
Comment thread .github/workflows/upstream-drift.yml Outdated
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.
@Jamkris Jamkris merged commit d258707 into main May 12, 2026
10 checks passed
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