Skip to content

feat: resolve AppKit template version from compatibility manifest#5139

Open
pkosiec wants to merge 10 commits intomainfrom
pkosiec/appkit-version-pinning
Open

feat: resolve AppKit template version from compatibility manifest#5139
pkosiec wants to merge 10 commits intomainfrom
pkosiec/appkit-version-pinning

Conversation

@pkosiec
Copy link
Copy Markdown
Member

@pkosiec pkosiec commented Apr 30, 2026

Summary

Decouples AppKit template and Agent Skills version pinning from CLI releases. Instead of hardcoded versions that require manual PRs to bump, both are now resolved from a compatibility manifest hosted in the AppKit repo.

Before

  • Hardcoded template-v0.24.0 in CLI source; every bump required a CLI PR
  • Skills version pinned via SKILLS_VERSION file in the installer
  • No way to deliver version updates to existing CLI releases

After

  • Manifest-driven: cli-compat.json in the AppKit repo maps CLI versions → AppKit + Skills versions
  • Resolution chain: 1h local cache → remote fetch (2 retries, 300ms backoff) → build-time embedded entry → error with --version hint
  • Build-time pinning: goreleaser runs go run ./internal/pindepversions --version {{ .Version }} to embed the resolved entry
  • --version / --branch flags and DATABRICKS_SKILLS_REF env var still override
  • DATABRICKS_CACHE_ENABLED=false bypasses the cache

Design Doc

https://docs.google.com/document/d/1qOchR4vnYAo_5a_oHyFdIdySBayzRc5bBmVZ0u-Mvus/edit?tab=t.0

Test plan

  • Unit tests: manifest parsing, semver resolution, caching, retries, resolveEntry fallback
  • Manual: apps init / aitools install print resolved versions
  • Manual: apps init --debug shows fetch URL and cache behavior
  • Manual: apps init --version X overrides manifest

Testing locally

The manifest doesn't exist on main yet (pending appkit#333). Temporarily change the URL:

// libs/depversions/depversions.go line 22
manifestURL = "https://raw.githubusercontent.com/databricks/appkit/pkosiec/appkit-version-pinning/cli-compat.json"
export GOPROXY=go-proxy.dev.databricks.com
make build

pkosiec added 5 commits April 29, 2026 15:46
Replace the hardcoded appkitDefaultVersion with a compatibility manifest
that maps CLI versions to compatible AppKit template and Agent Skills
versions.

At runtime, apps init fetches the latest manifest from the AppKit GitHub
repo. If the fetch fails, it falls back to an embedded copy. The
resolution algorithm finds the nearest compatible version for the running
CLI (exact match, nearest lower, or "next" for newer CLIs).

The resolved skills version is passed to the skills installer via the
DATABRICKS_SKILLS_REF context variable, ensuring apps init recommends
a manifest-compatible skills version.

Also add a Makefile target (fetch-compat-manifest) for CI to fetch the
latest manifest before building the CLI binary.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
- Add io.LimitReader (1MB cap) to fetchRemote to guard against
  corrupted or oversized HTTP responses.
- Rewrite TestFetchManifest_RemoteSuccess and
  TestFetchManifest_FallbackToEmbedded using a roundTripFunc
  transport so requests actually reach the httptest server.
  Previously, manifestURL being a const meant the test server
  was never called and both tests passed only via the embedded
  fallback.

Co-authored-by: Isaac
- Fix Resolve docstring to match actual nearest-lower behavior
- Strengthen TestResolve_NewerThanAll with distinct next values
- Fix import ordering in init.go
- Use manifest resolution in manifest.go (was hardcoded)
- Validate semver keys in parseManifest
- Reduce manifest fetch timeout from 5s to 3s
- Fix redirectToServer doc comment
- Add missing Skills assertions in tests
- Add test for invalid JSON fallback from remote

Co-authored-by: Isaac
…fest

- Cache fetched manifest locally for 1h using libs/cache
- Add retry logic (2 retries, 300ms backoff) for runtime fetches
- Fetch latest manifest during build (Makefile + goreleaser)
- Replace checked-in manifest with {} placeholder
- Remove hardcoded appkitDefaultVersion fallback; manifest is sole source of truth
- Print resolved template and skills versions to user during apps init
- Remove version from skills post-install message (shown upfront instead)

Co-authored-by: Isaac
- Move libs/apps/compat/ → libs/depversions/ (cross-cutting, not apps-only)
- Rename Entry.Appkit → Entry.AppKit
- Embed resolved entry in internal/build/dep_versions.json instead of full manifest
- Add build-time pin tool (internal/pindepversions) for goreleaser
- Add ResolveAppKitVersion/ResolveAgentSkillsVersion convenience helpers
- Remove cli-compat.json and fetch-compat-manifest Makefile target
- Resolve() returns lowest entry (not "next") for old CLI versions

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 15:10 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 15:10 — with GitHub Actions Inactive
- Rename Entry.Skills → Entry.AgentSkills (JSON tag stays "skills")
- Rename DepVersions.Skills → DepVersions.AgentSkills
- Rename compat.go → depversions.go to match package name
- Verified pin tool handles missing manifest gracefully (404 → warning, placeholder unchanged)

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 15:20 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 15:20 — with GitHub Actions Inactive
Use build-time pinned version from dep_versions.json in the --version
flag help text. Release builds show the actual default; dev builds show
a generic message since no version is pinned.

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:12 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:12 — with GitHub Actions Inactive
- Replace sort.Slice with slices.SortFunc (forbidigo)
- Check w.Write error returns in test handlers (errcheck)

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:16 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:16 — with GitHub Actions Inactive
… fallback

- GetSkillsRef now resolves from compatibility manifest instead of
  falling back to hardcoded SKILLS_VERSION file
- Delete SKILLS_VERSION and version.go — manifest is sole source of truth
- Remove DATABRICKS_SKILLS_REF env var override from apps init
  (GetSkillsRef handles manifest resolution internally)
- Update all callers to handle GetSkillsRef error return
- Tests use t.Setenv("DATABRICKS_SKILLS_REF", ...) to bypass manifest

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:25 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:25 — with GitHub Actions Inactive
Show "Using skills version X.Y.Z" before installation so the user
knows which version was resolved from the compatibility manifest.

Co-authored-by: Isaac
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:35 — with GitHub Actions Inactive
@pkosiec pkosiec temporarily deployed to test-trigger-is April 30, 2026 16:35 — with GitHub Actions Inactive
@pkosiec pkosiec marked this pull request as ready for review April 30, 2026 16:39
@github-actions
Copy link
Copy Markdown

Approval status: pending

/cmd/apps/ - needs approval

Files: cmd/apps/init.go, cmd/apps/init_test.go, cmd/apps/manifest.go
Suggested: @MarioCadenas
Also eligible: @arsenyinfo, @keugenek, @calvarjorge, @fjakobs, @jamesbroadhead, @Shridhad, @atilafassina, @igrekun, @pffigueiredo, @ditadi

/experimental/aitools/ - needs approval

9 files changed
Suggested: @MarioCadenas
Also eligible: @arsenyinfo, @keugenek, @calvarjorge, @fjakobs, @jamesbroadhead, @Shridhad, @atilafassina, @igrekun, @pffigueiredo, @ditadi, @lennartkats-db

/internal/ - needs approval

Files: internal/build/dep_versions.go, internal/build/dep_versions.json, internal/pindepversions/main.go
Suggested: @simonfaltum
Also eligible: @renaudhartert-db, @hectorcast-db, @parthban-db, @tanmay-db, @Divyansh-db, @tejaskochar-db, @mihaimitrea-db, @chrisst, @rauchy

General files (require maintainer)

Files: .goreleaser.yaml, libs/depversions/depversions.go, libs/depversions/depversions_test.go
Based on git history:

  • @pietern -- recent work in experimental/aitools/lib/installer/, internal/build/, cmd/apps/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db) can approve all areas.
See OWNERS for ownership rules.

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.

1 participant