Skip to content

Feature/xray 138688 add yarn support for jf ca#759

Open
gauriy-tech wants to merge 4 commits into
jfrog:devfrom
gauriy-tech:feature/XRAY-138688-add-yarn-support
Open

Feature/xray 138688 add yarn support for jf ca#759
gauriy-tech wants to merge 4 commits into
jfrog:devfrom
gauriy-tech:feature/XRAY-138688-add-yarn-support

Conversation

@gauriy-tech
Copy link
Copy Markdown
Contributor

@gauriy-tech gauriy-tech commented May 21, 2026

  • The pull request is targeting the dev branch.
  • The code has been validated to compile successfully by running go vet ./....
  • The code has been formatted properly using go fmt ./....
  • All static analysis checks passed.
  • All tests have passed. If this feature is not already covered by the tests, new tests have been added.
  • Updated the Contributing page / ReadMe page / CI Workflow files if needed.
  • All changes are detailed at the description. if not already covered at JFrog Documentation, new documentation have been added.

Add Yarn V2/V3 support for jf curation-audit

Previously jf ca had no Yarn support — running it on a Yarn project would either silently resolve via the npm code path or produce incomplete results. This PR adds full Yarn Berry (V2/V3) support.

What changed:

Curation install via Artifactory — rewrites the Yarn registry URL in .yarnrc.yml to the api/curation/audit// endpoint before running yarn install --mode=update-lockfile, then restores the original config. This routes all Yarn resolution through the curation service so 403 responses surface blocked packages.

Blocked package detection when install fails — when a curation 403 aborts the lockfile write (Yarn V3 rolls back on any error), the code falls back to probing declared direct dependencies via HEAD requests and renders the same blocked-package table the normal path produces.

Workspace member support — jf ca --working-dirs= on a Yarn workspace member re-routes to the workspace root automatically (Yarn V2+ cannot operate from a non-root). A new DetectedTechnologiesListForCurationAudit() promotes npm-detected workspace members to Yarn so the correct code path runs.

Workspace member filtering in graph — local workspace member packages (identified by the Yarn Berry name-hash pattern, e.g. admin-ui-428bae:0.0.0) are skipped when probing Artifactory — they have no remote artifact.

Root-only dep scope — when jf ca is run from a workspace root without --working-dirs, only the root package.json direct deps are audited. Use --working-dirs to audit individual members.

--run-native guard — --run-native is explicitly rejected for non-npm techs with a clear error; only npm implements the matching native-config flow today.

Graceful non-JSON 403 handling — when Artifactory returns an HTML error page instead of a JSON curation envelope, the package is still recorded as blocked with unknown policy rather than being silently dropped.

Testing done is documented here
https://jfrog-int.atlassian.net/browse/XRAY-140292

@gauriy-tech gauriy-tech force-pushed the feature/XRAY-138688-add-yarn-support branch from a4242f6 to decd960 Compare May 25, 2026 16:39
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-138688-add-yarn-support branch from decd960 to 1d6bde3 Compare May 26, 2026 08:30
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-138688-add-yarn-support branch from 1d6bde3 to a15280f Compare May 27, 2026 04:18
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-138688-add-yarn-support branch from a15280f to f496cf0 Compare May 27, 2026 04:22
@gauriy-tech
Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

if analyzer.cancelled.Load() {
// Any non-200/403 response from fetchNodesStatus means the walk is incomplete; bail out rather
// than rendering a misleading "0 blocked packages" report.
if err = analyzer.fetchNodesStatus(depTreeResult.FlatTree, &packagesStatusMap, rootNodes); err != nil {
Copy link
Copy Markdown

@gineshkumar gineshkumar May 27, 2026

Choose a reason for hiding this comment

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

Has this behavior change been signed off with Product?

auditTree now returns early on any non-nil error from fetchNodesStatus. Previously the walk continued and the user got both the partially-collected blocked packages and the error condition. The updated "npm tree - two blocked one error" test case captures the shift:

  • Before: report listed underscore@1.13.6 as blocked (because the HEAD-check returned 403) and surfaced the lightweight HTTP 500 as an executor error → user knew "one definitively blocked, one couldn't be checked."
  • After: report is empty and the user sees only the executor error → user knows "scan failed" but loses the actionable signal about underscore.

This affects every tech path that goes through auditTree (npm, pip, maven, gradle, gem, nuget, docker, …), not only yarn — so the blast radius is wider than the PR title suggests.

Both extremes are defensible, but they're not the only options. A third design that doesn't appear to have been evaluated: introduce a BlockingReasonScanIncomplete (or equivalent) entry in the report so the walker continues, the partially-collected blocked packages are surfaced, AND the rows that couldn't be checked are explicitly marked "scan incomplete" rather than silently dropped. That preserves the actionable signal for CI consumers while still being honest about coverage gaps.

Could you confirm Product has reviewed the change in user-visible behavior, and ideally call it out in the PR description / release notes so existing consumers of partial reports aren't caught by surprise?

Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread commands/audit/auditbasicparams.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
@gineshkumar
Copy link
Copy Markdown

Two new code paths in this PR handle the same upstream condition (a 403 with an unparseable or empty-Errors body) but produce very different report rows:

  • yarn V2 probe (yarn.go:857,911): row shows "Blocked by curation (response could not be parsed)" — honest.
  • General walker (curationaudit.go:1098,1109): row shows Policy violations with empty Policy / Explanation / Recommendation — looks identical to a real policy block.

The general walker runs for every tech (npm, pip, maven, gradle, yarn-V3-success-path, …), so the silent-collapse behaviour is the dominant case across the product. A support engineer triaging a later ticket has no way to tell "real policy block, empty payload" from "403 we couldn't decode."

Worth aligning the two paths before merge.

Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go Outdated
Comment thread sca/bom/buildinfo/technologies/yarn/yarn.go
@gauriy-tech gauriy-tech force-pushed the feature/XRAY-138688-add-yarn-support branch from f496cf0 to df3fcef Compare May 28, 2026 07:04
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