Skip to content

ci: cross-Node-major install canary + strict postinstall opt-in#208

Merged
efenocchi merged 1 commit into
mainfrom
fix/ci-cross-node-canary
May 27, 2026
Merged

ci: cross-Node-major install canary + strict postinstall opt-in#208
efenocchi merged 1 commit into
mainfrom
fix/ci-cross-node-canary

Conversation

@efenocchi
Copy link
Copy Markdown
Collaborator

@efenocchi efenocchi commented May 26, 2026

Why

PR #206 (fix(deps): build tree-sitter from source on linux-arm64 / Node >=22) introduced a postinstall heal that turned a hard install failure on Node 24 into a silent WARNING: tree-sitter bindings still unavailable + exit 0. Because ci.yaml runs only on Node 22 — where the linux-x64 prebuild ABI matches and the heal short-circuits cleanly — the regression was invisible at PR time and only surfaced post-merge in the Release workflow (run 26430516153), which was pinned to Node 24.12. That broke v0.7.55 mid-release.

The unblock is in #207 (pin release.yaml to Node 22). This PR closes the detection gap so the next regression of this class fails on the PR instead of on main.

What

Two pieces:

1. New cross-node-install job in ci.yaml

  • Matrix [22, 24] — every Node major the engines field (>=22.0.0) admits
  • Runs npm install && npm run build only — the bug class is install/build-time, not runtime, so running the full test suite on every matrix slot doubles CI cost for no extra signal
  • continue-on-error: true — keeps PRs unblocked while the known upstream tree-sitter@0.21 + Node 24 incompatibility is being resolved. Signal is still visible in the PR checks table as yellow/red. Flip to false once Node 24 install is healthy.

2. Opt-in strict mode for scripts/ensure-tree-sitter.mjs

  • HIVEMIND_STRICT_POSTINSTALL=1 (set by this repo's own CI workflows) turns WARNING: bindings still unavailable into exit 1 instead of exit 0
  • Downstream consumers of @deeplake/hivemind never see this flag, so their install stays non-fatal as before
  • Strict path turns a buried tsc: Cannot find module 'tree-sitter' 30 seconds later into an immediate, labeled install-time failure

How this would have caught #206#207

PR #206 in the new canary's Node 24 slot:

  1. npm install runs the postinstall heal
  2. Heal fails to make bindings loadable → WARNING + HIVEMIND_STRICT_POSTINSTALL=1exit 1
  3. Job fails at the install step with a clear [ensure-tree-sitter] WARNING: ... (strict mode — failing this install)
  4. PR check shows red Node 24 row; reviewer / author sees the regression before merging

Even with strict mode off, the next step (npm run build) would have failed tsc with Cannot find module 'tree-sitter' — same failure as the Release run, but on the PR.

Test plan

  • Node 22 canary slot passes (existing prebuild ABI match, heal no-op)
  • Node 24 canary slot fails RED but doesn't block PR merge (continue-on-error)
  • Existing test (Node 22) and duplication jobs unaffected
  • Locally verified: strict-mode logic in ensure-tree-sitter.mjs exits 1 only when both HIVEMIND_STRICT_POSTINSTALL=1 AND bindingsLoad() === false; healthy bindings still exit 0

Follow-up (not in this PR)

  • Align release.yaml and publish-smoke-test.yaml env to also set HIVEMIND_STRICT_POSTINSTALL=1 once ci(release): pin release + publish jobs to Node 22 #207 lands
  • Add Node 26 to matrix when it ships
  • Once tree-sitter@0.21 vs Node 24 is resolved upstream (or we upgrade tree-sitter), flip continue-on-error to false to make Node 24 install a hard gate

Summary by CodeRabbit

  • Chores
    • Enhanced CI pipeline to test builds across multiple Node.js versions (22, 24) with stricter validation rules, ensuring improved build reliability and compatibility.

Review Change Stack

PR #206 introduced a tree-sitter native-dep heal that turned a hard
install failure on Node 24 into a silent "WARNING" + exit 0. Because
ci.yaml only ran on Node 22 (where tree-sitter's linux-x64 prebuild
ABI matches and the heal short-circuits), the regression was invisible
at PR time and only surfaced post-merge on release.yaml (pinned to
Node 24.12), where it broke v0.7.55 mid-release.

Close the detection gap with two pieces:

1. New `cross-node-install` job in ci.yaml — matrix [22, 24], runs
   `npm install && npm run build` only (no full test suite — the bug
   class is install/build-time, not runtime). Marked
   `continue-on-error: true` so PRs are not blocked while the known
   tree-sitter@0.21 + Node 24 break is being resolved; the job is
   still visible in the PR checks table as yellow/red. Flip to
   `continue-on-error: false` once the underlying incompatibility
   is fixed (or matrix entries adjusted).

2. Opt-in strict mode for scripts/ensure-tree-sitter.mjs — when
   HIVEMIND_STRICT_POSTINSTALL=1 is set (only by this repo's own CI),
   the "bindings still unavailable" warning becomes `exit 1` instead
   of `exit 0`. Downstream consumers of @deeplake/hivemind never see
   this flag, so their install stays non-fatal as before. The strict
   path turns a buried tsc "Cannot find module 'tree-sitter'" failure
   30 seconds later into an immediate, labeled install-time error.

The canary alone would have caught PR #206's regression at the
typecheck step (tsc fails to resolve `tree-sitter`); strict mode
makes the failure faster and more diagnostic.

Follow-up: once Node 24 install is healthy, also align release.yaml +
publish-smoke-test.yaml to set HIVEMIND_STRICT_POSTINSTALL=1 and add
Node 26 to the matrix when it lands.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

📝 Walkthrough

Walkthrough

This PR introduces an opt-in strict postinstall mode for tree-sitter native bindings, controlled by the HIVEMIND_STRICT_POSTINSTALL environment variable. When enabled, unloadable bindings cause a hard failure (exit code 1) instead of silent continuation. A new GitHub Actions canary job tests this mode across Node 22 and 24 without blocking PRs.

Changes

Strict postinstall mode and Node canary

Layer / File(s) Summary
Strict postinstall mode implementation
scripts/ensure-tree-sitter.mjs
Script reads HIVEMIND_STRICT_POSTINSTALL flag and exits with code 1 when strict mode is enabled and tree-sitter bindings fail to load; warning text is updated to distinguish strict (hard-fail) from non-fatal (silent) behavior.
Node compatibility canary CI job
.github/workflows/ci.yaml
New GitHub Actions job cross-node-install runs npm install and npm run build with HIVEMIND_STRICT_POSTINSTALL=1 on Node 22 and 24 matrix; configured with continue-on-error: true and fail-fast: false to surface canary failures without blocking PRs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • activeloopai/hivemind#206: Both PRs modify scripts/ensure-tree-sitter.mjs to control how missing/unloadable tree-sitter native bindings are handled during install (retrieved PR adds the rebuild/no-op script, main PR adds the opt-in strict mode that can hard-fail).

Poem

🐰 A rabbit hops through Node versions bright,
With strict postinstall checks set tight,
Tree-sitter bindings fail or fly,
The canary sings—no silent goodbye! 🌳

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the two main changes: adding a cross-Node install canary and introducing strict postinstall mode.
Description check ✅ Passed The description fully completes the template with comprehensive Why/What/How context, test plan, and follow-ups; all required sections are thoroughly addressed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 fix/ci-cross-node-canary

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report

No src/*.ts files changed in this PR.

Generated for commit 5e1d795.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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.yaml:
- Around line 321-326: Replace the tag refs with pinned commit SHAs for the
GitHub Actions used and disable checkout credential persistence: update the
checkout step referencing actions/checkout (currently actions/checkout@v6.0.2)
to use a specific commit SHA and add persist-credentials: false, and similarly
pin actions/setup-node (currently actions/setup-node@v6.4.0) to its commit SHA;
ensure the steps named "actions/checkout" and "Setup Node.js"/uses
"actions/setup-node" are updated accordingly to use commit SHAs and the checkout
step includes persist-credentials: false.
🪄 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: CHILL

Plan: Pro Plus

Run ID: 7f550200-8200-4710-8cae-6d6434e03ef5

📥 Commits

Reviewing files that changed from the base of the PR and between 1732489 and a580fd4.

📒 Files selected for processing (2)
  • .github/workflows/ci.yaml
  • scripts/ensure-tree-sitter.mjs

Comment thread .github/workflows/ci.yaml
Comment on lines +321 to +326
- uses: actions/checkout@v6.0.2

- name: Setup Node.js
uses: actions/setup-node@v6.4.0
with:
node-version: ${{ matrix.node-version }}
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 26, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced workflow segment
sed -n '260,360p' .github/workflows/ci.yaml | nl -ba | sed -n '1,160p'

# Search for persist-credentials usage and whether checkout steps are pinned elsewhere
rg -n "persist-credentials" .github/workflows/ci.yaml .github/workflows || true
rg -n "uses:\s*actions/(checkout|setup-node)@" .github/workflows/ci.yaml .github/workflows || true
rg -n "actions/checkout@v|actions/setup-node@v" .github/workflows/ci.yaml .github/workflows || true

# Check if the job is named cross-node-install and capture its bounds
rg -n "cross-node-install" .github/workflows/ci.yaml

Repository: activeloopai/hivemind

Length of output: 108


🏁 Script executed:

#!/bin/bash
set -euo pipefail

WF=".github/workflows/ci.yaml"

# Show the referenced region with line numbers (no nl dependency)
awk 'NR>=260 && NR<=360 {printf "%6d  %s\n", NR, $0}' "$WF"

# Search for persist-credentials usage
rg -n "persist-credentials" .github/workflows/ci.yaml .github/workflows || true

# Search for unpinned checkout/setup-node usage patterns in workflows
rg -n "uses:\s*actions/(checkout|setup-node)@" .github/workflows/ci.yaml .github/workflows || true

# Search for other actions/checkout/setup-node with SHA pinning elsewhere
rg -n "uses:\s*actions/(checkout|setup-node)@[0-9a-f]{7,40}" .github/workflows/ci.yaml .github/workflows || true

# Locate the job block for cross-node-install (for context)
rg -n "cross-node-install" .github/workflows/ci.yaml

Repository: activeloopai/hivemind

Length of output: 6051


Pin GitHub Actions and disable checkout credential persistence in cross-node-install

  • In .github/workflows/ci.yaml (cross-node-install), actions/checkout@v6.0.2 and actions/setup-node@v6.4.0 use tag refs instead of commit SHAs.
  • Update the checkout step to set persist-credentials: false for least-privilege CI.
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 321-321: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 321-321: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 324-324: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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.yaml around lines 321 - 326, Replace the tag refs with
pinned commit SHAs for the GitHub Actions used and disable checkout credential
persistence: update the checkout step referencing actions/checkout (currently
actions/checkout@v6.0.2) to use a specific commit SHA and add
persist-credentials: false, and similarly pin actions/setup-node (currently
actions/setup-node@v6.4.0) to its commit SHA; ensure the steps named
"actions/checkout" and "Setup Node.js"/uses "actions/setup-node" are updated
accordingly to use commit SHAs and the checkout step includes
persist-credentials: false.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the flag — this is a real supply-chain hardening best-practice, but I'm going to leave PR #208 as-is and not apply the suggestion here. Reasoning:

  1. Consistency with existing repo convention. Every other actions/* reference in ci.yaml, release.yaml, and publish-smoke-test.yaml uses tag refs (@v6.0.2, @v6.4.0, @v4.0.0, …). The new cross-node-install job is following that established pattern.
  2. Partial pinning provides no real benefit. A compromised actions/checkout@v6.0.2 re-tag would still hit the other unprotected steps across the repo — pinning only the new job hardens nothing.
  3. Right scope is a separate PR. SHA-pinning + persist-credentials: false is a repo-wide hygiene change. Mixing it into a CI canary PR creates noisy review and risks divergent state if the broader rollout stalls.

Tracking this as a follow-up for a dedicated hardening PR that covers all workflow files at once. Will tag back here when that lands.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@efenocchi, that's a well-reasoned call — partial pinning in isolation doesn't move the security needle when the rest of the repo is unpinned, and a dedicated hardening PR is the right scope for this. Happy to open a tracking GitHub issue for the repo-wide SHA-pinning + persist-credentials: false rollout if that would help keep it from falling through the cracks. Just let me know.

🐇 (_) noted and stepping aside


✏️ Learnings added
Learnt from: efenocchi
Repo: activeloopai/hivemind PR: 208
File: .github/workflows/ci.yaml:321-326
Timestamp: 2026-05-26T17:14:33.852Z
Learning: In the activeloopai/hivemind repository, all GitHub Actions references in ci.yaml, release.yaml, and publish-smoke-test.yaml intentionally use tag refs (e.g., actions/checkoutv6.0.2, actions/setup-nodev6.4.0) rather than commit SHA pins. This is a known gap that the maintainers plan to address in a dedicated repo-wide hardening PR rather than per-job. Do not flag individual jobs for not using SHA-pinned actions until that dedicated PR lands.

Learnt from: efenocchi
Repo: activeloopai/hivemind PR: 208
File: .github/workflows/ci.yaml:321-326
Timestamp: 2026-05-26T17:14:33.852Z
Learning: In the activeloopai/hivemind repository, persist-credentials: false is not set on any checkout step across workflow files (ci.yaml, release.yaml, publish-smoke-test.yaml). The maintainers are aware and tracking a future repo-wide hardening PR to add SHA pinning and persist-credentials: false to all workflow files simultaneously.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@efenocchi efenocchi merged commit 6fc4698 into main May 27, 2026
7 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