fix(dsl): port corepack PM version pin to Python DSL; fail-fast on legacy pipeline(step) form#134
Merged
markovejnovic merged 1 commit intoJun 10, 2026
Conversation
…eline(step) Two parity/sharp-edge fixes in the Python pipeline DSL. js-corepack-pin-parity-1 — the corepack package-manager version pin shipped in the TypeScript DSL only. Python's DetectedToolchain had no pm_version, its detect_from_package_json never extracted the @-suffix of `packageManager`, and _pm_bootstrap always emitted the bare `corepack enable pnpm` / `corepack enable` with a CacheForever bootstrap step. That diverged the emitted IR and cache keys between the two SDKs for any project that pins its package manager. Port PR #86: - _detect.py: DetectedToolchain gains `pm_version`; detect_from_package_json captures the version segment when a known PM has one; detect() propagates it. - _js.py: _pm_bootstrap takes the detected version and emits `corepack enable pnpm && corepack install -g pnpm@<v>` (and the yarn form) when present; the bootstrap step's cache switches to CacheOnChange on package.json so the pin is rebuilt when it changes (CacheForever otherwise). Mirrors js.ts/detect.ts exactly. New Python tests assert the pinned command and the package.json-watch cache. cross_sdk_cache_test.rs gains a JS-toolchain pipeline with a pinned `packageManager`, proving the Python and TypeScript IR/cache keys stay identical (the invariant that previously had no JS coverage). py-pipeline-migration-error-1 — the polymorphic hm.pipeline() dispatcher only recognized a list/tuple of leaves; the pre-CLI-9 `pipeline(step)` form fell through to the decorator and blew up far downstream with a cryptic `AttributeError: 'function' object has no attribute 'get'`, while `pipeline(a, b)` leaked the decorator's TypeError. Guard the dispatcher: when the positionals are all Step objects, raise a doctrine-shaped TypeError that points at the observed shape and states the fix (wrap the leaves in a list). Regression tests cover both the single- and multi-leaf legacy forms.
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.
Summary
Two parity / sharp-edge fixes in the Python pipeline DSL, bringing it in line with the TypeScript DSL and giving a doctrine-shaped error for a legacy call form.
packageManagerversion pin shipped in the TypeScript DSL only.DetectedToolchainnow carriespm_version,detect_from_package_jsoncaptures the@-suffix of a known PM, and_pm_bootstrapemitscorepack enable pnpm && corepack install -g pnpm@<v>(and the yarn form) when a version is present. The bootstrap step's cache switches toCacheOnChange(package.json)when a pin is present so the snapshot rebuilds when the pin changes (CacheForeverotherwise). This keeps the emitted IR and cache keys identical between the two SDKs for any project that pins its package manager.pipeline(step)form: the polymorphichm.pipeline()dispatcher only recognized a list/tuple of leaves. The pre-CLI-9pipeline(step)/pipeline(a, b)forms fell through to the decorator and blew up far downstream with a crypticAttributeError. The dispatcher now guards on all-Steppositionals and raises a doctrine-shapedTypeErrorthat names the observed shape and states the fix (wrap leaves in a list).Findings addressed
js-corepack-pin-parity-1py-pipeline-migration-error-1Verification
PR diff vs
origin/mainis exactly the focused fix: 7 files (3 source, 4 test), +302 / -17.uv run pytest tests/test_detect.py tests/test_js.py tests/test_pipeline.py -q(incrates/hm-dsl-engine/harmont-py)cargo test -p hm-dsl-engine --test cross_sdk_cache_testcross_sdk_cache_keys_match_js_corepack_pinproving Python/TS IR + cache keys stay identical for a pinnedpackageManagerThe new cross-SDK test closes the invariant gap that previously had no JS coverage.
Judge verdict
Approved. No blocking issues.
Generated by the Harmont release-readiness workflow (automated; needs human review before merge). 🤖