Repository navigation
feat(release): vendor prebuilt runtimes on release branches only - #407
Merged
Merged
Conversation
Peefy
force-pushed
the
refactor/vendor-libs-release-branch-only
branch
2 times, most recently
from
October 13, 2026 12:57
d3f91ad to
c742aa7
Compare
go/lib/<platform>/ and wasm/kcl.wasm are ~370MB of compiled artifacts and ~89% of the tracked tree, and every one of them is reproducible from the kcl-lang/kcl release of the same version. They are now tracked on release/* branches and release tags only; development branches drop them and fetch them on demand, which takes a fresh clone from 394MB to 21MB. Same shape as wasmtime-go: an empty build/ directory on main plus a CI script that fills it in, with the artifacts committed onto the release. - hack/download-libs.sh fetches the platform's runtime from the matching kcl-lang/kcl release, cross-compiling the two iOS static archives from c/ since those have no published asset. Nine CI jobs now call it. - vendor-libs.yaml vendors everything onto a pushed release/* branch. It commits to the branch rather than force-updating a tag, because wasm-test.yaml publishes @kcl-lib/wasm to npm on a tag push and kcl.wasm is in that package's files: a workflow that rewrites the tag afterwards races the publish and silently ships a package with no runtime in it. - go/lib embeds the platform binary with //go:embed, which is a compile time dependency, so the six embed files take a !no_libembed opt-out and a new kcl_lib_noembed.go covers -tags no_libembed. install now rejects an empty CliLib with an actionable error instead of writing a zero-byte library that fails later at dlopen. Breaking for anyone building from a development branch: run hack/download-libs.sh, or build with -tags no_libembed to type-check. Release tags are unaffected. History is left alone on purpose -- filter-repo would strip the binaries from the existing v0.12.x tags. The dart-test windows-11-arm leg is commented out for now: it passed only because go/lib/windows-arm64/kcl.dll was committed here, and no kcl release publishes that asset yet. kcl-lang/kcl#2219 adds the target to that repo's release matrix; re-enable the leg once a release carrying it is out. Signed-off-by: Peefy <xpf6677@163.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Peefy
force-pushed
the
refactor/vendor-libs-release-branch-only
branch
from
October 13, 2026 13:12
c742aa7 to
db127fd
Compare
This was referenced Oct 13, 2026
Peefy
added a commit
that referenced
this pull request
Oct 16, 2026
Pushing release/v0.13.1 exposed three defects, all of which #407 shipped because the workflow had never actually executed. `Resolve versions` built the lib version as `v${branch#release/}`, but the branch already reads `release/v0.13.1`, so the expansion yielded `vv0.13.1` and the guard rejected it against KCL_VERSION. Every push failed at the first step: lib version: vv0.13.1 SDK KCL_VERSION: v0.13.1 ##[error]go/install/install.go KCL_VERSION (v0.13.1) does not match the branch version (vv0.13.1). `download-artifact` without a `name` downloads each artifact into its own staged/<artifact-name>/ subdirectory, so the merge step looked for staged/go/lib and would have failed on `test -d`. merge-multiple puts both artifacts into one repository-rooted tree, which is what the step assumes. The iOS upload listed the two archives as bare paths, and upload-artifact roots an archive at the least common ancestor of what it uploads — here go/lib, so the archive would have contained ios-arm64/libkcl.a rather than go/lib/ios-arm64/libkcl.a. Anchoring the search at the repository root with `path: .` + `include:` keeps both artifacts rooted identically regardless of which platforms a job builds. Signed-off-by: Peefy <xpf6677@163.com>
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.
Fixes #207
Summary
go/lib/<platform>/andwasm/kcl.wasmare ~370MB of compiled artifactsand ~89% of the tracked tree, and every one of them is reproducible from
the kcl-lang/kcl release of the same
version. They are now tracked on
release/*branches and release tagsonly; development branches drop them and fetch them on demand.
A fresh clone goes from 394MB to 21MB.
Same shape as wasmtime-go,
which keeps its
build/directory empty onmainand fills it in from CI,with the artifacts committed onto the release. The mechanism is not new
here either —
swift-release.yamlalreadygit add -fs the universallibkcl_lib_c.aonto its tag.What changes for consumers
hack/download-libs.shgo build -tags no_libembed ./...Only the development-branch row is a behaviour change.
How it works
hack/download-libs.shpulls one platform's runtime from the matchingkcl-lang/kcl release. The two iOS static archives are cross-compiled from
this repo's
c/crate instead, because they arekcl-lib-cand have nopublished asset. Nine CI jobs call it.
vendor-libs.yamlruns on a push torelease/v*and commits everyartifact onto that branch.
//go:embedis a compile-time dependency, so the sixkcl_lib_*.gofiles (Go's implicit
_GOOS_GOARCHfilename constraint picks one) take a!no_libembedopt-out, andkcl_lib_noembed.gocovers-tags no_libembed.installnow rejects an emptyCliLibwith an actionable error rather thanwriting a zero-byte library that fails later at
dlopen.Why a branch, not a force-moved tag
swift-release.yamlforce-updates its tag after the fact. That does not workhere:
wasm-test.yamlpublishes@kcl-lib/wasmto npm on a tag push, andkcl.wasmis in that package'sfilesarray. A workflow that rewrites thetag afterwards races the publish, and the failure is silent — npm publishes
successfully with no runtime inside it. On a release branch the binaries are
committed before the tag exists, so there is no ordering to get wrong.
Consequence: release tags must be cut from
release/*, not frommain.The procedure is in
docs/lib-vendoring.md.windows/arm64is not vendored yetvendor-libs.yamlderives the version from the branch name and downloadskcl-lib-<tag>-windows-arm64.zip, which no kcl release has shipped.kcl-lang/kcl#2219 adds that target
to the release matrix, but only the first kcl tag cut after it lands carries the
asset — so vendoring that one platform fails until then.
That also broke
dart-test.yaml'swindows-11-armleg, which used to passonly because
go/lib/windows-arm64/kcl.dllwas committed here. The leg is nowcommented out with a pointer back to kcl#2219; re-enable it once a release
carrying the asset is out and
KCL_VERSIONpoints at it. No other workflowbuilds for windows/arm64, so this is the only coverage affected.
The existing v0.12.x tags still carry their binaries and are untouched. History
is deliberately not rewritten —
git filter-repowould strip them from thosetags and break anyone pinning one.
Test plan
go build ./...on darwin/arm64 without the binary fails with theexpected
//go:embedmessage (unchanged, and self-explanatory)go build -tags no_libembed ./...andgo vetpass on all sixGOOS/GOARCH pairs
-tags no_libembed+InstallKclreturns the actionable error andwrites no library file
go test ./...passes with the binaries presenthack/download-libs.shexercised end to end against stubbed archives:download, unpack, stage, unknown platform, missing asset,
--wasm,bash 3.2 empty-array path, and the Windows zip fallback
working-directoryshellcheck -S styleclean; parses under the bash 3.2 that ships withmacOS
legs, the 4 AST-diff bindings and the wasm/npm job — the local sandbox
could not reach
release-assets.githubusercontent.com, so these runs arewhat actually exercise the download
Follow-ups this does not do
wasm/kcl.wasmis now a network fetch on every wasm CI run, and the wasmtests carry hardcoded expectations about what that specific build can and
cannot do (
wasm/tests/consistency.test.ts,generate_api.test.ts). Theypass today because the version is pinned by
KCL_VERSION; if that pin isever loosened to "latest", those skip lists will start failing. Worth a
follow-up issue.
🤖 Generated with Claude Code