Skip to content

Commit 70747c7

Browse files
authored
Unlocked edit mode for workspace deployed job (#4193)
## Changes 1. Add a new env flag that controls the behavior of deployments from the Workspace. Currently, this flag controls only the edit mode of the job. In the next PRs, it will also enable saving the resource snapshots that are required for the UI->YAML sync 2. Add logic that sets job edit mode to Editable when the flag is enabled and deploy is running from the Workspace ## Why We need to unlock jobs to allow users to manually edit Workspace-deployed jobs and run the UI->YAML sync. This feature is not yet released; therefore, we need to use a flag to maintain both old and new behaviors. ## Tests Currently, only unit tests. It seems that running acceptance tests is not yet possible for DBR-specific functionality. One potential option is to skip the DBR check for the sake of testability, but the flag is more likely to be removed at some point and we will need to introduce DBR check again. Also I will manually check that the Workspace integration works as expected
1 parent 3c597d1 commit 70747c7

File tree

3 files changed

+127
-4
lines changed

3 files changed

+127
-4
lines changed

bundle/deploy/metadata/annotate_jobs.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package metadata
22

33
import (
44
"context"
5+
"strings"
56

67
"github.com/databricks/cli/bundle"
8+
"github.com/databricks/cli/bundle/env"
9+
"github.com/databricks/cli/libs/dbr"
710
"github.com/databricks/cli/libs/diag"
811
"github.com/databricks/databricks-sdk-go/service/jobs"
912
)
@@ -18,13 +21,21 @@ func (m *annotateJobs) Name() string {
1821
return "metadata.AnnotateJobs"
1922
}
2023

21-
func (m *annotateJobs) Apply(_ context.Context, b *bundle.Bundle) diag.Diagnostics {
24+
func (m *annotateJobs) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics {
2225
for _, job := range b.Config.Resources.Jobs {
2326
job.Deployment = &jobs.JobDeployment{
2427
Kind: jobs.JobDeploymentKindBundle,
2528
MetadataFilePath: metadataFilePath(b),
2629
}
27-
job.EditMode = jobs.JobEditModeUiLocked
30+
31+
isDatabricksWorkspace := dbr.RunsOnRuntime(ctx) && strings.HasPrefix(b.SyncRootPath, "/Workspace/")
32+
_, experimentalYamlSyncEnabled := env.ExperimentalYamlSync(ctx)
33+
if isDatabricksWorkspace && experimentalYamlSyncEnabled {
34+
job.EditMode = jobs.JobEditModeEditable
35+
} else {
36+
job.EditMode = jobs.JobEditModeUiLocked
37+
}
38+
2839
job.Format = jobs.FormatMultiTask
2940
}
3041

bundle/deploy/metadata/annotate_jobs_test.go

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"github.com/databricks/cli/bundle"
88
"github.com/databricks/cli/bundle/config"
99
"github.com/databricks/cli/bundle/config/resources"
10+
"github.com/databricks/cli/libs/dbr"
11+
"github.com/databricks/cli/libs/env"
1012
"github.com/databricks/databricks-sdk-go/service/jobs"
1113
"github.com/stretchr/testify/assert"
1214
"github.com/stretchr/testify/require"
@@ -35,7 +37,10 @@ func TestAnnotateJobsMutator(t *testing.T) {
3537
},
3638
}
3739

38-
diags := AnnotateJobs().Apply(context.Background(), b)
40+
ctx := context.Background()
41+
ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: false, Version: ""})
42+
43+
diags := AnnotateJobs().Apply(ctx, b)
3944
require.NoError(t, diags.Error())
4045

4146
assert.Equal(t,
@@ -68,6 +73,98 @@ func TestAnnotateJobsMutatorJobWithoutSettings(t *testing.T) {
6873
},
6974
}
7075

71-
diags := AnnotateJobs().Apply(context.Background(), b)
76+
ctx := context.Background()
77+
ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: false, Version: ""})
78+
79+
diags := AnnotateJobs().Apply(ctx, b)
80+
require.NoError(t, diags.Error())
81+
}
82+
83+
func TestAnnotateJobsWorkspaceWithFlag(t *testing.T) {
84+
b := &bundle.Bundle{
85+
SyncRootPath: "/Workspace/Users/user@example.com/project",
86+
Config: config.Root{
87+
Workspace: config.Workspace{
88+
StatePath: "/a/b/c",
89+
},
90+
Resources: config.Resources{
91+
Jobs: map[string]*resources.Job{
92+
"my-job": {
93+
JobSettings: jobs.JobSettings{
94+
Name: "My Job",
95+
},
96+
},
97+
},
98+
},
99+
},
100+
}
101+
102+
ctx := context.Background()
103+
ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: true, Version: "14.0"})
104+
ctx = env.Set(ctx, "DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC", "1")
105+
106+
diags := AnnotateJobs().Apply(ctx, b)
107+
require.NoError(t, diags.Error())
108+
109+
assert.Equal(t, jobs.JobEditModeEditable, b.Config.Resources.Jobs["my-job"].EditMode)
110+
assert.Equal(t, jobs.FormatMultiTask, b.Config.Resources.Jobs["my-job"].Format)
111+
}
112+
113+
func TestAnnotateJobsWorkspaceWithoutFlag(t *testing.T) {
114+
b := &bundle.Bundle{
115+
SyncRootPath: "/Workspace/Users/user@example.com/project",
116+
Config: config.Root{
117+
Workspace: config.Workspace{
118+
StatePath: "/a/b/c",
119+
},
120+
Resources: config.Resources{
121+
Jobs: map[string]*resources.Job{
122+
"my-job": {
123+
JobSettings: jobs.JobSettings{
124+
Name: "My Job",
125+
},
126+
},
127+
},
128+
},
129+
},
130+
}
131+
132+
ctx := context.Background()
133+
ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: true, Version: "14.0"})
134+
135+
diags := AnnotateJobs().Apply(ctx, b)
72136
require.NoError(t, diags.Error())
137+
138+
assert.Equal(t, jobs.JobEditModeUiLocked, b.Config.Resources.Jobs["my-job"].EditMode)
139+
assert.Equal(t, jobs.FormatMultiTask, b.Config.Resources.Jobs["my-job"].Format)
140+
}
141+
142+
func TestAnnotateJobsNonWorkspaceWithFlag(t *testing.T) {
143+
b := &bundle.Bundle{
144+
SyncRootPath: "/some/local/path",
145+
Config: config.Root{
146+
Workspace: config.Workspace{
147+
StatePath: "/a/b/c",
148+
},
149+
Resources: config.Resources{
150+
Jobs: map[string]*resources.Job{
151+
"my-job": {
152+
JobSettings: jobs.JobSettings{
153+
Name: "My Job",
154+
},
155+
},
156+
},
157+
},
158+
},
159+
}
160+
161+
ctx := context.Background()
162+
ctx = dbr.MockRuntime(ctx, dbr.Environment{IsDbr: false, Version: ""})
163+
ctx = env.Set(ctx, "DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC", "1")
164+
165+
diags := AnnotateJobs().Apply(ctx, b)
166+
require.NoError(t, diags.Error())
167+
168+
assert.Equal(t, jobs.JobEditModeUiLocked, b.Config.Resources.Jobs["my-job"].EditMode)
169+
assert.Equal(t, jobs.FormatMultiTask, b.Config.Resources.Jobs["my-job"].Format)
73170
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package env
2+
3+
import "context"
4+
5+
// experimentalYamlSyncVariable names the environment variable that holds the flag whether
6+
// experimental YAML sync is enabled.
7+
const experimentalYamlSyncVariable = "DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC"
8+
9+
// ExperimentalYamlSync returns the environment variable that holds the flag whether
10+
// experimental YAML sync is enabled.
11+
func ExperimentalYamlSync(ctx context.Context) (string, bool) {
12+
return get(ctx, []string{
13+
experimentalYamlSyncVariable,
14+
})
15+
}

0 commit comments

Comments
 (0)