Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion internal/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,15 @@ func (c *Client) CreatePullRequest(ctx context.Context, repo *Repository, remote
return pullRequestMetadata, nil
}

// AddLabelsToIssue adds labels to an existing issue in a GitHub repository.
func (c *Client) AddLabelsToIssue(ctx context.Context, repo *Repository, number int, labels []string) error {
slog.Info("Labels added to issue", "number", number, "labels", labels)
_, _, err := c.Issues.AddLabelsToIssue(ctx, repo.Owner, repo.Name, number, labels)
return err
}

// FetchGitHubRepoFromRemote parses the GitHub repo name from the remote for this repository.
// There must be a remote named 'origin' with a Github URL (as the first URL), in order to
// There must be a remote named 'origin' with a GitHub URL (as the first URL), in order to
// provide an unambiguous result.
// Remotes without any URLs, or where the first URL does not start with https://github.com/ are ignored.
func FetchGitHubRepoFromRemote(repo gitrepo.Repository) (*Repository, error) {
Expand Down
71 changes: 71 additions & 0 deletions internal/github/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,74 @@ func TestCreatePullRequest(t *testing.T) {
})
}
}

func TestAddLabelsToIssue(t *testing.T) {
t.Parallel()
for _, test := range []struct {
name string
handler http.HandlerFunc
issueNum int
labels []string
wantErr bool
wantErrSubstr string
}{
{
name: "add labels to an issue",
handler: func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Errorf("unexpected method: got %s, want %s", r.Method, http.MethodPost)
}
wantPath := "/repos/owner/repo/issues/7/labels"
if r.URL.Path != wantPath {
t.Errorf("unexpected path: got %s, want %s", r.URL.Path, wantPath)
}
var labels []string
if err := json.NewDecoder(r.Body).Decode(&labels); err != nil {
t.Fatalf("failed to decode request body: %v", err)
}
expectedBody := []string{"new-label", "another-label"}
if strings.Join(labels, ",") != strings.Join(expectedBody, ",") {
t.Errorf("unexpected body: got %q, want %q", labels, expectedBody)
}
},
issueNum: 7,
labels: []string{"new-label", "another-label"},
},
{
name: "GitHub API error",
handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) },
wantErr: true,
wantErrSubstr: "500",
},
} {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
server := httptest.NewServer(test.handler)
defer server.Close()

repo := &Repository{Owner: "owner", Name: "repo"}
client, err := newClientWithHTTP("fake-token", repo, server.Client())
if err != nil {
t.Fatalf("newClientWithHTTP() error = %v", err)
}
client.BaseURL, _ = url.Parse(server.URL + "/")

err = client.AddLabelsToIssue(context.Background(), repo, test.issueNum, test.labels)

if test.wantErr {
if err == nil {
t.Errorf("AddLabelsToIssue() should return an error")
}
if !strings.Contains(err.Error(), test.wantErrSubstr) {
t.Errorf("AddLabelsToIssue() err = %v, want error containing %q", err, test.wantErrSubstr)
}

return
}

if err != nil {
t.Errorf("AddLabelsToIssue() err = %v, want nil", err)
}
})
}
}
1 change: 1 addition & 0 deletions internal/librarian/librarian.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func Run(ctx context.Context, arg ...string) error {
type GitHubClient interface {
GetRawContent(ctx context.Context, path, ref string) ([]byte, error)
CreatePullRequest(ctx context.Context, repo *github.Repository, remoteBranch, title, body string) (*github.PullRequestMetadata, error)
AddLabelsToIssue(ctx context.Context, repo *github.Repository, number int, labels []string) error
}

// ContainerClient is an abstraction over the Docker client.
Expand Down
7 changes: 7 additions & 0 deletions internal/librarian/mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ type mockGitHubClient struct {
rawContent []byte
rawErr error
createPullRequestCalls int
addLabelsToIssuesCalls int
createPullRequestErr error
addLabelsToIssuesErr error
createdPR *github.PullRequestMetadata
}

Expand All @@ -49,6 +51,11 @@ func (m *mockGitHubClient) CreatePullRequest(ctx context.Context, repo *github.R
return m.createdPR, nil
}

func (m *mockGitHubClient) AddLabelsToIssue(ctx context.Context, repo *github.Repository, number int, labels []string) error {
m.addLabelsToIssuesCalls++
return m.addLabelsToIssuesErr
}

// mockContainerClient is a mock implementation of the ContainerClient interface for testing.
type mockContainerClient struct {
ContainerClient
Expand Down