fix(manifest): auto-manifest reads the Conda file it actually detected - #1562
Merged
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 1 commit intoSep 25, 2026
Merged
Conversation
Detection accepted both environment.yml and environment.yaml but only returned a boolean, so the filename was dropped. The generator then read environment.yml unconditionally and failed on any repo using the .yaml spelling, unless a socket.json infile override was in place. Detection now reports which file it found and the generator reads that one. socket.json still wins when it sets infile. Two more things in the same path: - The generated requirements.txt was written relative to the process cwd instead of the target dir, so `socket manifest auto <dir>` and `socket scan create <org> <dir>` dropped it outside the scanned tree. It now resolves against the target dir, which is what the --out flag already documents. - Conda was the one auto-manifest ecosystem with no fail-closed check. Gradle, Maven and sbt abort the run when their generator fails; Conda just set exit 1 and carried on, so a scan uploaded without the pip block and the CLI still exited non-zero. Conda now aborts like the others.
Jeppe Fredsgaard Blaabjerg (jfblaa)
requested review from
John-David Dalton (jdalton) and
Martin Torp (mtorp)
September 25, 2026 08:43
Contributor
Author
|
I am not familiar with Conda, so I am deferring to Claude on this one. |
Martin Torp (mtorp)
approved these changes
Sep 25, 2026
Martin Torp (mtorp)
left a comment
Contributor
There was a problem hiding this comment.
Nice! Thank you Jeppe Fredsgaard Blaabjerg (@jfblaa) 🙏
Jeppe Fredsgaard Blaabjerg (jfblaa)
merged commit Sep 25, 2026
79b34a0
into
v1.x
15 of 17 checks passed
Jeppe Fredsgaard Blaabjerg (jfblaa)
deleted the
jfblaa/conda-auto-manifest-yaml
branch
September 25, 2026 09:40
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.
[agent] Takes over Martin Torp (@mtorp)'s draft in #1561, rebased onto v1.x after the 1.1.179 release. The code is his; I rebased, reviewed and verified it end to end.
The bug
--auto-manifestdetects a Conda project by looking for eitherenvironment.ymlorenvironment.yaml, butdetectManifestActions()only returnedconda: trueand threw the filename away.generateAutoManifest()then readenvironment.ymlunconditionally.On a repo whose Conda file is
environment.yaml, every run does this:The scan still uploads, the CLI still exits 1. You get a completed scan and a failed CI job on every run, and the packages in the file's
pip:block never reach the scan, because the conversion that produces them is the step that failed.The known workaround is a
socket.jsonwithdefaults.manifest.conda.infilenaming the real file, which works because that override is the one path that skips the hardcoded default.To be clear on a question that came up in triage: switching to
--dynamic-sbom-inferenceis not a workaround. That flag only covers Gradle, sbt and Maven. Conda and Bazel are reachable only through--auto-manifest, which remains the supported flag for them and for single-root JVM facts and the reachability sidecar.The fix
Detection reports which file it found (
GeneratableManifests.condaFile) and the generator reads that one. Asocket.jsoninfilestill wins when set.Two more bugs in the same code path
The generated
requirements.txtlanded in the wrong directory. It was written relative toprocess.cwd()rather than the target dir, sosocket manifest auto <dir>andsocket scan create <org> <dir>dropped it outside the tree being scanned and the scan never picked it up. Invisible when you run from the repo root, which is what CI does.Conda was the one auto-manifest ecosystem with no fail-closed check. Gradle, Maven and sbt abort the run when their generator fails (#1392); Conda just set exit 1 and carried on. That is what produces the "completed scan + failed CI job" pair, and the scan that uploads is missing the
pip:packages. Conda now callsabortManifestRunIfFailedlike the others.That last one is a deliberate behavior change and the one thing worth a second opinion. Before: scan uploads, exit 1. After: the run stops before upload. It matches the policy the other ecosystems already follow, on the grounds that a partial SBOM silently under-reports dependencies. Happy to drop it if the team would rather warn and continue.
socket manifest condaon its own also falls back to.yamlnow, so the two commands agree on what counts as a Conda file.Verification
End-to-end against a real org, on a directory with an
environment.yaml(with apip:block) plus apackage.json, so the scan has something else to upload — the customer's situation:npm/lodashnpm/lodash,pypi/requests,pypi/flask,pypi/certifi,pypi/charset-normalizer,pypi/idna,pypi/urllib3So before the fix the scan uploads with every Python dependency silently missing, and CI goes red anyway. After, the full transitive PyPI tree resolves and the run is green.
Also verified:
.ymlrepos unchanged;socket.jsoninfilestill wins;requirements.txtlands in the target dir rather than the invoking cwd; a Conda generator failure now aborts before upload;socket manifest condaworks on a.yamlrepo with no flags, where it previously needed--file.The new unit tests are genuine regression tests — reverting the four source files and keeping the tests fails 7 of them, including
.yamldetection and abort-on-failure.check:tscpasses, lint passes on the changed files,src/commands/manifest503 passed,src/commands/scan274 passed.Confidence
High on the two clear bugs (wrong filename, wrong output dir): small, well-tested, root cause understood, verified end to end against a real scan.
Medium on the fail-closed change, not because the code is doubtful but because it is a judgement call about behavior. It makes a currently-uploading run stop. That is right when the missing
pip:block would under-report dependencies, but any team relying on the scan landing despite a broken Conda file will see a new hard failure. Consistency with Gradle/Maven/sbt argues for it; it is the piece to say no to if anyone disagrees.One pre-existing issue I hit and deliberately left alone: a malformed Conda file produces an empty
requirements.txtand exits 0, because the converter is a line scanner for thepip:block rather than a YAML parser. Out of scope here, worth its own ticket.Release
No hand-written version bump. Entries go under
## [Unreleased]for the publish workflow to promote. The draft had hand-written a## [1.1.179]heading; the release workflow has since written the real one, so that was dropped in the rebase.🤖 Generated with Claude Code
Note
Medium Risk
Changes scan-create behavior when Conda manifest generation fails (upload may stop instead of completing with a partial SBOM) and touches manifest output paths used during uploads.
Overview
Fixes Conda handling in
--auto-manifestandsocket manifest condaso the CLI uses the environment file it actually finds, not a hardcodedenvironment.yml.Detection now exposes
condaFile(environment.ymlorenvironment.yaml, preferring.ymlwhen both exist) viafindCondaFile, and auto-manifest passes that path into the generator—socket.jsoninfilestill overrides. The standalonemanifest condacommand uses the same fallback when--fileis omitted.Generated
requirements.txtis written withpath.resolve(cwd, out)so scans targeting a subdirectory pick up the file even when the CLI is invoked from elsewhere.Conda failures now abort auto-manifest through
abortManifestRunIfFailed, matching Gradle/Maven/sbt: a failed Conda step no longer continues to upload a scan missingpip:dependencies.Reviewed by Cursor Bugbot for commit f76bf24. Configure here.