Skip to content
Open
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
89 changes: 89 additions & 0 deletions github/code_quality.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2026 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"context"
"fmt"
)

// CodeQualityService handles communication with the code quality related
// methods of the GitHub API.
//
// GitHub API docs: https://docs.github.com/rest/code-quality/code-quality?apiVersion=2022-11-28
type CodeQualityService service

// CodeQualitySetupConfiguration represents a code quality setup configuration for a repository.
type CodeQualitySetupConfiguration struct {
State *string `json:"state,omitempty"`
Languages []string `json:"languages,omitempty"`
RunnerType *string `json:"runner_type,omitempty"`
RunnerLabel *string `json:"runner_label,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Schedule *string `json:"schedule,omitempty"`
}

// UpdateCodeQualitySetupOptions specifies parameters to the
// CodeQualityService.UpdateSetup method.
type UpdateCodeQualitySetupOptions struct {
State *string `json:"state,omitempty"`
RunnerType *string `json:"runner_type,omitempty"`
RunnerLabel *string `json:"runner_label,omitempty"`
Languages []string `json:"languages,omitempty"`
}

// UpdateCodeQualitySetupResponse represents a response from updating a code quality setup configuration.
type UpdateCodeQualitySetupResponse struct {
RunID *int64 `json:"run_id,omitempty"`
RunURL *string `json:"run_url,omitempty"`
}

// GetSetup gets a code quality setup configuration for a repository.
//
// GitHub API docs: https://docs.github.com/rest/code-quality/code-quality?apiVersion=2022-11-28#get-a-code-quality-setup-configuration
Comment thread
MasterOogway1466 marked this conversation as resolved.
//
//meta:operation GET /repos/{owner}/{repo}/code-quality/setup
func (s *CodeQualityService) GetSetup(ctx context.Context, owner, repo string) (*CodeQualitySetupConfiguration, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-quality/setup", owner, repo)

req, err := s.client.NewRequest(ctx, "GET", u, nil)
if err != nil {
return nil, nil, err
}

var cfg *CodeQualitySetupConfiguration
resp, err := s.client.Do(req, &cfg)
if err != nil {
return nil, resp, err
}

return cfg, resp, nil
}

// UpdateSetup updates a code quality setup configuration for a repository.
//
// This method might return an AcceptedError and a status code of 202. This is because this is the status that GitHub
// returns to signify that it has now scheduled the update in a background task.
//
// GitHub API docs: https://docs.github.com/rest/code-quality/code-quality?apiVersion=2022-11-28#update-a-code-quality-setup-configuration
Comment thread
MasterOogway1466 marked this conversation as resolved.
//
//meta:operation PATCH /repos/{owner}/{repo}/code-quality/setup
func (s *CodeQualityService) UpdateSetup(ctx context.Context, owner, repo string, opts *UpdateCodeQualitySetupOptions) (*UpdateCodeQualitySetupResponse, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-quality/setup", owner, repo)

req, err := s.client.NewRequest(ctx, "PATCH", u, opts)
if err != nil {
return nil, nil, err
}

var result *UpdateCodeQualitySetupResponse
resp, err := s.client.Do(req, &result)
if err != nil {
return nil, resp, err
}

return result, resp, nil
}
185 changes: 185 additions & 0 deletions github/code_quality_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// Copyright 2026 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"fmt"
"net/http"
"testing"
"time"

"github.com/google/go-cmp/cmp"
)

func TestCodeQualityService_GetSetup(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/repos/o/r/code-quality/setup", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
"state": "configured",
"languages": ["javascript-typescript", "python"],
"runner_type": "standard",
"runner_label": null,
"updated_at": "2026-01-01T00:00:00Z",
"schedule": "weekly"
}`)
})

ctx := t.Context()
cfg, _, err := client.CodeQuality.GetSetup(ctx, "o", "r")
if err != nil {
t.Fatalf("CodeQuality.GetSetup returned error: %v", err)
}

want := &CodeQualitySetupConfiguration{
State: Ptr("configured"),
Languages: []string{"javascript-typescript", "python"},
RunnerType: Ptr("standard"),
UpdatedAt: &Timestamp{time.Date(2026, time.January, 1, 0, 0, 0, 0, time.UTC)},
Schedule: Ptr("weekly"),
}
if diff := cmp.Diff(want, cfg); diff != "" {
t.Errorf("CodeQuality.GetSetup mismatch (-want +got):\n%v", diff)
}

const methodName = "GetSetup"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.CodeQuality.GetSetup(ctx, "\n", "\n")
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.CodeQuality.GetSetup(ctx, "o", "r")
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestCodeQualityService_UpdateSetup(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := &UpdateCodeQualitySetupOptions{
State: Ptr("configured"),
Languages: []string{"javascript-typescript", "python", "ruby"},
}

mux.HandleFunc("/repos/o/r/code-quality/setup", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
fmt.Fprint(w, `{
"run_id": 42,
"run_url": "https://api.github.com/repos/octocat/hello-world/actions/runs/42"
}`)
})

ctx := t.Context()
result, _, err := client.CodeQuality.UpdateSetup(ctx, "o", "r", input)
if err != nil {
t.Fatalf("CodeQuality.UpdateSetup returned error: %v", err)
}

want := &UpdateCodeQualitySetupResponse{
RunID: Ptr(int64(42)),
RunURL: Ptr("https://api.github.com/repos/octocat/hello-world/actions/runs/42"),
}
if diff := cmp.Diff(want, result); diff != "" {
t.Errorf("CodeQuality.UpdateSetup mismatch (-want +got):\n%v", diff)
}

const methodName = "UpdateSetup"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.CodeQuality.UpdateSetup(ctx, "\n", "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.CodeQuality.UpdateSetup(ctx, "o", "r", input)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestCodeQualityService_UpdateSetup_withRunnerLabel(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := &UpdateCodeQualitySetupOptions{
State: Ptr("configured"),
RunnerType: Ptr("labeled"),
RunnerLabel: Ptr("my-runner"),
Languages: []string{"go", "python"},
}

mux.HandleFunc("/repos/o/r/code-quality/setup", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
fmt.Fprint(w, `{
"run_id": 99,
"run_url": "https://api.github.com/repos/octocat/hello-world/actions/runs/99"
}`)
})

ctx := t.Context()
result, _, err := client.CodeQuality.UpdateSetup(ctx, "o", "r", input)
if err != nil {
t.Fatalf("CodeQuality.UpdateSetup returned error: %v", err)
}

want := &UpdateCodeQualitySetupResponse{
RunID: Ptr(int64(99)),
RunURL: Ptr("https://api.github.com/repos/octocat/hello-world/actions/runs/99"),
}
if diff := cmp.Diff(want, result); diff != "" {
t.Errorf("CodeQuality.UpdateSetup mismatch (-want +got):\n%v", diff)
}
}

func TestCodeQualityService_UpdateSetup_notConfigured(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := &UpdateCodeQualitySetupOptions{
State: Ptr("not-configured"),
}

mux.HandleFunc("/repos/o/r/code-quality/setup", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{}`)
})

ctx := t.Context()
_, _, err := client.CodeQuality.UpdateSetup(ctx, "o", "r", input)
if err != nil {
t.Fatalf("CodeQuality.UpdateSetup returned error: %v", err)
}
}

func TestCodeQualityService_GetSetup_invalidOwner(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.CodeQuality.GetSetup(ctx, "%", "r")
testURLParseError(t, err)
}

func TestCodeQualityService_UpdateSetup_invalidOwner(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.CodeQuality.UpdateSetup(ctx, "%", "r", nil)
testURLParseError(t, err)
}
96 changes: 96 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading