Skip to content

Commit 3241ae2

Browse files
committed
feat: move cli-compat manifest to CLI repo with 3-tier fallback
- Embed cli-compat.json in the CLI binary with build-time fetch - Resolve AppKit and Agent Skills versions from the manifest - Add 1h local cache and retry for runtime manifest fetches - Show default AppKit version in --version flag help - Print resolved skills version during aitools install Co-authored-by: Isaac
1 parent 521074c commit 3241ae2

19 files changed

Lines changed: 1058 additions & 46 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
name: bump-cli-compat
3+
description: "Bump cli-compat.json with new AppKit and Agent Skills versions, then create a PR. Use when the user says 'bump cli-compat', 'update cli-compat', 'bump compatibility manifest', 'new appkit release cli-compat', or wants to update the CLI compatibility manifest after an AppKit or Agent Skills release."
4+
user-invocable: true
5+
allowed-tools: Read, Edit, Write, Bash, Glob, Grep, AskUserQuestion
6+
---
7+
8+
# Bump CLI Compatibility Manifest
9+
10+
Updates `internal/build/cli-compat.json` with new AppKit and Agent Skills versions, validates the result, and creates a PR.
11+
12+
## Arguments
13+
14+
Parse the user's input for optional version arguments:
15+
16+
- `--appkit <version>` or first positional arg → AppKit version (e.g. `0.28.0`)
17+
- `--skills <version>` or second positional arg → Agent Skills version (e.g. `0.1.6`)
18+
- No args → auto-detect latest versions from GitHub tags
19+
20+
Versions should be provided **without** the `v` prefix (e.g. `0.28.0`, not `v0.28.0`). If provided with the prefix, strip it.
21+
22+
## Workflow
23+
24+
### Step 1: Resolve versions
25+
26+
If both `appkit` and `skills` versions were provided as arguments, skip to Step 2.
27+
28+
Otherwise, fetch the latest tags from GitHub:
29+
30+
```bash
31+
# Latest appkit version (strip leading 'v')
32+
gh api repos/databricks/appkit/tags --jq '.[0].name' | sed 's/^v//'
33+
34+
# Latest skills version (strip leading 'v')
35+
gh api repos/databricks/databricks-agent-skills/tags --jq '.[0].name' | sed 's/^v//'
36+
```
37+
38+
Show the resolved versions to the user and ask:
39+
40+
> The latest versions are:
41+
> - AppKit: `{appkit_version}`
42+
> - Agent Skills: `{skills_version}`
43+
>
44+
> Have these versions been evaluated (evals passed with no regressions)?
45+
46+
**Do NOT proceed until the user confirms.** If the user says no or wants different versions, ask them to provide the correct versions.
47+
48+
### Step 2: Validate tags exist
49+
50+
Verify that the corresponding Git tags exist on GitHub:
51+
52+
```bash
53+
gh api repos/databricks/appkit/git/ref/tags/v{appkit_version} --jq '.ref' 2>&1
54+
gh api repos/databricks/databricks-agent-skills/git/ref/tags/v{skills_version} --jq '.ref' 2>&1
55+
```
56+
57+
If either tag doesn't exist, report the error and stop.
58+
59+
### Step 3: Read current manifest
60+
61+
Read `internal/build/cli-compat.json`. Note the current versions and the list of versioned entries.
62+
63+
### Step 4: Update the manifest
64+
65+
Update **all entries** (both `next` and all versioned CLI entries) to the new appkit and skills versions. This is the "no template changes" scenario — a simple search & replace.
66+
67+
Write the updated `internal/build/cli-compat.json`.
68+
69+
### Step 5: Validate
70+
71+
Run the Go tests to ensure the manifest is well-formed:
72+
73+
```bash
74+
go test ./libs/depversions/... -run TestEmbeddedManifest -v
75+
```
76+
77+
If validation fails, show the errors and fix them before proceeding.
78+
79+
### Step 6: Create branch, commit, and PR
80+
81+
```bash
82+
# Create a new branch from the current branch (or main)
83+
git checkout -b bump-cli-compat-appkit-{appkit_version}-skills-{skills_version}
84+
85+
# Stage and commit
86+
git add internal/build/cli-compat.json
87+
git commit -s -m "chore: bump cli-compat to appkit {appkit_version}, skills {skills_version}"
88+
89+
# Push and create PR
90+
git push -u origin HEAD
91+
gh pr create \
92+
--title "chore: bump cli-compat to appkit {appkit_version}, skills {skills_version}" \
93+
--body "$(cat <<'EOF'
94+
## Summary
95+
Bump `cli-compat.json` to use:
96+
- AppKit `{appkit_version}`
97+
- Agent Skills `{skills_version}`
98+
99+
## Checklist
100+
- [ ] Evals passed with no regressions
101+
- [ ] `go test ./libs/depversions/... -run TestEmbeddedManifest` passes
102+
EOF
103+
)"
104+
```
105+
106+
Show the PR URL to the user when done.
107+
108+
## Examples
109+
110+
### Example: With explicit versions
111+
```
112+
/bump-cli-compat 0.28.0 0.1.6
113+
```
114+
Validates tags exist, updates manifest, creates PR.
115+
116+
### Example: Auto-detect latest
117+
```
118+
/bump-cli-compat
119+
```
120+
Fetches latest tags, asks for eval confirmation, then updates and creates PR.
121+
122+
### Example: With flags
123+
```
124+
/bump-cli-compat --appkit 0.28.0 --skills 0.1.6
125+
```
126+
Same as positional args.

.github/OWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,9 @@
5959
# Internal
6060
/internal/ team:platform
6161

62+
# CLI compatibility manifest
63+
/internal/build/cli-compat.json team:eng-apps-devex team:platform
64+
/libs/depversions/ team:eng-apps-devex team:platform
65+
6266
# Experimental
6367
/experimental/aitools/ team:eng-apps-devex @lennartkats-db

cmd/apps/init.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/databricks/cli/libs/apps/prompt"
2626
"github.com/databricks/cli/libs/cmdctx"
2727
"github.com/databricks/cli/libs/cmdio"
28+
"github.com/databricks/cli/libs/depversions"
2829
"github.com/databricks/cli/libs/env"
2930
"github.com/databricks/cli/libs/git"
3031
"github.com/databricks/cli/libs/log"
@@ -38,7 +39,6 @@ const (
3839
appkitTemplateDir = "template"
3940
appkitDefaultBranch = "main"
4041
appkitTemplateTagPfx = "template-v"
41-
appkitDefaultVersion = "template-v0.24.0"
4242
defaultProfile = "DEFAULT"
4343
)
4444

@@ -169,7 +169,11 @@ Environment variables:
169169

170170
cmd.Flags().StringVar(&templatePath, "template", "", "Template path (local directory or GitHub URL)")
171171
cmd.Flags().StringVar(&branch, "branch", "", "Git branch or tag (for GitHub templates, mutually exclusive with --version)")
172-
cmd.Flags().StringVar(&version, "version", "", fmt.Sprintf("AppKit version to use (default: %s, use 'latest' for main branch)", appkitDefaultVersion))
172+
versionDesc := "AppKit version to use (use 'latest' for main branch)"
173+
if v := depversions.EmbeddedDefaultAppKitVersion(); v != "" {
174+
versionDesc = fmt.Sprintf("AppKit version to use (default: %s, use 'latest' for main branch)", v)
175+
}
176+
cmd.Flags().StringVar(&version, "version", "", versionDesc)
173177
cmd.Flags().StringVar(&name, "name", "", "Project name (prompts if not provided)")
174178
cmd.Flags().StringVar(&warehouseID, "warehouse-id", "", "SQL warehouse ID")
175179
_ = cmd.Flags().MarkDeprecated("warehouse-id", "use --set <plugin>.sql-warehouse.id=<value> instead")
@@ -783,8 +787,12 @@ func runCreate(ctx context.Context, opts createOptions) error {
783787
case opts.version != "":
784788
gitRef = normalizeVersion(opts.version)
785789
default:
786-
// Default: use pinned version
787-
gitRef = appkitDefaultVersion
790+
appkitVersion, err := depversions.ResolveAppKitVersion(ctx)
791+
if err != nil {
792+
return fmt.Errorf("could not resolve AppKit template version: %w. Use --version to specify a version manually", err)
793+
}
794+
gitRef = normalizeVersion(appkitVersion)
795+
cmdio.LogString(ctx, "Using AppKit template version "+appkitVersion)
788796
}
789797
templateSrc = appkitRepoURL
790798
}

cmd/apps/init_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ func TestNormalizeVersion(t *testing.T) {
443443
{"", ""},
444444
{"main", "main"},
445445
{"feat/something", "feat/something"},
446-
{appkitDefaultVersion, appkitDefaultVersion},
446+
{"template-v0.24.0", "template-v0.24.0"},
447447
}
448448

449449
for _, tt := range tests {

cmd/apps/manifest.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path/filepath"
1010

1111
"github.com/databricks/cli/libs/apps/manifest"
12+
"github.com/databricks/cli/libs/depversions"
1213
"github.com/databricks/cli/libs/env"
1314
"github.com/spf13/cobra"
1415
)
@@ -27,7 +28,11 @@ func runManifestOnly(ctx context.Context, templatePath, branch, version string)
2728
case version != "":
2829
gitRef = normalizeVersion(version)
2930
default:
30-
gitRef = appkitDefaultVersion
31+
appkitVersion, err := depversions.ResolveAppKitVersion(ctx)
32+
if err != nil {
33+
return fmt.Errorf("could not resolve AppKit template version: %w. Use --version to specify a version manually", err)
34+
}
35+
gitRef = normalizeVersion(appkitVersion)
3136
}
3237
templateSrc = appkitRepoURL
3338
}

experimental/aitools/cmd/list.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func newListCmd() *cobra.Command {
4848
func defaultListSkills(cmd *cobra.Command, scope string) error {
4949
ctx := cmd.Context()
5050

51-
ref := installer.GetSkillsRef(ctx)
51+
ref, err := installer.GetSkillsRef(ctx)
52+
if err != nil {
53+
return err
54+
}
5255

5356
src := &installer.GitHubManifestSource{}
5457
manifest, err := src.FetchManifest(ctx, ref)

experimental/aitools/cmd/version.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/databricks/cli/experimental/aitools/lib/installer"
99
"github.com/databricks/cli/libs/cmdio"
10+
"github.com/databricks/cli/libs/log"
1011
"github.com/spf13/cobra"
1112
)
1213

@@ -44,7 +45,10 @@ func newVersionCmd() *cobra.Command {
4445
return nil
4546
}
4647

47-
latestRef := installer.GetSkillsRef(ctx)
48+
latestRef, err := installer.GetSkillsRef(ctx)
49+
if err != nil {
50+
log.Debugf(ctx, "could not resolve skills version: %v", err)
51+
}
4852
bothScopes := globalState != nil && projectState != nil
4953

5054
cmdio.LogString(ctx, "Databricks AI Tools:")

experimental/aitools/lib/installer/SKILLS_VERSION

Lines changed: 0 additions & 1 deletion
This file was deleted.

experimental/aitools/lib/installer/installer.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/databricks/cli/experimental/aitools/lib/agents"
1818
"github.com/databricks/cli/internal/build"
1919
"github.com/databricks/cli/libs/cmdio"
20+
"github.com/databricks/cli/libs/depversions"
2021
"github.com/databricks/cli/libs/env"
2122
"github.com/databricks/cli/libs/log"
2223
"github.com/fatih/color"
@@ -33,13 +34,17 @@ const (
3334
// It is a package-level var so tests can replace it with a mock.
3435
var fetchFileFn = fetchSkillFile
3536

36-
// GetSkillsRef returns the skills repo ref to use. If DATABRICKS_SKILLS_REF
37-
// is set, it returns that value; otherwise it returns the default ref.
38-
func GetSkillsRef(ctx context.Context) string {
37+
// GetSkillsRef returns the skills repo ref to use.
38+
// Resolution order: DATABRICKS_SKILLS_REF env var → compatibility manifest → error.
39+
func GetSkillsRef(ctx context.Context) (string, error) {
3940
if ref := env.Get(ctx, "DATABRICKS_SKILLS_REF"); ref != "" {
40-
return ref
41+
return ref, nil
4142
}
42-
return defaultSkillsRepoRef
43+
v, err := depversions.ResolveAgentSkillsVersion(ctx)
44+
if err != nil {
45+
return "", fmt.Errorf("could not resolve skills version: %w", err)
46+
}
47+
return "v" + v, nil
4348
}
4449

4550
// Manifest describes the skills manifest fetched from the skills repo.
@@ -93,7 +98,12 @@ func fetchSkillFile(ctx context.Context, ref, skillName, filePath string) ([]byt
9398
// This is the core installation function. Callers are responsible for agent detection,
9499
// prompting, and printing the "Installing..." header.
95100
func InstallSkillsForAgents(ctx context.Context, src ManifestSource, targetAgents []*agents.Agent, opts InstallOptions) error {
96-
ref := GetSkillsRef(ctx)
101+
ref, err := GetSkillsRef(ctx)
102+
if err != nil {
103+
return err
104+
}
105+
tag := strings.TrimPrefix(ref, "v")
106+
cmdio.LogString(ctx, "Using skills version "+tag)
97107
manifest, err := src.FetchManifest(ctx, ref)
98108
if err != nil {
99109
return err
@@ -194,12 +204,11 @@ func InstallSkillsForAgents(ctx context.Context, src ManifestSource, targetAgent
194204
return err
195205
}
196206

197-
tag := strings.TrimPrefix(ref, "v")
198207
noun := "skills"
199208
if len(targetSkills) == 1 {
200209
noun = "skill"
201210
}
202-
cmdio.LogString(ctx, fmt.Sprintf("Installed %d %s (v%s).", len(targetSkills), noun, tag))
211+
cmdio.LogString(ctx, fmt.Sprintf("Installed %d %s.", len(targetSkills), noun))
203212
return nil
204213
}
205214

0 commit comments

Comments
 (0)