Skip to content

Commit 0dd0273

Browse files
authored
fix(internal/librarian): save librarian state in release init (#2034)
Write librarian state after updating libraries in release init. Modify the test to check `state.yaml` in repo to verify the libraries are updated. Fixes #2030
1 parent 9a501d1 commit 0dd0273

File tree

2 files changed

+168
-20
lines changed

2 files changed

+168
-20
lines changed

internal/librarian/release_init.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ func (r *initRunner) run(ctx context.Context) error {
126126
return err
127127
}
128128

129+
if err := saveLibrarianState(r.repo.GetDir(), r.state); err != nil {
130+
return err
131+
}
132+
129133
commitInfo := &commitInfo{
130134
cfg: r.cfg,
131135
state: r.state,

internal/librarian/release_init_test.go

Lines changed: 164 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import (
2222
"strings"
2323
"testing"
2424

25+
"github.com/go-git/go-git/v5/plumbing"
26+
"gopkg.in/yaml.v3"
27+
2528
"github.com/googleapis/librarian/internal/conventionalcommits"
2629

2730
"github.com/go-git/go-git/v5"
@@ -89,29 +92,33 @@ func TestInitRun(t *testing.T) {
8992
name string
9093
runner *initRunner
9194
files map[string]string
95+
want *config.LibrarianState
9296
wantErr bool
9397
wantErrMsg string
9498
}{
9599
{
96-
name: "run release init command for one library",
100+
name: "run release init command for all libraries, update librarian state",
97101
runner: &initRunner{
98102
workRoot: t.TempDir(),
99103
containerClient: &mockContainerClient{},
100-
cfg: &config.Config{
101-
Library: "example-id",
102-
Push: false,
103-
},
104+
cfg: &config.Config{},
104105
state: &config.LibrarianState{
105106
Libraries: []*config.LibraryState{
106107
{
107-
ID: "another-example-id",
108+
ID: "another-example-id",
109+
Version: "1.0.0",
108110
SourceRoots: []string{
109111
"dir3",
110112
"dir4",
111113
},
114+
RemoveRegex: []string{
115+
"dir3",
116+
"dir4",
117+
},
112118
},
113119
{
114-
ID: "example-id",
120+
ID: "example-id",
121+
Version: "2.0.0",
115122
SourceRoots: []string{
116123
"dir1",
117124
"dir2",
@@ -125,6 +132,30 @@ func TestInitRun(t *testing.T) {
125132
},
126133
repo: &MockRepository{
127134
Dir: t.TempDir(),
135+
GetCommitsForPathsSinceTagValueByTag: map[string][]*gitrepo.Commit{
136+
"another-example-id-1.0.0": {
137+
{
138+
Hash: plumbing.NewHash("123456"),
139+
Message: "feat: another new feature",
140+
},
141+
},
142+
"example-id-2.0.0": {
143+
{
144+
Hash: plumbing.NewHash("abcdefg"),
145+
Message: "feat: a new feature",
146+
},
147+
},
148+
},
149+
ChangedFilesInCommitValueByHash: map[string][]string{
150+
plumbing.NewHash("123456").String(): {
151+
"dir3/file3.txt",
152+
"dir4/file4.txt",
153+
},
154+
plumbing.NewHash("abcdefg").String(): {
155+
"dir1/file1.txt",
156+
"dir2/file2.txt",
157+
},
158+
},
128159
},
129160
librarianConfig: &config.LibrarianConfig{},
130161
partialRepo: t.TempDir(),
@@ -133,15 +164,48 @@ func TestInitRun(t *testing.T) {
133164
"file1.txt": "",
134165
"dir1/file1.txt": "",
135166
"dir2/file2.txt": "",
167+
"dir3/file3.txt": "",
168+
"dir4/file4.txt": "",
169+
},
170+
want: &config.LibrarianState{
171+
Libraries: []*config.LibraryState{
172+
{
173+
ID: "another-example-id",
174+
Version: "1.1.0", // version is bumped.
175+
APIs: []*config.API{},
176+
SourceRoots: []string{
177+
"dir3",
178+
"dir4",
179+
},
180+
PreserveRegex: []string{},
181+
RemoveRegex: []string{
182+
"dir3",
183+
"dir4",
184+
},
185+
},
186+
{
187+
ID: "example-id",
188+
Version: "2.1.0", // version is bumped.
189+
APIs: []*config.API{},
190+
SourceRoots: []string{
191+
"dir1",
192+
"dir2",
193+
},
194+
PreserveRegex: []string{},
195+
RemoveRegex: []string{
196+
"dir1",
197+
"dir2",
198+
},
199+
},
200+
},
136201
},
137202
},
138203
{
139-
name: "run release init command without librarian config",
204+
name: "run release init command for one library",
140205
runner: &initRunner{
141206
workRoot: t.TempDir(),
142207
containerClient: &mockContainerClient{},
143208
cfg: &config.Config{
144-
Push: false,
145209
Library: "example-id",
146210
},
147211
state: &config.LibrarianState{
@@ -169,20 +233,51 @@ func TestInitRun(t *testing.T) {
169233
repo: &MockRepository{
170234
Dir: t.TempDir(),
171235
},
172-
partialRepo: t.TempDir(),
236+
librarianConfig: &config.LibrarianConfig{},
237+
partialRepo: t.TempDir(),
173238
},
174239
files: map[string]string{
175240
"file1.txt": "",
176241
"dir1/file1.txt": "",
177242
"dir2/file2.txt": "",
178243
},
244+
want: &config.LibrarianState{
245+
Libraries: []*config.LibraryState{
246+
{
247+
ID: "another-example-id",
248+
APIs: []*config.API{},
249+
SourceRoots: []string{
250+
"dir3",
251+
"dir4",
252+
},
253+
PreserveRegex: []string{},
254+
RemoveRegex: []string{},
255+
},
256+
{
257+
ID: "example-id",
258+
APIs: []*config.API{},
259+
SourceRoots: []string{
260+
"dir1",
261+
"dir2",
262+
},
263+
PreserveRegex: []string{},
264+
RemoveRegex: []string{
265+
"dir1",
266+
"dir2",
267+
},
268+
},
269+
},
270+
},
179271
},
180272
{
181-
name: "run release init command for all libraries",
273+
name: "run release init command without librarian config",
182274
runner: &initRunner{
183275
workRoot: t.TempDir(),
184276
containerClient: &mockContainerClient{},
185-
cfg: &config.Config{},
277+
cfg: &config.Config{
278+
Push: false,
279+
Library: "example-id",
280+
},
186281
state: &config.LibrarianState{
187282
Libraries: []*config.LibraryState{
188283
{
@@ -191,10 +286,6 @@ func TestInitRun(t *testing.T) {
191286
"dir3",
192287
"dir4",
193288
},
194-
RemoveRegex: []string{
195-
"dir3",
196-
"dir4",
197-
},
198289
},
199290
{
200291
ID: "example-id",
@@ -212,17 +303,42 @@ func TestInitRun(t *testing.T) {
212303
repo: &MockRepository{
213304
Dir: t.TempDir(),
214305
},
215-
librarianConfig: &config.LibrarianConfig{},
216-
partialRepo: t.TempDir(),
306+
partialRepo: t.TempDir(),
217307
},
218308
files: map[string]string{
219309
"file1.txt": "",
220310
"dir1/file1.txt": "",
221311
"dir2/file2.txt": "",
222-
"dir3/file3.txt": "",
223-
"dir4/file4.txt": "",
312+
},
313+
want: &config.LibrarianState{
314+
Libraries: []*config.LibraryState{
315+
{
316+
ID: "another-example-id",
317+
APIs: []*config.API{},
318+
SourceRoots: []string{
319+
"dir3",
320+
"dir4",
321+
},
322+
PreserveRegex: []string{},
323+
RemoveRegex: []string{},
324+
},
325+
{
326+
ID: "example-id",
327+
APIs: []*config.API{},
328+
SourceRoots: []string{
329+
"dir1",
330+
"dir2",
331+
},
332+
PreserveRegex: []string{},
333+
RemoveRegex: []string{
334+
"dir1",
335+
"dir2",
336+
},
337+
},
338+
},
224339
},
225340
},
341+
226342
{
227343
name: "docker command returns error",
228344
runner: &initRunner{
@@ -364,6 +480,19 @@ func TestInitRun(t *testing.T) {
364480
files: map[string]string{
365481
"dir1/file1.txt": "hello",
366482
},
483+
want: &config.LibrarianState{
484+
Libraries: []*config.LibraryState{
485+
{
486+
ID: "example-id",
487+
APIs: []*config.API{},
488+
SourceRoots: []string{
489+
"dir1",
490+
},
491+
PreserveRegex: []string{},
492+
RemoveRegex: []string{},
493+
},
494+
},
495+
},
367496
},
368497
{
369498
name: "copy library files returns error",
@@ -484,6 +613,21 @@ func TestInitRun(t *testing.T) {
484613
if err != nil {
485614
t.Errorf("run() failed: %s", err.Error())
486615
}
616+
// load librarian state from state.yaml, which should contain updated
617+
// library state.
618+
bytes, err := os.ReadFile(filepath.Join(repoDir, ".librarian/state.yaml"))
619+
if err != nil {
620+
t.Fatal(err)
621+
}
622+
623+
var got *config.LibrarianState
624+
if err := yaml.Unmarshal(bytes, &got); err != nil {
625+
t.Fatal(err)
626+
}
627+
628+
if diff := cmp.Diff(test.want, got); diff != "" {
629+
t.Errorf("state mismatch (-want +got):\n%s", diff)
630+
}
487631
})
488632
}
489633
}

0 commit comments

Comments
 (0)