Skip to content

Commit 621ef79

Browse files
authored
batches: make published field optional (#538)
The first part of sourcegraph/sourcegraph#18277.
1 parent 0222062 commit 621ef79

File tree

12 files changed

+131
-36
lines changed

12 files changed

+131
-36
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ All notable changes to `src-cli` are documented in this file.
1313

1414
### Added
1515

16+
- Starting with Sourcegraph 3.30.0, the `published` field is optional in batch specs. If omitted, the publication state will be controlled through the Batch Changes UI. [#538](https://github.com/sourcegraph/src-cli/pull/538)
17+
18+
### Changed
19+
20+
### Fixed
21+
22+
## 3.29.1
23+
24+
### Added
25+
1626
- LSIF uploads now respect the `-insecure-skip-verify` flag to insecurely (surprise!) skip TLS certificate validation when communicating with Sourcegraph. [#559](https://github.com/sourcegraph/src-cli/pull/559)
1727

1828
### Changed

internal/batches/batch_spec.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type ChangesetTemplate struct {
4747
Body string `json:"body,omitempty" yaml:"body"`
4848
Branch string `json:"branch,omitempty" yaml:"branch"`
4949
Commit ExpandedGitCommitDescription `json:"commit,omitempty" yaml:"commit"`
50-
Published overridable.BoolOrString `json:"published" yaml:"published"`
50+
Published *overridable.BoolOrString `json:"published" yaml:"published"`
5151
}
5252

5353
type GitCommitAuthor struct {

internal/batches/executor/changeset_specs.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
"github.com/sourcegraph/src-cli/internal/batches"
1010
)
1111

12-
func createChangesetSpecs(task *Task, result executionResult, autoAuthorDetails bool) ([]*batches.ChangesetSpec, error) {
12+
var errOptionalPublishedUnsupported = errors.New(`This Sourcegraph version requires the "published" field to be specified in the batch spec; upgrade to version 3.30.0 or later to be able to omit the published field and control publication from the UI.`)
13+
14+
func createChangesetSpecs(task *Task, result executionResult, features batches.FeatureFlags) ([]*batches.ChangesetSpec, error) {
1315
repo := task.Repository.Name
1416

1517
tmplCtx := &ChangesetTemplateContext{
@@ -26,7 +28,7 @@ func createChangesetSpecs(task *Task, result executionResult, autoAuthorDetails
2628
var authorEmail string
2729

2830
if task.Template.Commit.Author == nil {
29-
if autoAuthorDetails {
31+
if features.IncludeAutoAuthorDetails {
3032
// user did not provide author info, so use defaults
3133
authorName = "Sourcegraph"
3234
authorEmail = "[email protected]"
@@ -66,7 +68,14 @@ func createChangesetSpecs(task *Task, result executionResult, autoAuthorDetails
6668
return nil, err
6769
}
6870

69-
newSpec := func(branch, diff string) *batches.ChangesetSpec {
71+
newSpec := func(branch, diff string) (*batches.ChangesetSpec, error) {
72+
var published interface{} = nil
73+
if task.Template.Published != nil {
74+
published = task.Template.Published.ValueWithSuffix(repo, branch)
75+
} else if !features.AllowOptionalPublished {
76+
return nil, errOptionalPublishedUnsupported
77+
}
78+
7079
return &batches.ChangesetSpec{
7180
BaseRepository: task.Repository.ID,
7281
CreatedChangeset: &batches.CreatedChangeset{
@@ -84,9 +93,9 @@ func createChangesetSpecs(task *Task, result executionResult, autoAuthorDetails
8493
Diff: diff,
8594
},
8695
},
87-
Published: task.Template.Published.ValueWithSuffix(repo, branch),
96+
Published: published,
8897
},
89-
}
98+
}, nil
9099
}
91100

92101
var specs []*batches.ChangesetSpec
@@ -105,10 +114,18 @@ func createChangesetSpecs(task *Task, result executionResult, autoAuthorDetails
105114
}
106115

107116
for branch, diff := range diffsByBranch {
108-
specs = append(specs, newSpec(branch, diff))
117+
spec, err := newSpec(branch, diff)
118+
if err != nil {
119+
return nil, err
120+
}
121+
specs = append(specs, spec)
109122
}
110123
} else {
111-
specs = append(specs, newSpec(defaultBranch, result.Diff))
124+
spec, err := newSpec(defaultBranch, result.Diff)
125+
if err != nil {
126+
return nil, err
127+
}
128+
specs = append(specs, spec)
112129
}
113130

114131
return specs, nil

internal/batches/executor/changeset_specs_test.go

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,23 @@ func TestCreateChangesetSpecs(t *testing.T) {
8080
Outputs: map[string]interface{}{},
8181
}
8282

83+
featuresWithoutOptionalPublished := featuresAllEnabled()
84+
featuresWithoutOptionalPublished.AllowOptionalPublished = false
85+
8386
tests := []struct {
84-
name string
85-
task *Task
86-
result executionResult
87+
name string
88+
task *Task
89+
features batches.FeatureFlags
90+
result executionResult
8791

8892
want []*batches.ChangesetSpec
8993
wantErr string
9094
}{
9195
{
92-
name: "success",
93-
task: defaultTask,
94-
result: defaultResult,
96+
name: "success",
97+
task: defaultTask,
98+
features: featuresAllEnabled(),
99+
result: defaultResult,
95100
want: []*batches.ChangesetSpec{
96101
defaultChangesetSpec,
97102
},
@@ -103,7 +108,8 @@ func TestCreateChangesetSpecs(t *testing.T) {
103108
published := `[{"github.com/sourcegraph/*@my-branch": true}]`
104109
task.Template.Published = parsePublishedFieldString(t, published)
105110
}),
106-
result: defaultResult,
111+
features: featuresAllEnabled(),
112+
result: defaultResult,
107113
want: []*batches.ChangesetSpec{
108114
specWith(defaultChangesetSpec, func(s *batches.ChangesetSpec) {
109115
s.Published = true
@@ -117,19 +123,44 @@ func TestCreateChangesetSpecs(t *testing.T) {
117123
published := `[{"github.com/sourcegraph/*@another-branch-name": true}]`
118124
task.Template.Published = parsePublishedFieldString(t, published)
119125
}),
120-
result: defaultResult,
126+
features: featuresAllEnabled(),
127+
result: defaultResult,
121128
want: []*batches.ChangesetSpec{
122129
specWith(defaultChangesetSpec, func(s *batches.ChangesetSpec) {
123130
s.Published = false
124131
}),
125132
},
126133
wantErr: "",
127134
},
135+
{
136+
name: "publish in UI on a supported version",
137+
task: taskWith(defaultTask, func(task *Task) {
138+
task.Template.Published = nil
139+
}),
140+
features: featuresAllEnabled(),
141+
result: defaultResult,
142+
want: []*batches.ChangesetSpec{
143+
specWith(defaultChangesetSpec, func(s *batches.ChangesetSpec) {
144+
s.Published = nil
145+
}),
146+
},
147+
wantErr: "",
148+
},
149+
{
150+
name: "publish in UI on an unsupported version",
151+
task: taskWith(defaultTask, func(task *Task) {
152+
task.Template.Published = nil
153+
}),
154+
features: featuresWithoutOptionalPublished,
155+
result: defaultResult,
156+
want: nil,
157+
wantErr: errOptionalPublishedUnsupported.Error(),
158+
},
128159
}
129160

130161
for _, tt := range tests {
131162
t.Run(tt.name, func(t *testing.T) {
132-
have, err := createChangesetSpecs(tt.task, tt.result, true)
163+
have, err := createChangesetSpecs(tt.task, tt.result, tt.features)
133164
if err != nil {
134165
if tt.wantErr != "" {
135166
if err.Error() != tt.wantErr {
@@ -308,12 +339,12 @@ func TestValidateGroups(t *testing.T) {
308339
}
309340
}
310341

311-
func parsePublishedFieldString(t *testing.T, input string) overridable.BoolOrString {
342+
func parsePublishedFieldString(t *testing.T, input string) *overridable.BoolOrString {
312343
t.Helper()
313344

314345
var result overridable.BoolOrString
315346
if err := json.Unmarshal([]byte(input), &result); err != nil {
316347
t.Fatalf("failed to parse %q as overridable.BoolOrString: %s", input, err)
317348
}
318-
return result
349+
return &result
319350
}

internal/batches/executor/coordinator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type NewCoordinatorOpts struct {
4848
SkipErrors bool
4949

5050
// Used by createChangesetSpecs
51-
AutoAuthorDetails bool
51+
Features batches.FeatureFlags
5252

5353
CleanArchives bool
5454
Parallelism int
@@ -66,7 +66,7 @@ func NewCoordinator(opts NewCoordinatorOpts) *Coordinator {
6666
Creator: opts.Creator,
6767
Logger: logManager,
6868

69-
AutoAuthorDetails: opts.AutoAuthorDetails,
69+
AutoAuthorDetails: opts.Features.IncludeAutoAuthorDetails,
7070
Parallelism: opts.Parallelism,
7171
Timeout: opts.Timeout,
7272
TempDir: opts.TempDir,
@@ -131,7 +131,7 @@ func (c *Coordinator) checkCacheForTask(ctx context.Context, task *Task) (specs
131131
return specs, true, nil
132132
}
133133

134-
specs, err = createChangesetSpecs(task, result, c.opts.AutoAuthorDetails)
134+
specs, err = createChangesetSpecs(task, result, c.opts.Features)
135135
if err != nil {
136136
return specs, false, err
137137
}
@@ -199,7 +199,7 @@ func (c *Coordinator) cacheAndBuildSpec(ctx context.Context, taskResult taskResu
199199
}
200200

201201
// Build the changeset specs.
202-
specs, err = createChangesetSpecs(taskResult.task, taskResult.result, c.opts.AutoAuthorDetails)
202+
specs, err = createChangesetSpecs(taskResult.task, taskResult.result, c.opts.Features)
203203
if err != nil {
204204
return specs, err
205205
}

internal/batches/executor/coordinator_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import (
99

1010
"github.com/google/go-cmp/cmp"
1111
"github.com/google/go-cmp/cmp/cmpopts"
12+
"github.com/sourcegraph/batch-change-utils/overridable"
1213
"github.com/sourcegraph/src-cli/internal/batches"
1314
"github.com/sourcegraph/src-cli/internal/batches/git"
1415
"github.com/sourcegraph/src-cli/internal/batches/graphql"
1516
"github.com/sourcegraph/src-cli/internal/batches/mock"
1617
)
1718

1819
func TestCoordinator_Execute(t *testing.T) {
20+
publishedFalse := overridable.FromBoolOrString(false)
1921
srcCLITask := &Task{Repository: testRepo1}
2022
sourcegraphTask := &Task{Repository: testRepo2}
2123

@@ -75,6 +77,7 @@ func TestCoordinator_Execute(t *testing.T) {
7577
{task: sourcegraphTask, result: executionResult{Diff: `dummydiff2`}},
7678
},
7779
},
80+
opts: NewCoordinatorOpts{Features: featuresAllEnabled()},
7881

7982
wantCacheEntries: 2,
8083
wantSpecs: []*batches.ChangesetSpec{
@@ -116,6 +119,7 @@ func TestCoordinator_Execute(t *testing.T) {
116119
Email: "output1=${{ outputs.output1}}",
117120
},
118121
},
122+
Published: &publishedFalse,
119123
},
120124
},
121125

@@ -141,6 +145,7 @@ func TestCoordinator_Execute(t *testing.T) {
141145
},
142146
},
143147
},
148+
opts: NewCoordinatorOpts{Features: featuresAllEnabled()},
144149

145150
wantCacheEntries: 1,
146151
wantSpecs: []*batches.ChangesetSpec{
@@ -191,6 +196,7 @@ func TestCoordinator_Execute(t *testing.T) {
191196
{task: sourcegraphTask, result: executionResult{Diff: nestedChangesDiff}},
192197
},
193198
},
199+
opts: NewCoordinatorOpts{Features: featuresAllEnabled()},
194200

195201
// We have 4 ChangesetSpecs, but we only want 2 cache entries,
196202
// since we cache per Task, not per resulting changeset spec.
@@ -216,7 +222,7 @@ func TestCoordinator_Execute(t *testing.T) {
216222
},
217223
{
218224
name: "skip errors",
219-
opts: NewCoordinatorOpts{SkipErrors: true},
225+
opts: NewCoordinatorOpts{Features: featuresAllEnabled(), SkipErrors: true},
220226

221227
tasks: []*Task{srcCLITask, sourcegraphTask},
222228

internal/batches/executor/executor_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,5 +463,6 @@ func featuresAllEnabled() batches.FeatureFlags {
463463
AllowTransformChanges: true,
464464
AllowWorkspaces: true,
465465
AllowConditionalExec: true,
466+
AllowOptionalPublished: true,
466467
}
467468
}

internal/batches/executor/main_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ var testRepo2 = &graphql.Repository{
2525
},
2626
}
2727

28+
var testPublished = overridable.FromBoolOrString(false)
29+
2830
var testChangesetTemplate = &batches.ChangesetTemplate{
2931
Title: "commit title",
3032
Body: "commit body",
@@ -36,5 +38,5 @@ var testChangesetTemplate = &batches.ChangesetTemplate{
3638
3739
},
3840
},
39-
Published: overridable.FromBoolOrString(false),
41+
Published: &testPublished,
4042
}

internal/batches/features.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type FeatureFlags struct {
1515
AllowWorkspaces bool
1616
BatchChanges bool
1717
AllowConditionalExec bool
18+
AllowOptionalPublished bool
1819
}
1920

2021
func (ff *FeatureFlags) SetFromVersion(version string) error {
@@ -30,6 +31,7 @@ func (ff *FeatureFlags) SetFromVersion(version string) error {
3031
{&ff.AllowWorkspaces, ">= 3.25.0", "2021-01-29"},
3132
{&ff.BatchChanges, ">= 3.26.0", "2021-03-07"},
3233
{&ff.AllowConditionalExec, ">= 3.28.0", "2021-05-05"},
34+
{&ff.AllowOptionalPublished, ">= 3.30.0", "2021-06-21"},
3335
} {
3436
value, err := api.CheckSourcegraphVersion(version, feature.constraint, feature.minDate)
3537
if err != nil {

internal/batches/service/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func (svc *Service) BuildTasks(ctx context.Context, repos []*graphql.Repository,
191191
func (svc *Service) NewCoordinator(opts executor.NewCoordinatorOpts) *executor.Coordinator {
192192
opts.ResolveRepoName = svc.resolveRepositoryName
193193
opts.Client = svc.client
194-
opts.AutoAuthorDetails = svc.features.IncludeAutoAuthorDetails
194+
opts.Features = svc.features
195195

196196
return executor.NewCoordinator(opts)
197197
}

0 commit comments

Comments
 (0)