Skip to content

ci: add regression guards (workspace typecheck + package.json dup-key lint + branch protection docs)#24

Merged
theosera merged 1 commit intomainfrom
claude/ci-regression-guards
Apr 21, 2026
Merged

ci: add regression guards (workspace typecheck + package.json dup-key lint + branch protection docs)#24
theosera merged 1 commit intomainfrom
claude/ci-regression-guards

Conversation

@theosera
Copy link
Copy Markdown
Owner

@theosera theosera commented Apr 21, 2026

Preventive measures for the regression class that enabled PR #22's unresolvable conflicts (see PR #23 post-mortem). Three tightenings of the CI gate + one documentation deliverable.

1. Workspace-wide typecheck in CI

Root typecheck script is now tsc --noEmit && pnpm --filter @obsidian-ai-pipeline/core build && pnpm -r typecheck, and the CI TypeScript type check step calls pnpm typecheck instead of root-only pnpm exec tsc --noEmit.

Why: the old CI only typechecked root files. packages/core/src/config/env.ts had loadDotEnv defined twice and readPort / safeFileSegment / safeAnalysisFileName helpers were never wired to their call sites — all of which TypeScript would have flagged, but -r typecheck was never run in CI. The duplicate-function-implementation error in core also masked the exactOptionalPropertyTypes violations in apps/sync/src/sync.ts, compounding the hidden breakage.

2. package.json duplicate-key lint (.github/scripts/check-package-json-duplicates.py)

New CI step Lint package.json files for duplicate keys, runs before install for fail-fast behavior. The linter uses Python's json.load(object_pairs_hook=...) to reject duplicates at any nesting level — JSON.parse and default json.load silently accept them with last-wins semantics.

Why: main ended up with "private": true written twice in root package.json during merge history. Neither node nor pnpm complains about that; it only surfaced when I had to hand-merge. Annotations use GitHub's ::error file=...:: format so PR UI highlights the offending file inline.

Tested locally against a synthetic duplicate — linter exits 1 and emits ::error file=package.json::duplicate key 'private'.

3. Branch protection docs (docs/branch-protection.md)

Can't be expressed in repo code. Documents the required Web UI / gh api settings — critically required_status_checks.strict=true ("Require branches to be up to date before merging"), which would have forced PR #22 to rebase onto current main before becoming mergeable and prevented the whole "old base + corrupted main = unresolvable 3-way merge" scenario.

Includes a ready-to-run gh api PUT /repos/.../branches/main/protection invocation for the complete recommended ruleset.

Verified locally (simulated CI order)

=== #1 package.json lint ===             6/6 OK
=== #2 pnpm install --frozen-lockfile === clean
=== #3 pnpm rebuild better-sqlite3 ===    done
=== #4 pnpm test ===                      120 passed, 0 failed
=== #5 pnpm typecheck (full) ===          root + 3 workspace packages clean

Also verified the duplicate-key linter correctly fails (exit 1 + ::error:: annotation) on a synthetic package.json with duplicate "private" keys.

Test plan

  • CI pipeline job: package.json lint step passes on current tree
  • CI pipeline job: pnpm typecheck step passes (was just root tsc)
  • CI chrome-extension job: still green (unchanged)
  • Maintainer: apply docs/branch-protection.md settings on GitHub after merge

Summary by CodeRabbit

Release Notes

  • Chores

    • Added automated duplicate key validation for all package.json files in the CI pipeline
    • Enhanced TypeScript type-checking workflow to include explicit root-level compilation verification
  • Documentation

    • Added comprehensive guide on GitHub branch protection configuration, including recommended settings and API examples for the main branch

Three preventive measures for the bug class that let main accumulate
a duplicate loadDotEnv / duplicate "private" key / unused helper wiring
across multiple merges without CI noticing:

1. CI typecheck now runs workspace-wide
   - Root script `typecheck` expanded to
     `tsc --noEmit && pnpm --filter @obsidian-ai-pipeline/core build && pnpm -r typecheck`
   - CI step calls `pnpm typecheck` instead of root-only `tsc --noEmit`.
   - Catches Duplicate-function-implementation and unused-helper errors
     in packages/core and apps/* that the old CI missed.

2. package.json duplicate-key lint
   - .github/scripts/check-package-json-duplicates.py uses Python's
     json.load(object_pairs_hook=...) to reject duplicate keys (JSON.parse
     and default json.load accept them silently, last-wins).
   - New CI step runs the linter across all package.json in the repo
     (excluding node_modules) before install, fail-fast.
   - Emits ::error::file=... annotations for PR UI surfacing.

3. Branch protection docs (docs/branch-protection.md)
   - Can't be expressed in repo code; documents the required Web-UI /
     gh api settings. The critical flag is
     required_status_checks.strict=true (Require branches to be up to
     date before merging) which would have forced PR #22 to rebase onto
     current main before becoming mergeable, preventing the whole class
     of "old base + corrupted main = unresolvable 3-way merge" bug.

Verified locally (simulated CI order):
- package.json lint: 6/6 OK
- pnpm install --frozen-lockfile: clean
- pnpm rebuild better-sqlite3: done
- pnpm test: 120/120 passed
- pnpm typecheck (root + workspace): clean
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

A new CI validation step that checks for duplicate keys in package.json files is introduced, along with updates to TypeScript typecheck execution in both the root package.json script and CI workflow. Documentation for GitHub branch protection settings is added.

Changes

Cohort / File(s) Summary
CI Validation & Duplicate Key Detection
.github/scripts/check-package-json-duplicates.py, .github/workflows/ci.yml
New Python script that recursively finds and validates all package.json files for duplicate keys, with error annotations on failure. CI workflow adds this validation step before dependency installation.
TypeScript Typecheck Configuration
package.json, .github/workflows/ci.yml
Updated root typecheck script to run tsc --noEmit before workspace typecheck flow. CI workflow command changed from pnpm exec tsc --noEmit to pnpm typecheck to align with updated script definition.
Documentation
docs/branch-protection.md
New documentation file describing GitHub branch protection configuration for the main branch, including UI settings, recommended options, API configuration example, and expected operating behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A script to catch the duplicate keys,
TypeScript checks flow with ease,
Branch protection guards the main,
No duplicate pain!
Hop forward with confidence, please! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures all three main changes: workspace typecheck enhancement, package.json duplicate-key linting, and branch protection documentation—matching the PR objectives and file modifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/ci-regression-guards

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.

@theosera theosera merged commit 65138f2 into main Apr 21, 2026
2 of 3 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.

2 participants