Add no-change diagnostics for npm/yarn/pnpm lockfile updates#15068
Open
robaiken wants to merge 6 commits into
Open
Add no-change diagnostics for npm/yarn/pnpm lockfile updates#15068robaiken wants to merge 6 commits into
robaiken wants to merge 6 commits into
Conversation
Captures per-command traces (timing, success, truncated stdout/stderr, content-changed flag) across every native npm/yarn/pnpm invocation in the three lockfile updaters and surfaces them via NoChangeError#error_context. - New CommandTrace class wraps native commands and records diagnostics. - npm/yarn/pnpm lockfile updaters expose @command_traces; file_updater aggregates them into NoChangeError#error_context with reason, commands_succeeded, fallback_attempted, fallback_succeeded. - Dependabot.updater_error_details maps NoChangeError (by class name) to error-type 'no_change_error' with the structured detail hash. - ErrorHandler emits updater.no_change metric with low-cardinality tags and logs a structured summary line per command trace (debug-level dump of truncated stdout/stderr). Raise behavior of NoChangeError is unchanged.
Keeps the common layer ecosystem-agnostic. The updater already loads every ecosystem gem, so the structured 'no_change_error' payload is now produced in ErrorHandler#no_change_error_details via a class-name match (works for both Dependabot::NpmAndYarn::FileUpdater::NoChangeError and Dependabot::Bun::FileUpdater::NoChangeError, which already exists). The metric/log emission paths are unchanged.
…andTrace.record Sorbet's block: sig requires the &block param to be named 'block', and the convention in this repo is to invoke it via block.call with an inline disable (matches bun/npm_and_yarn constraint_helper.rb).
…aces Promotes the npm/yarn/pnpm-only Dependabot::NpmAndYarn::FileUpdater::CommandTrace to Dependabot::SharedHelpers::CommandTrace. The class only depends on SharedHelpers::HelperSubprocessFailed (already in common), so any ecosystem can now record per-command diagnostics with the same wrapper. A lightweight Dependabot::NpmAndYarn::FileUpdater::CommandTrace = ... alias keeps existing references compiling without churn.
dc1519c to
40a5f6a
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds structured diagnostics for npm/yarn/pnpm “no change” lockfile update failures so they’re observable (backend error details + metric + logs) instead of surfacing as an unhelpful unknown_error.
Changes:
- Introduces
Dependabot::SharedHelpers::CommandTraceand wraps native helper invocations to record timing/success and truncated output. - Enhances
npm_and_yarnNoChangeError#error_contextwith command traces and fallback metadata. - Updates the updater
ErrorHandlerto mapNoChangeErrortono_change_error, emit a newupdater.no_changemetric, and log a diagnostics block.
Show a summary per file
| File | Description |
|---|---|
| updater/spec/dependabot/updater/error_handler_spec.rb | Adds coverage for NoChangeError → no_change_error mapping, metric emission, and logging. |
| updater/lib/dependabot/updater/error_handler.rb | Maps ecosystem NoChangeError to structured payload, emits updater.no_change, logs trace summaries. |
| npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater_spec.rb | Asserts yarn updater collects traces across primary + fallback flows. |
| npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater_spec.rb | Asserts npm updater collects traces and records content_changed_after for fallback. |
| npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb | Wraps yarn commands with CommandTrace.record and annotates content_changed_after. |
| npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb | Wraps pnpm commands/fallbacks with CommandTrace.record and annotates content_changed_after. |
| npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/npm_lockfile_updater.rb | Wraps npm install/update/audit commands with CommandTrace.record and annotates content_changed_after. |
| npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater.rb | Adds CommandTrace alias and enriches NoChangeError context with traces + fallback state. |
| common/spec/dependabot/shared_helpers/command_trace_spec.rb | Adds unit tests for trace recording, truncation, and summaries. |
| common/lib/dependabot/shared_helpers/command_trace.rb | New shared helper class implementing trace capture/truncation and serialization. |
Copilot's findings
Comments suppressed due to low confidence (1)
npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater.rb:8
PnpmLockfileUpdaterreopensDependabot::NpmAndYarn::FileUpdaterbut doesn’trequire "dependabot/npm_and_yarn/file_updater"first (unlike the npm/yarn lockfile updaters). This can create load-order issues and can lead to superclass-mismatch/partial-class problems if this file is required directly. Align with the established helper pattern by requiring the main file first (and rely on it to provide theCommandTracealias).
# typed: strict
# frozen_string_literal: true
require "dependabot/shared_helpers/command_trace"
require "dependabot/npm_and_yarn/helpers"
require "dependabot/npm_and_yarn/package/registry_finder"
require "dependabot/npm_and_yarn/registry_parser"
require "dependabot/shared_helpers"
- Files reviewed: 10/10 changed files
- Comments generated: 5
markhallen
previously approved these changes
May 20, 2026
Contributor
markhallen
left a comment
There was a problem hiding this comment.
This is really cool. Nice work
- bun: expose error_context on NoChangeError so observability picks it up - updater: emit "unknown" instead of empty-string for nil boolean metric tags via bool_tag helper - npm_and_yarn: detect fallback traces by stable fingerprint to avoid false positives from dep names containing "audit" - yarn lockfile updater: extract yarn berry audit-fix fallback into helper methods to drop Metrics/AbcSize + Metrics/MethodLength rubocop disables - pnpm lockfile updater: extract fallback logic into maybe_run_pnpm_fallback to drop Metrics/AbcSize rubocop disable - pnpm lockfile updater: add load-order require for dependabot/npm_and_yarn/file_updater
5 tasks
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.
What are you trying to accomplish?
Make
NoChangeErrordebuggable for npm/yarn/pnpm. Today it surfaces asunknown_errorwith no detail on which native command ran, whether the fallback was tried, or what the package manager printed.This PR adds:
CommandTracethat wraps every native npm/yarn/pnpm invocation and records timing, success, and truncated stdout/stderr.NoChangeError#error_context, plusreason,commands_succeeded,fallback_attempted,fallback_succeeded.updater.no_changemetric (tagged by package manager + the four fields above) and a structuredno_change_errorerror-type sent to the backend.Anything you want to highlight for special attention from reviewers?
NoChangeError → no_change_errormapping lives inErrorHandler#no_change_error_details, not incommon/, socommon/stays ecosystem-agnostic. It matches by class-name suffix, which also picks up the existingDependabot::Bun::FileUpdater::NoChangeError.NoChangeError's raise behavior andsentry_contextare unchanged.How will you know you've accomplished your goal?
command_trace_spec,error_handler_spec, npm/yarn lockfile no-op specs),srb tcand rubocop clean.updater.no_changemetric appears in dashboards broken down by reason/fallback, and no-change jobs get aNo-change diagnostics:block in their logs.Checklist