Skip to content

Commit f114aa2

Browse files
authored
feat: Add release-please tag to release PRs so louhi flow will get triggered (#2050)
fixes #2038 Tested with ``` go run github.com/googleapis/librarian/cmd/librarian release tag-and-release -repo=/Users/ldetmer/workspace2/librarian -pr=ldetmer#1 ``` ldetmer@39ab425 contains tag release-please-1
1 parent 919487b commit f114aa2

File tree

6 files changed

+109
-2
lines changed

6 files changed

+109
-2
lines changed

internal/github/github.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,16 @@ func (c *Client) FindMergedPullRequestsWithPendingReleaseLabel(ctx context.Conte
312312
}
313313
return allPRs, nil
314314
}
315+
316+
// CreateTag creates a lightweight tag in the repository at the given commit SHA.
317+
// This does NOT create a release, just the tag.
318+
func (c *Client) CreateTag(ctx context.Context, tagName, commitSHA string) error {
319+
slog.Info("Creating tag", "tag", tagName, "commit", commitSHA)
320+
ref := "refs/tags/" + tagName
321+
tagRef := &github.Reference{
322+
Ref: github.Ptr(ref),
323+
Object: &github.GitObject{SHA: github.Ptr(commitSHA), Type: github.Ptr("commit")},
324+
}
325+
_, _, err := c.Git.CreateRef(ctx, c.repo.Owner, c.repo.Name, tagRef)
326+
return err
327+
}

internal/github/github_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,3 +1081,67 @@ func TestFindMergedPullRequestsWithPendingReleaseLabel(t *testing.T) {
10811081
})
10821082
}
10831083
}
1084+
func TestCreateTag(t *testing.T) {
1085+
t.Parallel()
1086+
for _, test := range []struct {
1087+
name string
1088+
tagName string
1089+
commitSHA string
1090+
handler http.HandlerFunc
1091+
wantErr bool
1092+
}{
1093+
{
1094+
name: "Success",
1095+
tagName: "v1.2.3",
1096+
commitSHA: "abcdef123456",
1097+
handler: func(w http.ResponseWriter, r *http.Request) {
1098+
if r.Method != http.MethodPost {
1099+
t.Errorf("unexpected method: got %s, want %s", r.Method, http.MethodPost)
1100+
}
1101+
wantPath := "/repos/owner/repo/git/refs"
1102+
if r.URL.Path != wantPath {
1103+
t.Errorf("unexpected path: got %s, want %s", r.URL.Path, wantPath)
1104+
}
1105+
1106+
var ref github.Reference
1107+
if err := json.NewDecoder(r.Body).Decode(&ref); err != nil {
1108+
t.Fatalf("failed to decode request body: %v", err)
1109+
}
1110+
if ref.Ref == nil || *ref.Ref != "refs/tags/v1.2.3" {
1111+
t.Errorf("unexpected ref: got %v, want %s", ref.Ref, "refs/tags/v1.2.3")
1112+
}
1113+
fmt.Fprint(w, `{"ref": "refs/tags/v1.2.3"}`)
1114+
},
1115+
},
1116+
{
1117+
name: "API Error",
1118+
tagName: "v1.2.3",
1119+
commitSHA: "abcdef123456",
1120+
handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) },
1121+
wantErr: true,
1122+
},
1123+
} {
1124+
t.Run(test.name, func(t *testing.T) {
1125+
t.Parallel()
1126+
server := httptest.NewServer(test.handler)
1127+
defer server.Close()
1128+
1129+
repo := &Repository{Owner: "owner", Name: "repo"}
1130+
client, err := newClientWithHTTP("fake-token", repo, server.Client())
1131+
if err != nil {
1132+
t.Fatalf("newClientWithHTTP() error = %v", err)
1133+
}
1134+
client.BaseURL, _ = url.Parse(server.URL + "/")
1135+
1136+
err = client.CreateTag(context.Background(), test.tagName, test.commitSHA)
1137+
1138+
if test.wantErr {
1139+
if err == nil {
1140+
t.Errorf("CreateTag() err = nil, expected error")
1141+
}
1142+
} else if err != nil {
1143+
t.Errorf("CreateTag() err = %v, want nil", err)
1144+
}
1145+
})
1146+
}
1147+
}

internal/librarian/librarian.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type GitHubClient interface {
115115
GetPullRequest(ctx context.Context, number int) (*github.PullRequest, error)
116116
CreateRelease(ctx context.Context, tagName, name, body, commitish string) (*github.RepositoryRelease, error)
117117
CreateIssueComment(ctx context.Context, number int, comment string) error
118+
CreateTag(ctx context.Context, tag, commitish string) error
118119
}
119120

120121
// ContainerClient is an abstraction over the Docker client.

internal/librarian/mocks_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ type mockGitHubClient struct {
4040
searchPullRequestsCalls int
4141
getPullRequestCalls int
4242
createReleaseCalls int
43+
createTagCalls int
4344
createPullRequestErr error
4445
addLabelsToIssuesErr error
4546
getLabelsErr error
4647
replaceLabelsErr error
4748
searchPullRequestsErr error
4849
getPullRequestErr error
4950
createReleaseErr error
51+
createTagErr error
5052
createdPR *github.PullRequestMetadata
5153
labels []string
5254
pullRequests []*github.PullRequest
@@ -97,6 +99,11 @@ func (m *mockGitHubClient) CreateRelease(ctx context.Context, tagName, releaseNa
9799
return m.createdRelease, m.createReleaseErr
98100
}
99101

102+
func (m *mockGitHubClient) CreateTag(ctx context.Context, tagName, commitish string) error {
103+
m.createTagCalls++
104+
return m.createTagErr
105+
}
106+
100107
// mockContainerClient is a mock implementation of the ContainerClient interface for testing.
101108
type mockContainerClient struct {
102109
ContainerClient

internal/librarian/tag_and_release.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,17 @@ func (r *tagAndReleaseRunner) processPullRequest(ctx context.Context, p *github.
174174
slog.Warn("no release details found in pull request body, skipping")
175175
return nil
176176
}
177+
178+
// Add a tag to the release commit to trigger louhi flow: "release-please-{pr number}"
179+
//TODO: remove this logic as part of https://github.com/googleapis/librarian/issues/2044
180+
commitSha := p.GetMergeCommitSHA()
181+
tagName := fmt.Sprintf("release-please-%d", p.GetNumber())
182+
if err := r.ghClient.CreateTag(ctx, tagName, commitSha); err != nil {
183+
return fmt.Errorf("failed to create tag %s: %w", tagName, err)
184+
}
185+
177186
for _, release := range releases {
178187
slog.Info("creating release", "library", release.Library, "version", release.Version)
179-
commitish := p.GetMergeCommitSHA()
180188

181189
lib := r.state.LibraryByID(release.Library)
182190
if lib == nil {
@@ -186,7 +194,7 @@ func (r *tagAndReleaseRunner) processPullRequest(ctx context.Context, p *github.
186194
// Create the release.
187195
tagName := formatTag(lib, release.Version)
188196
releaseName := fmt.Sprintf("%s %s", release.Library, release.Version)
189-
if _, err := r.ghClient.CreateRelease(ctx, tagName, releaseName, release.Body, commitish); err != nil {
197+
if _, err := r.ghClient.CreateRelease(ctx, tagName, releaseName, release.Body, commitSha); err != nil {
190198
return fmt.Errorf("failed to create release: %w", err)
191199
}
192200

internal/librarian/tag_and_release_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ func TestProcessPullRequest(t *testing.T) {
374374
wantErrMsg string
375375
wantCreateReleaseCalls int
376376
wantReplaceLabelsCalls int
377+
wantCreateTagCalls int
377378
}{
378379
{
379380
name: "happy path",
@@ -382,6 +383,7 @@ func TestProcessPullRequest(t *testing.T) {
382383
state: state,
383384
wantCreateReleaseCalls: 1,
384385
wantReplaceLabelsCalls: 1,
386+
wantCreateTagCalls: 1,
385387
},
386388
{
387389
name: "no release details",
@@ -405,6 +407,7 @@ func TestProcessPullRequest(t *testing.T) {
405407
state: state,
406408
wantErrMsg: "failed to create release",
407409
wantCreateReleaseCalls: 1,
410+
wantCreateTagCalls: 1,
408411
},
409412
{
410413
name: "replace labels fails",
@@ -416,6 +419,17 @@ func TestProcessPullRequest(t *testing.T) {
416419
wantErrMsg: "failed to replace labels",
417420
wantCreateReleaseCalls: 1,
418421
wantReplaceLabelsCalls: 1,
422+
wantCreateTagCalls: 1,
423+
},
424+
{
425+
name: "create tag fails",
426+
pr: prWithRelease,
427+
ghClient: &mockGitHubClient{
428+
createTagErr: errors.New("create tag error"),
429+
},
430+
state: state,
431+
wantErrMsg: "failed to create tag",
432+
wantCreateTagCalls: 1,
419433
},
420434
} {
421435
t.Run(test.name, func(t *testing.T) {

0 commit comments

Comments
 (0)