Resolve config per-file when -f is used#136
Merged
silverwind merged 2 commits intomasterfrom May 4, 2026
Merged
Conversation
Previously loadConfig was always called with cwd(), so running `updates -f ../other -M docker` from a different cwd would never see `../other/updates.config.ts` and silently ignore its pin/include/exclude. Changes: - loadConfig now walks up from its argument to find the nearest updates.config.*. Both the walk-up (findCache by startDir) and the final config (configCache by resolved configDir) are memoized so per-dep loadConfig calls in the docker/actions handlers don't rescan the filesystem. - index.ts derives a startDir from -f/positionals (first path's dir, or itself if it's a directory). Falls back to cwd when no path was given. - pin, include, and exclude are now resolved per-file: each docker and actions dep walks up from its own file's dir to find the nearest config and uses that config's pin/include/exclude. CLI/API-set values still act as cross-file overrides. - The candidate-loading logic (tryLoadInDir) uses Promise.all + outcome objects so a broken sibling updates.config.js next to a valid updates.config.ts no longer blocks the valid one. - utils/renovate.ts: loadRenovateConfig walks up to find the nearest renovate config, mirroring the updates.config behavior, and is cached by startDir. Behavior change worth calling out: when a workspace member has its own updates.config.ts, the member's pin is now authoritative for its deps instead of being merged with (and overridden by) the workspace root's pin. The closer config wins. Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
… filePin to dep info - utils/utils.ts: add walkUp and memoizeAsync helpers. - config.ts: use both helpers; drop the second cache layer (configCache) since findCache + the renovate cache already cover the expensive work; replace the LoadOutcome union with FoundConfig | Error | null. - utils/renovate.ts: collapse findRenovateUp into a memoizeAsync(walkUp) one-liner. - api.ts: attach filePin to ActionDepInfo/DockerDepInfo at push time instead of fishing it back out of wfData/dockerFileData via relPath split. collectDockerRefs takes a single FileFilters object instead of two extra positionals. - index.ts: factor startDir derivation into deriveStartDir, drop the narrating comment. Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
silverwind
added a commit
that referenced
this pull request
May 4, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Why
Running
updates -f ../other -M dockerfrom a different cwd silently ignored../other/updates.config.tsbecauseloadConfigonly looked atcwd().What
loadConfignow walks up to find the nearestupdates.config.*. Renovate config gets the same treatment.startDirfrom-f/positionals (first path's dir) and feeds that toloadConfig.pin,include, andexcludeare resolved per-file: each docker/actions dep walks up from its own file's dir and uses that config. CLI/API-set values still override across files.updates.config.jsnext to a validupdates.config.tsno longer blocks the valid one.utils/utils.ts(walkUp,memoizeAsync); reused in renovate loader.Behavior change
When a workspace member has its own
updates.config.ts, the member's pin is now authoritative for its deps. Previously the workspace root's pin merged on top. The closer config wins.Verification
make lintcleanupdates -f ../leaseapi -M dockerhonorspin: { mysql: "8.0" };-l mysql=9overrides correctly.This PR was written with the help of Claude Opus 4.7