You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Internal takeover of fork PR #2606 by @philippzentner. CI and secrets don't run on fork PRs. Their 6 signed commits are kept as they made them, merged in, with one fix commit on top. Thanks for the detailed write-up on #2606. The package notes below come from it.
Stacked on #2609, which is stacked on #2607. Merge after both. Until then, GitHub shows #2609's changes as the base of this diff.
dotenv 17+ prints an "injected env" line on every config() call. Explicit calls now pass { quiet: true }, including the facet demo template, except in the five demo scripts listed below. import 'dotenv/config' is quiet by default in 18.
bs58
4.0.1 → 6.0.0
v6 ships types, so the @ts-expect-error is gone.
merkletreejs
0.3.11 → 0.6.0
No code change. #2606 checked that the output is byte-identical (demoGenerateMerkleTree.ts plus 72 synthetic trees).
@arbitrum/sdk removed instead of bumped, and demoArbitrumBridge.ts deleted. It was the only user. The demo targets the Goerli testnet, which is shut down, and it reads config['goerli'].l2GatewayRouter, a key that config/arbitrumBridge.json doesn't have. Nothing references it. config/arbitrumBridge.json stays: DeployArbitrumBridgeFacet.s.sol reads it.
@cowprotocol/cow-sdk removed instead of bumped to 9, and demoPatcher.ts plus utils/cowSwapHelpers.ts deleted. They were the only users. The demo's CowShed post-hook calls RelayFacet.startBridgeTokensViaRelay, and RelayFacet is no longer on the diamond, so the script fails against current deployments (its own header said so). docs/Patcher.md and demoPatcherDest.ts still show the Patcher pattern.
Five demo scripts left as on main:demoChainflip, demoGasZip, demoLidoWrapper, demoMayanSolana, demoSquid. Their only change was the dotenv quiet flag. Touching them makes validate-scripts type-check them, and they have 15 type errors that already exist on main. Running them now prints one dotenv line.
protobufjs override removed. Nothing in the dependency tree installs protobufjs any more, so the override matched nothing.
Signing path
script/deploy/safe/ changes by one line in each of 7 files: config() → config({ quiet: true, override: false }). Nothing else under the Safe/timelock scripts changes.
override: false is there because dotenv 17+ merges DOTENV_OVERRIDE / DOTENV_CONFIG_OVERRIDE from the shell into every config() call (16 only read them for import 'dotenv/config'). Without the pin, a signer with that flag exported would have .env replace an exported PRIVATE_KEY or SC_MONGODB_URI. Options passed in code win over the shell, so the pin keeps the old precedence: an export beats the file. I checked this against dotenv 18.0.9 with DOTENV_OVERRIDE=true. propose-to-safe.ts still uses import 'dotenv/config', which reads these variables in both versions, so docs/SigningFallbackRunbook.md §3 now stops the ceremony when any DOTENV_* variable is exported, and its description of the config() call is updated.
Verification
bunx tsx ./script/utils/validateScripts.ts --base origin/chore/exsc-1281-ci-tooling-upgrades: passes (typecheck of changed scripts, bare imports, citty args)
bun test:ts: 7207 pass, 0 fail
bunx prettier --check on the touched script directories: clean. bunx oxlint --type-aware on the changed helpers: exit 0. The remaining warnings are older anys on lines this PR doesn't touch.
Node smoke run via tsx: bs58 round trip, chalk, quiet dotenv and a merkletreejs root all load and run.
Checklist before requesting a review
I have performed a self-review of my code
This pull request is as small as possible and only tackles one problem
I have added tests that cover the functionality / test the bug
Node 22 reaches end-of-life on 2027-04-30. Pin CI and .nvmrc to Node 26,
raise engines.node to >=24 so developers on the 24 LTS line keep working,
and move @types/node to 24.19.2 to match the lowest supported runtime.
tj-actions/changed-files was compromised in March 2025. The Olympix job only
needs the added/copied/modified/renamed src/**/*.sol list and a boolean, which
dorny/paths-filter (already used elsewhere) provides with identical semantics.
Bump the overrides still needed to the latest safe version within their
current major (protobufjs 7.6.6, axios 1.21.0, smol-toml 1.9.1, lodash 4.18.1,
katex 0.18.11, ws 8.22.1, ip-address 10.7.5, fast-uri 3.1.9; markdown-it is
already at the latest 14.x) and move the direct axios and smol-toml pins with
them. Drop socks, validator and handlebars: without the override the tree
already resolves a non-vulnerable version. bun audit: 83 -> 60.
Unify actions/checkout on v7.0.1 (four different v4 SHAs were in use) and
move every other external action to its latest release, SHA-pinned with
a version comment.
Minor and patch bumps for bun.lock dependencies arrive as one grouped PR
per month, with at most 5 open Dependabot PRs. The github-actions entry
stays weekly and ungrouped.
Moves the submodule to the v1.17.0 tag commit (f3dae6e) and updates
foundry.lock. src artifacts compile to identical bytecode, and forge test
gives the same pass/fail set as before.
TypeScript 7 (the native Go port) only ships the tsc binary and an
unstable API under typescript/unstable/*; require('typescript') returns
just the version. The node-runtime and funnel fences, validate-scripts
and several placement tests use the classic compiler API, so 6.0.3 is the
newest release that works.
husky 9: prepare runs `husky` (no `husky install`), and hooks no longer
source husky.sh. husky 9's wrapper still runs hooks under `sh -e`, so
pre-commit and pre-push keep re-execing themselves under `bash -e`, now
behind their own guard variable instead of husky v8's husky_skip_init.
lint-staged 17: the pre-commit output filter also drops the new progress
lines so failures still show only the tool output.
solhint 6 adds use-natspec, function-max-lines and seven gas-* rules to
solhint:recommended, which would raise ~900 warnings on src/. They are
turned off to keep the v5 rule set; the other new recommended rules
(duplicated-imports, no-immutable-before-declaration, no-unchecked-calls)
report nothing on src/ and stay on.
no-unused-vars now also checks modifier parameters (solhint 6.0.1) and
flags the unused _polymerData parameter of PolymerCCTPFacet's
validatePolymerData modifier. Fixing it changes src bytecode, so the rule
drops to warn and lint:sol reports 0 errors, 1 warning. .solhint.json is
plain JSON and solhint rejects extra keys, so the reasons live here.
.oxfmtrc.json is generated by `oxfmt --migrate=prettier` from
.prettierrc.cjs (same options, .prettierignore entries as ignorePatterns).
Prettier stays on 2.8 + prettier-plugin-solidity 1.4 for *.sol only:
Prettier 3 + plugin 2 would reformat 113 .sol files (49 under src/), and
any src/*.sol change alters bytecode metadata. solhint-plugin-prettier
stays on 0.0.5 because 0.1.0 needs Prettier 3.
Updates the format scripts, lint-staged, the agent format hook, the
factory format check, the docs that name the formatter and the VS Code
settings template.
Mechanical output of `bun format:fix` after the switch to oxfmt. No
.sol file changes. Listed in .git-blame-ignore-revs.
Committed with --no-verify: lint-staged's typecheck-files step fails on
script/demoScripts/demoChainflip.ts with the same 4 type errors it has on
main. oxlint, both fences and typecheck of the other 89 files pass.
- node-gyp 10 -> 13
- plop 3 -> 4 (bun codegen --help and a non-interactive facet run work)
- @typechain/ethers-v5 10 -> 11: same 369 files; inputs lose the
PromiseOrValue<T> wrapper and overloaded event keys use full tuple
signatures. No script uses either; tsc reports the same errors.
- markdownlint-cli2 0.23.3 -> 0.24.0 (lint:md clean)
- @types/bun 1.2 -> 1.4
- patch-package removed together with its postinstall step: the repo has
no patches/ directory, so it never applied anything.
The file has 4 type errors on main, including an undefined
lifiDiamondAddress, so they can't be fixed with type-only changes.
Reformatting it made validate-scripts type-check it and fail. It is
restored byte-for-byte to main and listed in the oxfmt ignorePatterns.
lint-staged's oxfmt entry gets --no-error-on-unmatched-pattern so
staging an ignored file doesn't fail the commit.
Committed with --no-verify: staging the file makes lint-staged's
typecheck-files step report its 4 pre-existing errors, which happens for
any commit that touches it on main too.
v11 drops PromiseOrValue<T> from common.ts and every input type and
renames overloaded event keys. types.yaml publishes this output to
lifinance/lifi-contract-types as a patch/minor release, so v11 would
break downstream TS consumers. It needs a coordinated major release of
lifi-contract-types plus a downstream migration. The typechain output is
identical to the #2604 baseline again.
v4 renamed L1ToL2MessageGasEstimator to ParentToChildMessageGasEstimator
and exports it from the package root. estimateAll keeps the same
arguments and the l2CallValue field, so the demo script only needs the
import and constructor rename.
bs58 6 ships its own types, so the @ts-expect-error on the default
import is no longer needed. decode() now returns a Uint8Array instead of
a Buffer; the only consumer passes it to viem's toHex, which accepts
both.
Output is unchanged: demoGenerateMerkleTree.ts writes a byte-identical
outputMerkleProofs.json under 0.3.11 and 0.6.0 (sha256 0ab8f479…), and a
comparison over 72 trees (both gasRebates networks plus synthetic trees
of 1-70 leaves, including odd counts and a duplicate leaf) gives the
same roots and proofs.
chalk 6 only raises the Node floor to 22 (the repo runs Node 26) and
changes numeric FORCE_COLOR / ansi256 downsampling, neither of which the
scripts use. Kept as an exact pin, like before.
dotenv 17+ logs an "injected env" line on every config() call (to
stderr since 18). Pass { quiet: true } at all 34 explicit config() call
sites, including the facet demo template, so script output stays the
same as on dotenv 16. The 'dotenv/config' side-effect import already
defaults to quiet since 18.0.4. No script uses the removed .env.vault
support or preloading.
Touches signing-path files under script/deploy/safe/ (one-line
config() -> config({ quiet: true }) each).
cow-sdk 7+ takes a provider adapter instead of an ethers signer. The
demo now passes a ViemAdapter (@cowprotocol/sdk-viem-adapter) built from
the same Arbitrum RPC and private key; the ethers v5 adapter was not used
because it peers on @typechain/ethers-v5 11. postSwapOrder now returns an
object, so the order id is read from .orderId.
The CowShed constants moved to @cowprotocol/sdk-cow-shed and are keyed by
version; the helper keeps the 1.0.0 factory and implementation, which
are the same addresses cow-sdk 5 exported.
- Restore the validator 13.15.26 override: tronweb pins 13.15.23,
which still carries AIKIDO-2025-10980 (see #2257).
- Pin dorny/paths-filter to v3.0.4: list-files: shell is affected by
GHSA-7hc6-8hq5-9q2m below 3.0.4.
- Raise the Node minimum to 26 (engines, @types/node 26.6.6, Setup.md)
to match .nvmrc, CI and the factory doctor check.
- Correct the setup-bun version comment (the SHA is v2.1.2) and quote
$GITHUB_ENV in the Olympix args step.
- Reword the node-runtime fence comment: the allowlist follows what a
.ts entry gets under tsx, not a Node version.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pin the three remaining setup-bun@v2 steps to v2.1.2 with
bun-version-file, and install with --frozen-lockfile in validate-scripts
- Add setup-node (node-version-file: .nvmrc) after every setup-bun step,
so scripts run by `bunx tsx` use the Node that engines requires; the
two existing setup-node steps also read .nvmrc
- Move every dorny/paths-filter call site to v3.0.4
- Olympix: read the changed-file list as JSON and fail on whitespace in
a path instead of re-parsing shell output with xargs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- factory.yml: check TS/JS format with oxfmt, which now owns it.
- Drop .git-blame-ignore-revs: it names a fork-branch SHA that a
squash merge discards. Add the main-branch SHA after merge.
- dependabot: 7-day cooldown on bun updates, and ignore the majors
this PR holds back (@typechain/ethers-v5, prettier,
prettier-plugin-solidity, solhint-plugin-prettier >=0.1, typescript).
- solhint: keep no-unused-vars an error, with validateParameters off
so the existing unused modifier parameter in PolymerCCTPFacet does
not need a src change.
- Drop the ip-address override: its only consumer (socks) is gone.
- Pin the bumped dev dependencies to their resolved versions.
- .oxfmtrc.json: drop the copy of .prettierignore, which oxfmt reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
oxfmt follows Prettier 3's output, so switching from Prettier 2.8.8
rewrites ~90 TS/JS files (ternary indentation, trailing commas in type
arguments, parentheses around ??) with no way to configure it back.
That churn conflicts with every open script branch and pushes this PR
past CodeRabbit's 100-file limit. Restore the formatter setup, the
reformatted files and the docs/hooks to their pre-switch state, and
leave a formatter change for its own PR.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in d1cde7d (setup-node after every setup-bun, paths-filter
unified, Olympix JSON file list). Conflicts keep this branch's newer
pins (paths-filter v4.0.3, setup-bun v2.2.0), and every setup-node,
including the ones d1cde7d adds, moves to v7.1.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
husky 9 runs hooks under sh -e, so sourcing ~/.huskyrc before the re-exec
ran it under dash on Linux and dropped its unexported variables at exec.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pin the bumped SDKs to exact versions
- drop the protobufjs override: the cow-sdk 9 tree no longer pulls it in
- delete demoArbitrumBridge.ts and @arbitrum/sdk: the demo targets the shut
down Goerli testnet and reads a config key that does not exist
- leave five demo scripts as on main: their only change was dotenv's quiet
flag, and touching them surfaces type errors that predate this PR
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No actionable comments were generated in the recent review.
Walkthrough
The PR updates package dependencies, removes three demo-related code components, and changes dotenv configuration across scripts and a template. It also updates the signing runbook’s environment checks and removes a TypeScript suppression on the bs58 import.
Changes
Script and dependency updates
Layer / File(s)
Summary
Dependency changes and demo removals package.json, script/demoScripts/demoArbitrumBridge.ts, script/demoScripts/demoPatcher.ts, script/demoScripts/utils/cowSwapHelpers.ts
Dependency versions and package entries changed. The Arbitrum bridge demo, Patcher demo, and CowSwap helper file were removed.
Dotenv calls now use quiet: true. The @ts-expect-error directive on the bs58 import was removed.
Safe-script environment loading and runbook checks script/deploy/safe/*, docs/SigningFallbackRunbook.md
Safe scripts now use dotenv options quiet: true and override: false. The runbook documents dotenv configuration variables and flags exported DOTENV_* variables as environment conflicts.
The new override:false setting in the Safe scripts does not protect against earlier dotenv loads in shared helpers. A direct CLI run with DOTENV_CONFIG_OVERRIDE set could replace exported signing values. Apply override:false to those helper loads or accept the limited risk before merging.
Pre-merge checks: 5
Check name
Status
Explanation
Title check
The title identifies the main dependency upgrades.
Description check
The description includes all template sections and explains the changes and verification. The tests and documentation checklist items remain unchecked.
Docstring Coverage
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage
Explanation
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 28 files. (1 skipped: 1 unsupported.)
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.
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.
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.
demoPatcher.ts was the only user of @cowprotocol/cow-sdk,
sdk-cow-shed and sdk-viem-adapter. Its post-hook calls RelayFacet,
which is no longer on the diamond.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
dotenv 17+ merges DOTENV_OVERRIDE / DOTENV_CONFIG_OVERRIDE from the
shell into every config() call, so an exported flag could let .env
replace an exported PRIVATE_KEY or SC_MONGODB_URI. Passing
override: false keeps exports ahead of the file. The signing runbook
now also stops on any exported DOTENV_* setting, which still applies
to propose-to-safe's import 'dotenv/config'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Verdict: ✅ Approve · Head dfdd1b1bd7eb · 🆕 First review · 0 findings · Awaiting response: 0 · 5 refuted
Summary
Script dependency bump (dotenv 18, chalk 6, bs58 6, merkletreejs 0.6) that removes @arbitrum/sdk, the CoW SDKs and their demo scripts. 35 files, +76/−1370, no src/ change (no audit entry needed). The PR is stacked on #2609, so the files diff is only this PR's own work; it must merge after #2609 and #2607.
Ticket check
AC
Result
Remove @arbitrum/sdk with demoArbitrumBridge.ts
✅
Remove @cowprotocol/cow-sdk with demoPatcher.ts, cowSwapHelpers.ts
✅
dotenv 16 → 18 with quiet: true
✅
chalk 5 → 6, bs58 4 → 6, merkletreejs 0.3 → 0.6
✅
Skip @solana/web3.js 3 and citty 0.2
✅
Findings
None.
Refuted candidates
Removed deps still referenced: repo-wide grep (excluding bun.lock) finds no remaining reference to @arbitrum/sdk, @cowprotocol/*, cowSwapHelpers, demoPatcher.ts, demoArbitrumBridge, protobufjs.
bs58 6 break: sole user demoScriptHelpers.ts uses decode/encode with Uint8Array, which viem's toHex accepts; dropping the @ts-expect-error is right since v6 ships types.
Unpinned dotenv in the signing path: all 7 script/deploy/safe/*config() calls pass { quiet: true, override: false }; only the 5 demo scripts keep bare calls, as the PR states.
chalk 6 / merkletreejs 0.6 API change: imports and the new MerkleTree(leafNodes, keccak256, { sortPairs: true }) call match the new APIs.
Lockfile / protobufjs override: bun-lockfile-check passes and bun.lock has no protobufjs entry.
Notes (do not gate)
🔵 No test pins override: false in the 7 signing files; a later refactor could drop it unnoticed.
🔵 DOTENV_CONFIG_PATH could redirect which .env the signing scripts load under dotenv 17+; the new runbook ^DOTENV_ check covers the manual ceremony.
🔵 bs58 and dotenv sit in devDependencies although demo scripts use them at runtime (pre-existing).
Downstream impact
Tooling only; no ABI, selector or storage change. CI is green (run-ts-tests, validate-scripts, bun-lockfile-check, check-secrets, enforce-proposal-funnel, verify-build-manifest); audit and Solidity jobs are skipped as expected. I did not run the scripts; CI is the evidence.
The reason will be displayed to describe this comment to others. Learn more.
The bumps and removals check out. merkletreejs 0.6 gives byte-identical roots and proofs, bs58 6's Uint8Array decode is fine for the one toHex use, CI runs Node 26 for chalk 6, and nothing references the removed SDKs any more.
One thing to fix: the override: false pin in script/deploy/safe/ doesn't hold. Those files import viemScriptHelpers.ts, which imports utils.ts, and both load .env without a pin at module scope (import 'dotenv/config' in utils.ts:6, dotenv.config({ quiet: true }) in viemScriptHelpers.ts:39). ESM runs those before the safe file's own config() call, so by the time the pin runs, .env has already overwritten the export.
Repro: export a variable, put a different value in a file passed via DOTENV_PATH, set DOTENV_OVERRIDE=true, and import safe-utils.ts. The file value wins. Without DOTENV_OVERRIDE the export still wins, as before.
The new runbook guard on DOTENV_* still stops the ceremony, so this isn't a live hole there. But the PR description and runbook §3 promise more than the code does, and anyone running the safe scripts outside the runbook isn't covered. Part of this predates the PR (dotenv 16 already honoured DOTENV_CONFIG_OVERRIDE through utils.ts), but 18 applies it to every config() call.
Suggested fix: pin override: false in utils.ts and viemScriptHelpers.ts, ideally through one shared loader, then rerun the repro.
The reason will be displayed to describe this comment to others. Learn more.
Every pinned call in script/deploy/safe/ runs after this one, because they import this file. With DOTENV_OVERRIDE=true exported, this call has already let .env overwrite the export. It needs override: false here too, and so does the import 'dotenv/config' in utils.ts:6, which this file imports.
The reason will be displayed to describe this comment to others. Learn more.
DOTENV_OVERRIDE flips precedence for any unpinned config() in the import graph, not only import 'dotenv/config'. Also, utils.ts's dotenv/config loads before confirm-safe-tx's pinned call. The STOP outcome is right; the explanation just needs to match the code once the pin is fixed.
Base automatically changed from
chore/exsc-1281-ci-tooling-upgrades to
mainNovember 9, 2026 11:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
QA AI ApprovedZeus QA review passedrequires-typesTrigger Types Bindings CI (ABI/type generation for lifi-contract-types)
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which Linear task belongs to this PR?
Fixes EXSC-1306
Why did I implement it this way?
Internal takeover of fork PR #2606 by @philippzentner. CI and secrets don't run on fork PRs. Their 6 signed commits are kept as they made them, merged in, with one fix commit on top. Thanks for the detailed write-up on #2606. The package notes below come from it.
Stacked on #2609, which is stacked on #2607. Merge after both. Until then, GitHub shows #2609's changes as the base of this diff.
Packages (from #2606)
dotenvconfig()call. Explicit calls now pass{ quiet: true }, including the facet demo template, except in the five demo scripts listed below.import 'dotenv/config'is quiet by default in 18.bs58@ts-expect-erroris gone.merkletreejsdemoGenerateMerkleTree.tsplus 72 synthetic trees).chalkNot bumped, as in #2606:
@solana/web3.js3:@solana/spl-token0.4.x still peers on web3.js 1.citty0.2: it breaks 11script/deploy/safeflag tests, so it needs its own reviewed PR.Changes on top of #2606
@arbitrum/sdkremoved instead of bumped, anddemoArbitrumBridge.tsdeleted. It was the only user. The demo targets the Goerli testnet, which is shut down, and it readsconfig['goerli'].l2GatewayRouter, a key thatconfig/arbitrumBridge.jsondoesn't have. Nothing references it.config/arbitrumBridge.jsonstays:DeployArbitrumBridgeFacet.s.solreads it.@cowprotocol/cow-sdkremoved instead of bumped to 9, anddemoPatcher.tsplusutils/cowSwapHelpers.tsdeleted. They were the only users. The demo's CowShed post-hook callsRelayFacet.startBridgeTokensViaRelay, and RelayFacet is no longer on the diamond, so the script fails against current deployments (its own header said so).docs/Patcher.mdanddemoPatcherDest.tsstill show the Patcher pattern.demoChainflip,demoGasZip,demoLidoWrapper,demoMayanSolana,demoSquid. Their only change was the dotenvquietflag. Touching them makesvalidate-scriptstype-check them, and they have 15 type errors that already exist on main. Running them now prints one dotenv line.protobufjsoverride removed. Nothing in the dependency tree installs protobufjs any more, so the override matched nothing.Signing path
script/deploy/safe/changes by one line in each of 7 files:config()→config({ quiet: true, override: false }). Nothing else under the Safe/timelock scripts changes.override: falseis there because dotenv 17+ mergesDOTENV_OVERRIDE/DOTENV_CONFIG_OVERRIDEfrom the shell into everyconfig()call (16 only read them forimport 'dotenv/config'). Without the pin, a signer with that flag exported would have.envreplace an exportedPRIVATE_KEYorSC_MONGODB_URI. Options passed in code win over the shell, so the pin keeps the old precedence: an export beats the file. I checked this against dotenv 18.0.9 withDOTENV_OVERRIDE=true.propose-to-safe.tsstill usesimport 'dotenv/config', which reads these variables in both versions, sodocs/SigningFallbackRunbook.md§3 now stops the ceremony when anyDOTENV_*variable is exported, and its description of theconfig()call is updated.Verification
bunx tsx ./script/utils/validateScripts.ts --base origin/chore/exsc-1281-ci-tooling-upgrades: passes (typecheck of changed scripts, bare imports, citty args)bun test:ts: 7207 pass, 0 failbunx prettier --checkon the touched script directories: clean.bunx oxlint --type-awareon the changed helpers: exit 0. The remaining warnings are olderanys on lines this PR doesn't touch.tsx:bs58round trip,chalk, quietdotenvand amerkletreejsroot all load and run.Checklist before requesting a review
Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)
🤖 Generated with Claude Code