From fd206ab5994b116b23647117e8f880198ef15e26 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 17 Dec 2025 13:49:46 +0000 Subject: [PATCH 1/7] add remaining codespace endpoints and tests --- github/codespaces.go | 329 +++++++++++++++++++++- github/codespaces_test.go | 483 ++++++++++++++++++++++++++++++++ github/github-accessors.go | 128 +++++++++ github/github-accessors_test.go | 176 ++++++++++++ 4 files changed, 1115 insertions(+), 1 deletion(-) diff --git a/github/codespaces.go b/github/codespaces.go index 608370503f6..5dc2aea06bc 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -167,7 +167,86 @@ type CreateCodespaceOptions struct { DisplayName *string `json:"display_name,omitempty"` // RetentionPeriodMinutes represents the duration in minutes after codespace has gone idle in which it will be deleted. // Must be integer minutes between 0 and 43200 (30 days). - RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"` + RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"` + Location *string `json:"location,omitempty"` +} + +// DevContainer represents a devcontainer configuration in a repository. +type DevContainer struct { + Path string `json:"path"` + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` +} + +// DevContainersConfig represents list of devcontainer configuration in a repository. +type DevContainersConfig struct { + Devcontainers []*DevContainer `json:"devcontainers"` + TotalCount int64 `json:"total_count"` +} + +// CodespaceDefaults represents the a field for DefaultAttributes. +type CodespaceDefaults struct { + DevcontainerPath *string `json:"devcontainer_path,omitempty"` + Location string `json:"location"` +} + +// CodespaceDefaultAttributes represents the default attributes for codespaces created by the user with the repository. +type CodespaceDefaultAttributes struct { + BillableOwner User `json:"billable_owner"` + Defaults CodespaceDefaults `json:"defaults"` +} + +// CodespaceGetDefaultAttributesOptions represents options for getting default attributes for a codespace. +type CodespaceGetDefaultAttributesOptions struct { + // Ref represents the branch or commit to check for a default devcontainer path. If not specified, the default branch will be checked. + Ref *string `url:"ref,omitempty"` + // ClientIP represents an alternative IP for default location auto-detection, such as when proxying a request. + ClientIP *string `url:"client_ip,omitempty"` +} + +// CodespacePullRequestOptions represents a field for CodespaceCreateForUserOptions. +type CodespacePullRequestOptions struct { + // PullRequestNumber represents the pull request number. + PullRequestNumber int64 `json:"pull_request_number"` + // RepositoryID represents the repository ID for this codespace. + RepositoryID int64 `json:"repository_id"` +} + +// CodespaceCreateForUserOptions represents options for creating a codespace for the authenticated user. +type CodespaceCreateForUserOptions struct { + *CreateCodespaceOptions + *CodespacePullRequestOptions + // RepositoryID represents the repository ID for this codespace. + RepositoryID int64 `json:"repository_id"` +} + +// UpdateCodespaceOptions represents options for updating a codespace. +type UpdateCodespaceOptions struct { + // Machine represents a valid machine to transition this codespace to. + Machine *string `json:"machine,omitempty"` + // RecentFolders represents the recently opened folders inside the codespace. + // It is currently used by the clients to determine the folder path to load the codespace in. + RecentFolders []string `json:"recent_folders,omitempty"` +} + +// CodespaceExport represents an export of a codespace. +type CodespaceExport struct { + // Can be one of: `succeeded`, `failed`, `in_progress`. + State *string `json:"state,omitempty"` + CompletedAt *Timestamp `json:"completed_at,omitempty"` + Branch *string `json:"branch,omitempty"` + SHA *string `json:"sha,omitempty"` + ID *string `json:"id,omitempty"` + ExportURL *string `json:"export_url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` +} + +// PublishCodespaceOptions represents options for creating a repository from an unpublished codespace. +type PublishCodespaceOptions struct { + // Name represents the name of the new repository. + Name *string `json:"name,omitempty"` + // Private represents whether the new repository is private. Defaults to false. + Private *bool `json:"private,omitempty"` } // CreateInRepo creates a codespace in a repository. @@ -264,3 +343,251 @@ func (s *CodespacesService) Delete(ctx context.Context, codespaceName string) (* return s.client.Do(ctx, req, nil) } + +// ListDevContainersConfig lists devcontainer configurations in a repository for the authenticated user. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#list-devcontainer-configurations-in-a-repository-for-the-authenticated-user +// +//meta:operation GET /repos/{owner}/{repo}/codespaces/devcontainers +func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, repo string, opt *ListOptions) (*DevContainersConfig, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/codespaces/devcontainers", owner, repo) + + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var devcontainers *DevContainersConfig + resp, err := s.client.Do(ctx, req, &devcontainers) + if err != nil { + return nil, resp, err + } + + return devcontainers, resp, nil +} + +// GetDefaultAttributes gets the default attributes for codespaces created by the user with the repository. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-default-attributes-for-a-codespace +// +//meta:operation GET /repos/{owner}/{repo}/codespaces/new +func (s *CodespacesService) GetDefaultAttributes(ctx context.Context, owner, repo string, opt *CodespaceGetDefaultAttributesOptions) (*CodespaceDefaultAttributes, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/codespaces/new", owner, repo) + + u, err := addOptions(u, opt) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var attributes *CodespaceDefaultAttributes + resp, err := s.client.Do(ctx, req, &attributes) + if err != nil { + return nil, resp, err + } + + return attributes, resp, nil +} + +// CheckPermissions checks whether the permissions defined by a given devcontainer configuration have been accepted by the authenticated user. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#check-if-permissions-defined-by-a-devcontainer-have-been-accepted-by-the-authenticated-user +// +//meta:operation GET /repos/{owner}/{repo}/codespaces/permissions_check +func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, ref, devcontainerPath string) (*bool, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/codespaces/permissions_check", owner, repo) + + u, err := addOptions(u, &struct { + Ref string `url:"ref"` + DevcontainerPath string `url:"devcontainer_path"` + }{ + Ref: ref, + DevcontainerPath: devcontainerPath, + }) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var hasPermission struct { + Accepted *bool `json:"accepted,omitempty"` + } + + resp, err := s.client.Do(ctx, req, &hasPermission) + if err != nil { + return nil, resp, err + } + + return hasPermission.Accepted, resp, nil +} + +// CreateFromPullRequest creates a codespace owned by the authenticated user for the specified pull request. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-from-a-pull-request +// +//meta:operation POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces +func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, opt *CreateCodespaceOptions) (*Codespace, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/pulls/%v/codespaces", owner, repo, pullNumber) + + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + var codespace *Codespace + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// CreateForAuthenticatedUser creates a new codespace, owned by the authenticated user. +// +// This method requires either RepositoryId OR a PullRequest but not both. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-for-the-authenticated-user +// +//meta:operation POST /user/codespaces +func (s *CodespacesService) CreateForAuthenticatedUser(ctx context.Context, opt *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { + u := "user/codespaces" + + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + var codespace *Codespace + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// GetInfo gets information about a user's codespace. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-a-codespace-for-the-authenticated-user +// +//meta:operation GET /user/codespaces/{codespace_name} +func (s *CodespacesService) GetInfo(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { + u := fmt.Sprintf("user/codespaces/%v", codespaceName) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var codespace *Codespace + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// Update updates a codespace owned by the authenticated user. +// +// Only the codespace's machine type and recent folders can be modified using this endpoint. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#update-a-codespace-for-the-authenticated-user +// +//meta:operation PATCH /user/codespaces/{codespace_name} +func (s *CodespacesService) Update(ctx context.Context, codespaceName string, opt *UpdateCodespaceOptions) (*Codespace, *Response, error) { + u := fmt.Sprintf("user/codespaces/%v", codespaceName) + + req, err := s.client.NewRequest("PATCH", u, opt) + if err != nil { + return nil, nil, err + } + + var codespace *Codespace + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// TriggerExport triggers an export of the specified codespace and returns a URL and ID where the status of the export can be monitored. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#export-a-codespace-for-the-authenticated-user +// +//meta:operation POST /user/codespaces/{codespace_name}/exports +func (s *CodespacesService) TriggerExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { + u := fmt.Sprintf("user/codespaces/%v/exports", codespaceName) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + var codespace *CodespaceExport + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// GetLatestExport gets information about an export of a codespace. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-details-about-a-codespace-export +// +//meta:operation GET /user/codespaces/{codespace_name}/exports/{export_id} +func (s *CodespacesService) GetLatestExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { + u := fmt.Sprintf("user/codespaces/%v/exports/latest", codespaceName) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var codespace *CodespaceExport + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} + +// PublishCodespace publishes an unpublished codespace, creating a new repository and assigning it to the codespace. +// +// GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-repository-from-an-unpublished-codespace +// +//meta:operation POST /user/codespaces/{codespace_name}/publish +func (s *CodespacesService) PublishCodespace(ctx context.Context, codespaceName string, opt *PublishCodespaceOptions) (*Codespace, *Response, error) { + u := fmt.Sprintf("user/codespaces/%v/publish", codespaceName) + + req, err := s.client.NewRequest("POST", u, opt) + if err != nil { + return nil, nil, err + } + + var codespace *Codespace + resp, err := s.client.Do(ctx, req, &codespace) + if err != nil { + return nil, resp, err + } + + return codespace, resp, nil +} diff --git a/github/codespaces_test.go b/github/codespaces_test.go index eb3d452326e..2521a91fa1a 100644 --- a/github/codespaces_test.go +++ b/github/codespaces_test.go @@ -291,3 +291,486 @@ func TestCodespacesService_Delete(t *testing.T) { return client.Codespaces.Delete(ctx, "codespace_1") }) } + +func TestCodespacesService_ListDevContainersConfig(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/codespaces/devcontainers", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "total_count": 1, + "devcontainers": [{ + "path": ".devcontainer/foobar/devcontainer.json", + "name": "foobar", + "display_name": "foobar" + }] + }`) + }) + + ctx := t.Context() + opts := &ListOptions{Page: 1, PerPage: 10} + + got, _, err := client.Codespaces.ListDevContainersConfig(ctx, "o", "r", opts) + if err != nil { + t.Fatalf("Codespaces.ListDevContainersConfig returned error: %v", err) + } + + want := &DevContainersConfig{ + TotalCount: 1, + Devcontainers: []*DevContainer{ + { + Path: ".devcontainer/foobar/devcontainer.json", + Name: Ptr("foobar"), + DisplayName: Ptr("foobar"), + }, + }, + } + + if !cmp.Equal(got, want) { + t.Errorf("Codespaces.ListDevContainersConfig = %+v, want %+v", got, want) + } + + const methodName = "ListDevContainersConfig" + + testBadOptions(t, methodName, func() error { + _, _, err := client.Codespaces.ListDevContainersConfig(ctx, "\n", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.ListDevContainersConfig(ctx, "e", "r", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_GetDefaultAttributes(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/codespaces/new", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "billable_owner": { + "login": "user1", + "id": 1001, + "url": "https://example.com/user1" + }, + "defaults": { + "devcontainer_path": ".devcontainer/devcontainer.json", + "location": "WestUs2" + } + }`) + }) + + ctx := t.Context() + + opt := &CodespaceGetDefaultAttributesOptions{ + Ref: Ptr("main"), + ClientIP: Ptr("1.2.3.4"), + } + + got, _, err := client.Codespaces.GetDefaultAttributes(ctx, "o", "r", opt) + if err != nil { + t.Fatalf("Codespaces.GetDefaultAttributes returned error: %v", err) + } + + want := &CodespaceDefaultAttributes{ + BillableOwner: User{ + Login: Ptr("user1"), + ID: Ptr(int64(1001)), + URL: Ptr("https://example.com/user1"), + }, + Defaults: CodespaceDefaults{ + DevcontainerPath: Ptr(".devcontainer/devcontainer.json"), + Location: "WestUs2", + }, + } + + if !cmp.Equal(got, want) { + t.Errorf("Codespaces.GetDefaultAttributes = %+v, want %+v", got, want) + } + + const methodName = "GetDefaultAttributes" + + testBadOptions(t, methodName, func() error { + _, _, err := client.Codespaces.GetDefaultAttributes(ctx, "\n", "\n", opt) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.GetDefaultAttributes(ctx, "e", "r", opt) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_CheckPermissions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/codespaces/permissions_check", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"accepted": true}`) + }) + + ctx := t.Context() + hasPermission, _, err := client.Codespaces.CheckPermissions(ctx, "o", "r", "main", "path") + if err != nil { + t.Errorf("Codespaces.CheckPermissions returned error: %v", err) + } + + want := bool(true) + if !cmp.Equal(hasPermission, &want) { + t.Errorf("Codespaces.CheckPermissions = %+v, want %+v", hasPermission, want) + } + + const methodName = "CheckPermissions" + + testBadOptions(t, methodName, func() error { + _, _, err := client.Codespaces.CheckPermissions(ctx, "\n", "\n", "main", "path") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.CheckPermissions(ctx, "o", "r", "main", "path") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_CreateFromPullRequest(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/owner/repo/pulls/42/codespaces", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testBody(t, r, `{"machine":"standardLinux","idle_timeout_minutes":60}`+"\n") + fmt.Fprint(w, `{"id":1, "repository": {"id": 1}}`) + }) + input := &CreateCodespaceOptions{ + Machine: Ptr("standardLinux"), + IdleTimeoutMinutes: Ptr(60), + } + ctx := t.Context() + codespace, _, err := client.Codespaces.CreateFromPullRequest(ctx, "owner", "repo", 42, input) + if err != nil { + t.Errorf("Codespaces.CreateFromPullRequest returned error: %v", err) + } + want := &Codespace{ + ID: Ptr(int64(1)), + Repository: &Repository{ + ID: Ptr(int64(1)), + }, + } + + if !cmp.Equal(codespace, want) { + t.Errorf("Codespaces.CreateFromPullRequest returned %+v, want %+v", codespace, want) + } + + const methodName = "CreateFromPullRequest" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Codespaces.CreateFromPullRequest(ctx, "\n", "", 0, input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.CreateFromPullRequest(ctx, "o", "r", 42, input) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testBody( + t, + r, + `{"ref":"main","geo":"WestUs2","machine":"standardLinux","idle_timeout_minutes":60,"repository_id":111}`+"\n", + ) + fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) + }) + + opt := &CodespaceCreateForUserOptions{ + CreateCodespaceOptions: &CreateCodespaceOptions{ + Ref: Ptr("main"), + Geo: Ptr("WestUs2"), + Machine: Ptr("standardLinux"), + IdleTimeoutMinutes: Ptr(60), + }, + RepositoryID: int64(111), + } + + ctx := t.Context() + codespace, _, err := client.Codespaces.CreateForAuthenticatedUser( + ctx, + opt, + ) + if err != nil { + t.Fatalf("Codespaces.CreateForAuthenticatedUser returned error: %v", err) + } + + want := &Codespace{ + ID: Ptr(int64(1)), + Repository: &Repository{ + ID: Ptr(int64(111)), + }, + } + + if !cmp.Equal(codespace, want) { + t.Errorf("Codespaces.CreateForAuthenticatedUser returned %+v, want %+v", codespace, want) + } + + const methodName = "CreateForAuthenticatedUser" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.CreateForAuthenticatedUser( + ctx, + opt, + ) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_GetInfo(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces/codespace_1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) + }) + + ctx := t.Context() + codespace, _, err := client.Codespaces.GetInfo(ctx, "codespace_1") + if err != nil { + t.Fatalf("Codespaces.GetInfo returned error: %v", err) + } + + want := &Codespace{ + ID: Ptr(int64(1)), + Repository: &Repository{ + ID: Ptr(int64(111)), + }, + } + + if !cmp.Equal(codespace, want) { + t.Errorf("Codespaces.GetInfo returned %+v, want %+v", codespace, want) + } + + const methodName = "GetInfo" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.GetInfo(ctx, "codespace_1") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_Update(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces/codespace_1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + testBody( + t, + r, + `{"machine":"standardLinux","recent_folders":["folder1","folder2"]}`+"\n", + ) + fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) + }) + + opt := &UpdateCodespaceOptions{ + Machine: Ptr("standardLinux"), + RecentFolders: []string{ + "folder1", + "folder2", + }, + } + + ctx := t.Context() + codespace, _, err := client.Codespaces.Update( + ctx, + "codespace_1", + opt, + ) + if err != nil { + t.Fatalf("Codespaces.Update returned error: %v", err) + } + + want := &Codespace{ + ID: Ptr(int64(1)), + Repository: &Repository{ + ID: Ptr(int64(111)), + }, + } + + if !cmp.Equal(codespace, want) { + t.Errorf("Codespaces.Update returned %+v, want %+v", codespace, want) + } + + const methodName = "Update" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.Update( + ctx, + "codespace_1", + opt, + ) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_TriggerExport(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces/codespace_1/exports", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{ + "state": "succeeded", + "completed_at": "2025-12-11T00:00:00Z", + "branch": "main", + "export_url": "https://api.github.com/user/codespaces/:name/exports/latest" + }`) + }) + + ctx := t.Context() + export, _, err := client.Codespaces.TriggerExport(ctx, "codespace_1") + if err != nil { + t.Fatalf("Codespaces.TriggerExport returned error: %v", err) + } + + want := &CodespaceExport{ + State: Ptr("succeeded"), + CompletedAt: Ptr(Timestamp{Time: time.Date(2025, time.December, 11, 0, 0, 0, 0, time.UTC)}), + Branch: Ptr("main"), + ExportURL: Ptr("https://api.github.com/user/codespaces/:name/exports/latest"), + } + + if !cmp.Equal(export, want) { + t.Errorf("Codespaces.TriggerExport returned %+v, want %+v", export, want) + } + + const methodName = "TriggerExport" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.TriggerExport(ctx, "codespace_1") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_GetLatestExport(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces/codespace_1/exports/latest", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "state": "succeeded", + "completed_at": "2025-12-11T00:00:00Z", + "branch": "main", + "export_url": "https://api.github.com/user/codespaces/:name/exports/latest" + }`) + }) + + ctx := t.Context() + export, _, err := client.Codespaces.GetLatestExport(ctx, "codespace_1") + if err != nil { + t.Fatalf("Codespaces.GetLatestExport returned error: %v", err) + } + + want := &CodespaceExport{ + State: Ptr("succeeded"), + CompletedAt: Ptr(Timestamp{Time: time.Date(2025, time.December, 11, 0, 0, 0, 0, time.UTC)}), + Branch: Ptr("main"), + ExportURL: Ptr("https://api.github.com/user/codespaces/:name/exports/latest"), + } + + if !cmp.Equal(export, want) { + t.Errorf("Codespaces.GetLatestExport returned %+v, want %+v", export, want) + } + + const methodName = "GetLatestExport" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.GetLatestExport(ctx, "codespace_1") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestCodespacesService_PublishCodespace(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/user/codespaces/codespace_1/publish", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + testBody( + t, + r, + `{"name":"repo","private":true}`+"\n", + ) + fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) + }) + + opt := &PublishCodespaceOptions{ + Name: Ptr("repo"), + Private: Ptr(true), + } + + ctx := t.Context() + repo, _, err := client.Codespaces.PublishCodespace( + ctx, + "codespace_1", + opt, + ) + if err != nil { + t.Fatalf("Codespaces.PublishCodespace returned error: %v", err) + } + + want := &Codespace{ + ID: Ptr(int64(1)), + Repository: &Repository{ + ID: Ptr(int64(111)), + }, + } + if !cmp.Equal(repo, want) { + t.Errorf("Codespaces.PublishCodespace returned %+v, want %+v", repo, want) + } + + const methodName = "PublishCodespace" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Codespaces.PublishCodespace( + ctx, + "codespace_1", + opt, + ) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 6b7ec07c7e9..499cd2f48ad 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3734,6 +3734,86 @@ func (c *Codespace) GetWebURL() string { return *c.WebURL } +// GetDevcontainerPath returns the DevcontainerPath field if it's non-nil, zero value otherwise. +func (c *CodespaceDefaults) GetDevcontainerPath() string { + if c == nil || c.DevcontainerPath == nil { + return "" + } + return *c.DevcontainerPath +} + +// GetBranch returns the Branch field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetBranch() string { + if c == nil || c.Branch == nil { + return "" + } + return *c.Branch +} + +// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetCompletedAt() Timestamp { + if c == nil || c.CompletedAt == nil { + return Timestamp{} + } + return *c.CompletedAt +} + +// GetExportURL returns the ExportURL field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetExportURL() string { + if c == nil || c.ExportURL == nil { + return "" + } + return *c.ExportURL +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetHTMLURL() string { + if c == nil || c.HTMLURL == nil { + return "" + } + return *c.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetID() string { + if c == nil || c.ID == nil { + return "" + } + return *c.ID +} + +// GetSHA returns the SHA field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetSHA() string { + if c == nil || c.SHA == nil { + return "" + } + return *c.SHA +} + +// GetState returns the State field if it's non-nil, zero value otherwise. +func (c *CodespaceExport) GetState() string { + if c == nil || c.State == nil { + return "" + } + return *c.State +} + +// GetClientIP returns the ClientIP field if it's non-nil, zero value otherwise. +func (c *CodespaceGetDefaultAttributesOptions) GetClientIP() string { + if c == nil || c.ClientIP == nil { + return "" + } + return *c.ClientIP +} + +// GetRef returns the Ref field if it's non-nil, zero value otherwise. +func (c *CodespaceGetDefaultAttributesOptions) GetRef() string { + if c == nil || c.Ref == nil { + return "" + } + return *c.Ref +} + // GetAhead returns the Ahead field if it's non-nil, zero value otherwise. func (c *CodespacesGitStatus) GetAhead() int { if c == nil || c.Ahead == nil { @@ -6262,6 +6342,14 @@ func (c *CreateCodespaceOptions) GetIdleTimeoutMinutes() int { return *c.IdleTimeoutMinutes } +// GetLocation returns the Location field if it's non-nil, zero value otherwise. +func (c *CreateCodespaceOptions) GetLocation() string { + if c == nil || c.Location == nil { + return "" + } + return *c.Location +} + // GetMachine returns the Machine field if it's non-nil, zero value otherwise. func (c *CreateCodespaceOptions) GetMachine() string { if c == nil || c.Machine == nil { @@ -8462,6 +8550,22 @@ func (d *DeploymentStatusRequest) GetState() string { return *d.State } +// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. +func (d *DevContainer) GetDisplayName() string { + if d == nil || d.DisplayName == nil { + return "" + } + return *d.DisplayName +} + +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (d *DevContainer) GetName() string { + if d == nil || d.Name == nil { + return "" + } + return *d.Name +} + // GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise. func (d *Discussion) GetActiveLockReason() string { if d == nil || d.ActiveLockReason == nil { @@ -20174,6 +20278,22 @@ func (p *PublicKey) GetKeyID() string { return *p.KeyID } +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (p *PublishCodespaceOptions) GetName() string { + if p == nil || p.Name == nil { + return "" + } + return *p.Name +} + +// GetPrivate returns the Private field if it's non-nil, zero value otherwise. +func (p *PublishCodespaceOptions) GetPrivate() bool { + if p == nil || p.Private == nil { + return false + } + return *p.Private +} + // GetActiveLockReason returns the ActiveLockReason field if it's non-nil, zero value otherwise. func (p *PullRequest) GetActiveLockReason() string { if p == nil || p.ActiveLockReason == nil { @@ -29638,6 +29758,14 @@ func (u *UpdateCheckRunOptions) GetStatus() string { return *u.Status } +// GetMachine returns the Machine field if it's non-nil, zero value otherwise. +func (u *UpdateCodespaceOptions) GetMachine() string { + if u == nil || u.Machine == nil { + return "" + } + return *u.Machine +} + // GetQuerySuite returns the QuerySuite field if it's non-nil, zero value otherwise. func (u *UpdateDefaultSetupConfigurationOptions) GetQuerySuite() string { if u == nil || u.QuerySuite == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 766bc5f2593..4fcadafbbe8 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -4872,6 +4872,116 @@ func TestCodespace_GetWebURL(tt *testing.T) { c.GetWebURL() } +func TestCodespaceDefaults_GetDevcontainerPath(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceDefaults{DevcontainerPath: &zeroValue} + c.GetDevcontainerPath() + c = &CodespaceDefaults{} + c.GetDevcontainerPath() + c = nil + c.GetDevcontainerPath() +} + +func TestCodespaceExport_GetBranch(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{Branch: &zeroValue} + c.GetBranch() + c = &CodespaceExport{} + c.GetBranch() + c = nil + c.GetBranch() +} + +func TestCodespaceExport_GetCompletedAt(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + c := &CodespaceExport{CompletedAt: &zeroValue} + c.GetCompletedAt() + c = &CodespaceExport{} + c.GetCompletedAt() + c = nil + c.GetCompletedAt() +} + +func TestCodespaceExport_GetExportURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{ExportURL: &zeroValue} + c.GetExportURL() + c = &CodespaceExport{} + c.GetExportURL() + c = nil + c.GetExportURL() +} + +func TestCodespaceExport_GetHTMLURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{HTMLURL: &zeroValue} + c.GetHTMLURL() + c = &CodespaceExport{} + c.GetHTMLURL() + c = nil + c.GetHTMLURL() +} + +func TestCodespaceExport_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{ID: &zeroValue} + c.GetID() + c = &CodespaceExport{} + c.GetID() + c = nil + c.GetID() +} + +func TestCodespaceExport_GetSHA(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{SHA: &zeroValue} + c.GetSHA() + c = &CodespaceExport{} + c.GetSHA() + c = nil + c.GetSHA() +} + +func TestCodespaceExport_GetState(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceExport{State: &zeroValue} + c.GetState() + c = &CodespaceExport{} + c.GetState() + c = nil + c.GetState() +} + +func TestCodespaceGetDefaultAttributesOptions_GetClientIP(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceGetDefaultAttributesOptions{ClientIP: &zeroValue} + c.GetClientIP() + c = &CodespaceGetDefaultAttributesOptions{} + c.GetClientIP() + c = nil + c.GetClientIP() +} + +func TestCodespaceGetDefaultAttributesOptions_GetRef(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceGetDefaultAttributesOptions{Ref: &zeroValue} + c.GetRef() + c = &CodespaceGetDefaultAttributesOptions{} + c.GetRef() + c = nil + c.GetRef() +} + func TestCodespacesGitStatus_GetAhead(tt *testing.T) { tt.Parallel() var zeroValue int @@ -8174,6 +8284,17 @@ func TestCreateCodespaceOptions_GetIdleTimeoutMinutes(tt *testing.T) { c.GetIdleTimeoutMinutes() } +func TestCreateCodespaceOptions_GetLocation(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CreateCodespaceOptions{Location: &zeroValue} + c.GetLocation() + c = &CreateCodespaceOptions{} + c.GetLocation() + c = nil + c.GetLocation() +} + func TestCreateCodespaceOptions_GetMachine(tt *testing.T) { tt.Parallel() var zeroValue string @@ -10974,6 +11095,28 @@ func TestDeploymentStatusRequest_GetState(tt *testing.T) { d.GetState() } +func TestDevContainer_GetDisplayName(tt *testing.T) { + tt.Parallel() + var zeroValue string + d := &DevContainer{DisplayName: &zeroValue} + d.GetDisplayName() + d = &DevContainer{} + d.GetDisplayName() + d = nil + d.GetDisplayName() +} + +func TestDevContainer_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + d := &DevContainer{Name: &zeroValue} + d.GetName() + d = &DevContainer{} + d.GetName() + d = nil + d.GetName() +} + func TestDiscussion_GetActiveLockReason(tt *testing.T) { tt.Parallel() var zeroValue string @@ -26130,6 +26273,28 @@ func TestPublicKey_GetKeyID(tt *testing.T) { p.GetKeyID() } +func TestPublishCodespaceOptions_GetName(tt *testing.T) { + tt.Parallel() + var zeroValue string + p := &PublishCodespaceOptions{Name: &zeroValue} + p.GetName() + p = &PublishCodespaceOptions{} + p.GetName() + p = nil + p.GetName() +} + +func TestPublishCodespaceOptions_GetPrivate(tt *testing.T) { + tt.Parallel() + var zeroValue bool + p := &PublishCodespaceOptions{Private: &zeroValue} + p.GetPrivate() + p = &PublishCodespaceOptions{} + p.GetPrivate() + p = nil + p.GetPrivate() +} + func TestPullRequest_GetActiveLockReason(tt *testing.T) { tt.Parallel() var zeroValue string @@ -38189,6 +38354,17 @@ func TestUpdateCheckRunOptions_GetStatus(tt *testing.T) { u.GetStatus() } +func TestUpdateCodespaceOptions_GetMachine(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UpdateCodespaceOptions{Machine: &zeroValue} + u.GetMachine() + u = &UpdateCodespaceOptions{} + u.GetMachine() + u = nil + u.GetMachine() +} + func TestUpdateDefaultSetupConfigurationOptions_GetQuerySuite(tt *testing.T) { tt.Parallel() var zeroValue string From 58be399af1903e6ff6f98eec5f35ad5172795e75 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 17 Dec 2025 14:59:44 +0000 Subject: [PATCH 2/7] remove unnecessary blank line, fix comments, fix struct and CheckPermissions now returns a struct --- github/codespaces.go | 52 ++++++------ github/codespaces_test.go | 21 +++-- github/github-accessors.go | 112 ++++++++++++++++++++++++ github/github-accessors_test.go | 145 ++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+), 38 deletions(-) diff --git a/github/codespaces.go b/github/codespaces.go index 5dc2aea06bc..8c97ec7d05f 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -178,13 +178,13 @@ type DevContainer struct { DisplayName *string `json:"display_name,omitempty"` } -// DevContainersConfig represents list of devcontainer configuration in a repository. +// DevContainersConfig represents a list of devcontainer configurations in a repository. type DevContainersConfig struct { Devcontainers []*DevContainer `json:"devcontainers"` TotalCount int64 `json:"total_count"` } -// CodespaceDefaults represents the a field for DefaultAttributes. +// CodespaceDefaults represents default settings for a Codespace. type CodespaceDefaults struct { DevcontainerPath *string `json:"devcontainer_path,omitempty"` Location string `json:"location"` @@ -192,8 +192,8 @@ type CodespaceDefaults struct { // CodespaceDefaultAttributes represents the default attributes for codespaces created by the user with the repository. type CodespaceDefaultAttributes struct { - BillableOwner User `json:"billable_owner"` - Defaults CodespaceDefaults `json:"defaults"` + BillableOwner *User `json:"billable_owner"` + Defaults *CodespaceDefaults `json:"defaults"` } // CodespaceGetDefaultAttributesOptions represents options for getting default attributes for a codespace. @@ -204,7 +204,7 @@ type CodespaceGetDefaultAttributesOptions struct { ClientIP *string `url:"client_ip,omitempty"` } -// CodespacePullRequestOptions represents a field for CodespaceCreateForUserOptions. +// CodespacePullRequestOptions represents options for a CodespacePullRequest. type CodespacePullRequestOptions struct { // PullRequestNumber represents the pull request number. PullRequestNumber int64 `json:"pull_request_number"` @@ -214,8 +214,18 @@ type CodespacePullRequestOptions struct { // CodespaceCreateForUserOptions represents options for creating a codespace for the authenticated user. type CodespaceCreateForUserOptions struct { - *CreateCodespaceOptions - *CodespacePullRequestOptions + Ref *string `json:"ref,omitempty"` + Geo *string `json:"geo,omitempty"` + ClientIP *string `json:"client_ip,omitempty"` + RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"` + Location *string `json:"location,omitempty"` + PullRequest *CodespacePullRequestOptions `json:"pull_request"` + Machine *string `json:"machine,omitempty"` + DevcontainerPath *string `json:"devcontainer_path,omitempty"` + MultiRepoPermissionsOptOut *bool `json:"multi_repo_permissions_opt_out,omitempty"` + WorkingDirectory *string `json:"working_directory,omitempty"` + IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"` + DisplayName *string `json:"display_name,omitempty"` // RepositoryID represents the repository ID for this codespace. RepositoryID int64 `json:"repository_id"` } @@ -249,6 +259,11 @@ type PublishCodespaceOptions struct { Private *bool `json:"private,omitempty"` } +// CodespacePermissions represents a response indicating whether the permissions defined by a devcontainer have been accepted. +type CodespacePermissions struct { + Accepted bool `json:"accepted"` +} + // CreateInRepo creates a codespace in a repository. // // Creates a codespace owned by the authenticated user in the specified repository. @@ -260,7 +275,6 @@ type PublishCodespaceOptions struct { //meta:operation POST /repos/{owner}/{repo}/codespaces func (s *CodespacesService) CreateInRepo(ctx context.Context, owner, repo string, request *CreateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces", owner, repo) - req, err := s.client.NewRequest("POST", u, request) if err != nil { return nil, nil, err @@ -285,7 +299,6 @@ func (s *CodespacesService) CreateInRepo(ctx context.Context, owner, repo string //meta:operation POST /user/codespaces/{codespace_name}/start func (s *CodespacesService) Start(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/start", codespaceName) - req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, nil, err @@ -310,7 +323,6 @@ func (s *CodespacesService) Start(ctx context.Context, codespaceName string) (*C //meta:operation POST /user/codespaces/{codespace_name}/stop func (s *CodespacesService) Stop(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/stop", codespaceName) - req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, nil, err @@ -335,7 +347,6 @@ func (s *CodespacesService) Stop(ctx context.Context, codespaceName string) (*Co //meta:operation DELETE /user/codespaces/{codespace_name} func (s *CodespacesService) Delete(ctx context.Context, codespaceName string) (*Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) - req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -351,7 +362,6 @@ func (s *CodespacesService) Delete(ctx context.Context, codespaceName string) (* //meta:operation GET /repos/{owner}/{repo}/codespaces/devcontainers func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, repo string, opt *ListOptions) (*DevContainersConfig, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces/devcontainers", owner, repo) - u, err := addOptions(u, opt) if err != nil { return nil, nil, err @@ -378,7 +388,6 @@ func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, //meta:operation GET /repos/{owner}/{repo}/codespaces/new func (s *CodespacesService) GetDefaultAttributes(ctx context.Context, owner, repo string, opt *CodespaceGetDefaultAttributesOptions) (*CodespaceDefaultAttributes, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces/new", owner, repo) - u, err := addOptions(u, opt) if err != nil { return nil, nil, err @@ -403,9 +412,8 @@ func (s *CodespacesService) GetDefaultAttributes(ctx context.Context, owner, rep // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#check-if-permissions-defined-by-a-devcontainer-have-been-accepted-by-the-authenticated-user // //meta:operation GET /repos/{owner}/{repo}/codespaces/permissions_check -func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, ref, devcontainerPath string) (*bool, *Response, error) { +func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, ref, devcontainerPath string) (*CodespacePermissions, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces/permissions_check", owner, repo) - u, err := addOptions(u, &struct { Ref string `url:"ref"` DevcontainerPath string `url:"devcontainer_path"` @@ -422,16 +430,13 @@ func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, r return nil, nil, err } - var hasPermission struct { - Accepted *bool `json:"accepted,omitempty"` - } - + var hasPermission *CodespacePermissions resp, err := s.client.Do(ctx, req, &hasPermission) if err != nil { return nil, resp, err } - return hasPermission.Accepted, resp, nil + return hasPermission, resp, nil } // CreateFromPullRequest creates a codespace owned by the authenticated user for the specified pull request. @@ -441,7 +446,6 @@ func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, r //meta:operation POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, opt *CreateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%v/codespaces", owner, repo, pullNumber) - req, err := s.client.NewRequest("POST", u, opt) if err != nil { return nil, nil, err @@ -465,7 +469,6 @@ func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, re //meta:operation POST /user/codespaces func (s *CodespacesService) CreateForAuthenticatedUser(ctx context.Context, opt *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { u := "user/codespaces" - req, err := s.client.NewRequest("POST", u, opt) if err != nil { return nil, nil, err @@ -487,7 +490,6 @@ func (s *CodespacesService) CreateForAuthenticatedUser(ctx context.Context, opt //meta:operation GET /user/codespaces/{codespace_name} func (s *CodespacesService) GetInfo(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) - req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -511,7 +513,6 @@ func (s *CodespacesService) GetInfo(ctx context.Context, codespaceName string) ( //meta:operation PATCH /user/codespaces/{codespace_name} func (s *CodespacesService) Update(ctx context.Context, codespaceName string, opt *UpdateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) - req, err := s.client.NewRequest("PATCH", u, opt) if err != nil { return nil, nil, err @@ -533,7 +534,6 @@ func (s *CodespacesService) Update(ctx context.Context, codespaceName string, op //meta:operation POST /user/codespaces/{codespace_name}/exports func (s *CodespacesService) TriggerExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/exports", codespaceName) - req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, nil, err @@ -555,7 +555,6 @@ func (s *CodespacesService) TriggerExport(ctx context.Context, codespaceName str //meta:operation GET /user/codespaces/{codespace_name}/exports/{export_id} func (s *CodespacesService) GetLatestExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/exports/latest", codespaceName) - req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -577,7 +576,6 @@ func (s *CodespacesService) GetLatestExport(ctx context.Context, codespaceName s //meta:operation POST /user/codespaces/{codespace_name}/publish func (s *CodespacesService) PublishCodespace(ctx context.Context, codespaceName string, opt *PublishCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/publish", codespaceName) - req, err := s.client.NewRequest("POST", u, opt) if err != nil { return nil, nil, err diff --git a/github/codespaces_test.go b/github/codespaces_test.go index 2521a91fa1a..d27751f26ce 100644 --- a/github/codespaces_test.go +++ b/github/codespaces_test.go @@ -379,12 +379,12 @@ func TestCodespacesService_GetDefaultAttributes(t *testing.T) { } want := &CodespaceDefaultAttributes{ - BillableOwner: User{ + BillableOwner: &User{ Login: Ptr("user1"), ID: Ptr(int64(1001)), URL: Ptr("https://example.com/user1"), }, - Defaults: CodespaceDefaults{ + Defaults: &CodespaceDefaults{ DevcontainerPath: Ptr(".devcontainer/devcontainer.json"), Location: "WestUs2", }, @@ -425,7 +425,7 @@ func TestCodespacesService_CheckPermissions(t *testing.T) { t.Errorf("Codespaces.CheckPermissions returned error: %v", err) } - want := bool(true) + want := CodespacePermissions{Accepted: true} if !cmp.Equal(hasPermission, &want) { t.Errorf("Codespaces.CheckPermissions = %+v, want %+v", hasPermission, want) } @@ -499,19 +499,18 @@ func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { testBody( t, r, - `{"ref":"main","geo":"WestUs2","machine":"standardLinux","idle_timeout_minutes":60,"repository_id":111}`+"\n", + `{"ref":"main","geo":"WestUs2","pull_request":null,"machine":"standardLinux","idle_timeout_minutes":60,"repository_id":111}`+"\n", ) fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) }) opt := &CodespaceCreateForUserOptions{ - CreateCodespaceOptions: &CreateCodespaceOptions{ - Ref: Ptr("main"), - Geo: Ptr("WestUs2"), - Machine: Ptr("standardLinux"), - IdleTimeoutMinutes: Ptr(60), - }, - RepositoryID: int64(111), + Ref: Ptr("main"), + Geo: Ptr("WestUs2"), + Machine: Ptr("standardLinux"), + IdleTimeoutMinutes: Ptr(60), + RepositoryID: int64(111), + PullRequest: nil, } ctx := t.Context() diff --git a/github/github-accessors.go b/github/github-accessors.go index 499cd2f48ad..43d0e2e3d5c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -3734,6 +3734,118 @@ func (c *Codespace) GetWebURL() string { return *c.WebURL } +// GetClientIP returns the ClientIP field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetClientIP() string { + if c == nil || c.ClientIP == nil { + return "" + } + return *c.ClientIP +} + +// GetDevcontainerPath returns the DevcontainerPath field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetDevcontainerPath() string { + if c == nil || c.DevcontainerPath == nil { + return "" + } + return *c.DevcontainerPath +} + +// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetDisplayName() string { + if c == nil || c.DisplayName == nil { + return "" + } + return *c.DisplayName +} + +// GetGeo returns the Geo field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetGeo() string { + if c == nil || c.Geo == nil { + return "" + } + return *c.Geo +} + +// GetIdleTimeoutMinutes returns the IdleTimeoutMinutes field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetIdleTimeoutMinutes() int { + if c == nil || c.IdleTimeoutMinutes == nil { + return 0 + } + return *c.IdleTimeoutMinutes +} + +// GetLocation returns the Location field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetLocation() string { + if c == nil || c.Location == nil { + return "" + } + return *c.Location +} + +// GetMachine returns the Machine field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetMachine() string { + if c == nil || c.Machine == nil { + return "" + } + return *c.Machine +} + +// GetMultiRepoPermissionsOptOut returns the MultiRepoPermissionsOptOut field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetMultiRepoPermissionsOptOut() bool { + if c == nil || c.MultiRepoPermissionsOptOut == nil { + return false + } + return *c.MultiRepoPermissionsOptOut +} + +// GetPullRequest returns the PullRequest field. +func (c *CodespaceCreateForUserOptions) GetPullRequest() *CodespacePullRequestOptions { + if c == nil { + return nil + } + return c.PullRequest +} + +// GetRef returns the Ref field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetRef() string { + if c == nil || c.Ref == nil { + return "" + } + return *c.Ref +} + +// GetRetentionPeriodMinutes returns the RetentionPeriodMinutes field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetRetentionPeriodMinutes() int { + if c == nil || c.RetentionPeriodMinutes == nil { + return 0 + } + return *c.RetentionPeriodMinutes +} + +// GetWorkingDirectory returns the WorkingDirectory field if it's non-nil, zero value otherwise. +func (c *CodespaceCreateForUserOptions) GetWorkingDirectory() string { + if c == nil || c.WorkingDirectory == nil { + return "" + } + return *c.WorkingDirectory +} + +// GetBillableOwner returns the BillableOwner field. +func (c *CodespaceDefaultAttributes) GetBillableOwner() *User { + if c == nil { + return nil + } + return c.BillableOwner +} + +// GetDefaults returns the Defaults field. +func (c *CodespaceDefaultAttributes) GetDefaults() *CodespaceDefaults { + if c == nil { + return nil + } + return c.Defaults +} + // GetDevcontainerPath returns the DevcontainerPath field if it's non-nil, zero value otherwise. func (c *CodespaceDefaults) GetDevcontainerPath() string { if c == nil || c.DevcontainerPath == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 4fcadafbbe8..78249314e47 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -4872,6 +4872,151 @@ func TestCodespace_GetWebURL(tt *testing.T) { c.GetWebURL() } +func TestCodespaceCreateForUserOptions_GetClientIP(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{ClientIP: &zeroValue} + c.GetClientIP() + c = &CodespaceCreateForUserOptions{} + c.GetClientIP() + c = nil + c.GetClientIP() +} + +func TestCodespaceCreateForUserOptions_GetDevcontainerPath(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{DevcontainerPath: &zeroValue} + c.GetDevcontainerPath() + c = &CodespaceCreateForUserOptions{} + c.GetDevcontainerPath() + c = nil + c.GetDevcontainerPath() +} + +func TestCodespaceCreateForUserOptions_GetDisplayName(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{DisplayName: &zeroValue} + c.GetDisplayName() + c = &CodespaceCreateForUserOptions{} + c.GetDisplayName() + c = nil + c.GetDisplayName() +} + +func TestCodespaceCreateForUserOptions_GetGeo(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{Geo: &zeroValue} + c.GetGeo() + c = &CodespaceCreateForUserOptions{} + c.GetGeo() + c = nil + c.GetGeo() +} + +func TestCodespaceCreateForUserOptions_GetIdleTimeoutMinutes(tt *testing.T) { + tt.Parallel() + var zeroValue int + c := &CodespaceCreateForUserOptions{IdleTimeoutMinutes: &zeroValue} + c.GetIdleTimeoutMinutes() + c = &CodespaceCreateForUserOptions{} + c.GetIdleTimeoutMinutes() + c = nil + c.GetIdleTimeoutMinutes() +} + +func TestCodespaceCreateForUserOptions_GetLocation(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{Location: &zeroValue} + c.GetLocation() + c = &CodespaceCreateForUserOptions{} + c.GetLocation() + c = nil + c.GetLocation() +} + +func TestCodespaceCreateForUserOptions_GetMachine(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{Machine: &zeroValue} + c.GetMachine() + c = &CodespaceCreateForUserOptions{} + c.GetMachine() + c = nil + c.GetMachine() +} + +func TestCodespaceCreateForUserOptions_GetMultiRepoPermissionsOptOut(tt *testing.T) { + tt.Parallel() + var zeroValue bool + c := &CodespaceCreateForUserOptions{MultiRepoPermissionsOptOut: &zeroValue} + c.GetMultiRepoPermissionsOptOut() + c = &CodespaceCreateForUserOptions{} + c.GetMultiRepoPermissionsOptOut() + c = nil + c.GetMultiRepoPermissionsOptOut() +} + +func TestCodespaceCreateForUserOptions_GetPullRequest(tt *testing.T) { + tt.Parallel() + c := &CodespaceCreateForUserOptions{} + c.GetPullRequest() + c = nil + c.GetPullRequest() +} + +func TestCodespaceCreateForUserOptions_GetRef(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{Ref: &zeroValue} + c.GetRef() + c = &CodespaceCreateForUserOptions{} + c.GetRef() + c = nil + c.GetRef() +} + +func TestCodespaceCreateForUserOptions_GetRetentionPeriodMinutes(tt *testing.T) { + tt.Parallel() + var zeroValue int + c := &CodespaceCreateForUserOptions{RetentionPeriodMinutes: &zeroValue} + c.GetRetentionPeriodMinutes() + c = &CodespaceCreateForUserOptions{} + c.GetRetentionPeriodMinutes() + c = nil + c.GetRetentionPeriodMinutes() +} + +func TestCodespaceCreateForUserOptions_GetWorkingDirectory(tt *testing.T) { + tt.Parallel() + var zeroValue string + c := &CodespaceCreateForUserOptions{WorkingDirectory: &zeroValue} + c.GetWorkingDirectory() + c = &CodespaceCreateForUserOptions{} + c.GetWorkingDirectory() + c = nil + c.GetWorkingDirectory() +} + +func TestCodespaceDefaultAttributes_GetBillableOwner(tt *testing.T) { + tt.Parallel() + c := &CodespaceDefaultAttributes{} + c.GetBillableOwner() + c = nil + c.GetBillableOwner() +} + +func TestCodespaceDefaultAttributes_GetDefaults(tt *testing.T) { + tt.Parallel() + c := &CodespaceDefaultAttributes{} + c.GetDefaults() + c = nil + c.GetDefaults() +} + func TestCodespaceDefaults_GetDevcontainerPath(tt *testing.T) { tt.Parallel() var zeroValue string From 6464d6a11029ad80bdae19ae501c44a2212190c7 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 17 Dec 2025 15:21:24 +0000 Subject: [PATCH 3/7] change order in field --- github/codespaces.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/github/codespaces.go b/github/codespaces.go index 8c97ec7d05f..db8eb6b7a1d 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -186,8 +186,8 @@ type DevContainersConfig struct { // CodespaceDefaults represents default settings for a Codespace. type CodespaceDefaults struct { - DevcontainerPath *string `json:"devcontainer_path,omitempty"` Location string `json:"location"` + DevcontainerPath *string `json:"devcontainer_path,omitempty"` } // CodespaceDefaultAttributes represents the default attributes for codespaces created by the user with the repository. @@ -214,20 +214,20 @@ type CodespacePullRequestOptions struct { // CodespaceCreateForUserOptions represents options for creating a codespace for the authenticated user. type CodespaceCreateForUserOptions struct { - Ref *string `json:"ref,omitempty"` - Geo *string `json:"geo,omitempty"` - ClientIP *string `json:"client_ip,omitempty"` - RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"` - Location *string `json:"location,omitempty"` - PullRequest *CodespacePullRequestOptions `json:"pull_request"` - Machine *string `json:"machine,omitempty"` - DevcontainerPath *string `json:"devcontainer_path,omitempty"` - MultiRepoPermissionsOptOut *bool `json:"multi_repo_permissions_opt_out,omitempty"` - WorkingDirectory *string `json:"working_directory,omitempty"` - IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"` - DisplayName *string `json:"display_name,omitempty"` + PullRequest *CodespacePullRequestOptions `json:"pull_request"` // RepositoryID represents the repository ID for this codespace. - RepositoryID int64 `json:"repository_id"` + RepositoryID int64 `json:"repository_id"` + Ref *string `json:"ref,omitempty"` + Geo *string `json:"geo,omitempty"` + ClientIP *string `json:"client_ip,omitempty"` + RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"` + Location *string `json:"location,omitempty"` + Machine *string `json:"machine,omitempty"` + DevcontainerPath *string `json:"devcontainer_path,omitempty"` + MultiRepoPermissionsOptOut *bool `json:"multi_repo_permissions_opt_out,omitempty"` + WorkingDirectory *string `json:"working_directory,omitempty"` + IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"` + DisplayName *string `json:"display_name,omitempty"` } // UpdateCodespaceOptions represents options for updating a codespace. From ccf76775744d32906cef4bc34eaedba8dd45a309 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 17 Dec 2025 15:33:51 +0000 Subject: [PATCH 4/7] fix test --- github/codespaces_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/codespaces_test.go b/github/codespaces_test.go index d27751f26ce..e1370033f44 100644 --- a/github/codespaces_test.go +++ b/github/codespaces_test.go @@ -499,7 +499,7 @@ func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { testBody( t, r, - `{"ref":"main","geo":"WestUs2","pull_request":null,"machine":"standardLinux","idle_timeout_minutes":60,"repository_id":111}`+"\n", + `{"pull_request":null,"repository_id":111,"ref":"main","geo":"WestUs2","machine":"standardLinux","idle_timeout_minutes":60}`+"\n", ) fmt.Fprint(w, `{"id":1,"repository":{"id":111}}`) }) From 5859f8c1d908bc7ba4c9f48c446a0819bef60efa Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Wed, 17 Dec 2025 16:52:45 +0000 Subject: [PATCH 5/7] change method name and opt to opts --- github/codespaces.go | 46 ++++++++++++++-------------- github/codespaces_test.go | 64 +++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/github/codespaces.go b/github/codespaces.go index db8eb6b7a1d..9f7e36dc15e 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -178,8 +178,8 @@ type DevContainer struct { DisplayName *string `json:"display_name,omitempty"` } -// DevContainersConfig represents a list of devcontainer configurations in a repository. -type DevContainersConfig struct { +// DevContainerConfigurations represents a list of devcontainer configurations in a repository. +type DevContainerConfigurations struct { Devcontainers []*DevContainer `json:"devcontainers"` TotalCount int64 `json:"total_count"` } @@ -355,14 +355,14 @@ func (s *CodespacesService) Delete(ctx context.Context, codespaceName string) (* return s.client.Do(ctx, req, nil) } -// ListDevContainersConfig lists devcontainer configurations in a repository for the authenticated user. +// ListDevContainerConfigurations lists devcontainer configurations in a repository for the authenticated user. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#list-devcontainer-configurations-in-a-repository-for-the-authenticated-user // //meta:operation GET /repos/{owner}/{repo}/codespaces/devcontainers -func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, repo string, opt *ListOptions) (*DevContainersConfig, *Response, error) { +func (s *CodespacesService) ListDevContainerConfigurations(ctx context.Context, owner, repo string, opts *ListOptions) (*DevContainerConfigurations, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces/devcontainers", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -372,7 +372,7 @@ func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, return nil, nil, err } - var devcontainers *DevContainersConfig + var devcontainers *DevContainerConfigurations resp, err := s.client.Do(ctx, req, &devcontainers) if err != nil { return nil, resp, err @@ -386,9 +386,9 @@ func (s *CodespacesService) ListDevContainersConfig(ctx context.Context, owner, // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-default-attributes-for-a-codespace // //meta:operation GET /repos/{owner}/{repo}/codespaces/new -func (s *CodespacesService) GetDefaultAttributes(ctx context.Context, owner, repo string, opt *CodespaceGetDefaultAttributesOptions) (*CodespaceDefaultAttributes, *Response, error) { +func (s *CodespacesService) GetDefaultAttributes(ctx context.Context, owner, repo string, opts *CodespaceGetDefaultAttributesOptions) (*CodespaceDefaultAttributes, *Response, error) { u := fmt.Sprintf("repos/%v/%v/codespaces/new", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } @@ -444,9 +444,9 @@ func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, r // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-from-a-pull-request // //meta:operation POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces -func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, opt *CreateCodespaceOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, opts *CreateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%v/codespaces", owner, repo, pullNumber) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -460,16 +460,16 @@ func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, re return codespace, resp, nil } -// CreateForAuthenticatedUser creates a new codespace, owned by the authenticated user. +// CreateCodespace creates a new codespace, owned by the authenticated user. // // This method requires either RepositoryId OR a PullRequest but not both. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-for-the-authenticated-user // //meta:operation POST /user/codespaces -func (s *CodespacesService) CreateForAuthenticatedUser(ctx context.Context, opt *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) CreateCodespace(ctx context.Context, opts *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { u := "user/codespaces" - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } @@ -483,12 +483,12 @@ func (s *CodespacesService) CreateForAuthenticatedUser(ctx context.Context, opt return codespace, resp, nil } -// GetInfo gets information about a user's codespace. +// GetCodespace gets information about a user's codespace. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-a-codespace-for-the-authenticated-user // //meta:operation GET /user/codespaces/{codespace_name} -func (s *CodespacesService) GetInfo(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { +func (s *CodespacesService) GetCodespace(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -511,9 +511,9 @@ func (s *CodespacesService) GetInfo(ctx context.Context, codespaceName string) ( // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#update-a-codespace-for-the-authenticated-user // //meta:operation PATCH /user/codespaces/{codespace_name} -func (s *CodespacesService) Update(ctx context.Context, codespaceName string, opt *UpdateCodespaceOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) Update(ctx context.Context, codespaceName string, opts *UpdateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) - req, err := s.client.NewRequest("PATCH", u, opt) + req, err := s.client.NewRequest("PATCH", u, opts) if err != nil { return nil, nil, err } @@ -527,12 +527,12 @@ func (s *CodespacesService) Update(ctx context.Context, codespaceName string, op return codespace, resp, nil } -// TriggerExport triggers an export of the specified codespace and returns a URL and ID where the status of the export can be monitored. +// ExportCodespace triggers an export of the specified codespace and returns a URL and ID where the status of the export can be monitored. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#export-a-codespace-for-the-authenticated-user // //meta:operation POST /user/codespaces/{codespace_name}/exports -func (s *CodespacesService) TriggerExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { +func (s *CodespacesService) ExportCodespace(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/exports", codespaceName) req, err := s.client.NewRequest("POST", u, nil) if err != nil { @@ -548,12 +548,12 @@ func (s *CodespacesService) TriggerExport(ctx context.Context, codespaceName str return codespace, resp, nil } -// GetLatestExport gets information about an export of a codespace. +// GetLatestCodespaceExport gets information about an export of a codespace. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-details-about-a-codespace-export // //meta:operation GET /user/codespaces/{codespace_name}/exports/{export_id} -func (s *CodespacesService) GetLatestExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { +func (s *CodespacesService) GetLatestCodespaceExport(ctx context.Context, codespaceName string) (*CodespaceExport, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/exports/latest", codespaceName) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -574,9 +574,9 @@ func (s *CodespacesService) GetLatestExport(ctx context.Context, codespaceName s // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-repository-from-an-unpublished-codespace // //meta:operation POST /user/codespaces/{codespace_name}/publish -func (s *CodespacesService) PublishCodespace(ctx context.Context, codespaceName string, opt *PublishCodespaceOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) PublishCodespace(ctx context.Context, codespaceName string, opts *PublishCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/publish", codespaceName) - req, err := s.client.NewRequest("POST", u, opt) + req, err := s.client.NewRequest("POST", u, opts) if err != nil { return nil, nil, err } diff --git a/github/codespaces_test.go b/github/codespaces_test.go index e1370033f44..efd090df3a3 100644 --- a/github/codespaces_test.go +++ b/github/codespaces_test.go @@ -292,7 +292,7 @@ func TestCodespacesService_Delete(t *testing.T) { }) } -func TestCodespacesService_ListDevContainersConfig(t *testing.T) { +func TestCodespacesService_ListDevContainerConfigurations(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -311,12 +311,12 @@ func TestCodespacesService_ListDevContainersConfig(t *testing.T) { ctx := t.Context() opts := &ListOptions{Page: 1, PerPage: 10} - got, _, err := client.Codespaces.ListDevContainersConfig(ctx, "o", "r", opts) + got, _, err := client.Codespaces.ListDevContainerConfigurations(ctx, "o", "r", opts) if err != nil { - t.Fatalf("Codespaces.ListDevContainersConfig returned error: %v", err) + t.Fatalf("Codespaces.ListDevContainerConfigurations returned error: %v", err) } - want := &DevContainersConfig{ + want := &DevContainerConfigurations{ TotalCount: 1, Devcontainers: []*DevContainer{ { @@ -328,18 +328,18 @@ func TestCodespacesService_ListDevContainersConfig(t *testing.T) { } if !cmp.Equal(got, want) { - t.Errorf("Codespaces.ListDevContainersConfig = %+v, want %+v", got, want) + t.Errorf("Codespaces.ListDevContainerConfigurations = %+v, want %+v", got, want) } - const methodName = "ListDevContainersConfig" + const methodName = "ListDevContainerConfigurations" testBadOptions(t, methodName, func() error { - _, _, err := client.Codespaces.ListDevContainersConfig(ctx, "\n", "\n", opts) + _, _, err := client.Codespaces.ListDevContainerConfigurations(ctx, "\n", "\n", opts) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.ListDevContainersConfig(ctx, "e", "r", opts) + got, resp, err := client.Codespaces.ListDevContainerConfigurations(ctx, "e", "r", opts) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -490,7 +490,7 @@ func TestCodespacesService_CreateFromPullRequest(t *testing.T) { }) } -func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { +func TestCodespacesService_CreateCodespace(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -514,12 +514,12 @@ func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { } ctx := t.Context() - codespace, _, err := client.Codespaces.CreateForAuthenticatedUser( + codespace, _, err := client.Codespaces.CreateCodespace( ctx, opt, ) if err != nil { - t.Fatalf("Codespaces.CreateForAuthenticatedUser returned error: %v", err) + t.Fatalf("Codespaces.CreateCodespace returned error: %v", err) } want := &Codespace{ @@ -530,12 +530,12 @@ func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { } if !cmp.Equal(codespace, want) { - t.Errorf("Codespaces.CreateForAuthenticatedUser returned %+v, want %+v", codespace, want) + t.Errorf("Codespaces.CreateCodespace returned %+v, want %+v", codespace, want) } - const methodName = "CreateForAuthenticatedUser" + const methodName = "CreateCodespace" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.CreateForAuthenticatedUser( + got, resp, err := client.Codespaces.CreateCodespace( ctx, opt, ) @@ -546,7 +546,7 @@ func TestCodespacesService_CreateForAuthenticatedUser(t *testing.T) { }) } -func TestCodespacesService_GetInfo(t *testing.T) { +func TestCodespacesService_GetCodespace(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -556,9 +556,9 @@ func TestCodespacesService_GetInfo(t *testing.T) { }) ctx := t.Context() - codespace, _, err := client.Codespaces.GetInfo(ctx, "codespace_1") + codespace, _, err := client.Codespaces.GetCodespace(ctx, "codespace_1") if err != nil { - t.Fatalf("Codespaces.GetInfo returned error: %v", err) + t.Fatalf("Codespaces.GetCodespace returned error: %v", err) } want := &Codespace{ @@ -569,12 +569,12 @@ func TestCodespacesService_GetInfo(t *testing.T) { } if !cmp.Equal(codespace, want) { - t.Errorf("Codespaces.GetInfo returned %+v, want %+v", codespace, want) + t.Errorf("Codespaces.GetCodespace returned %+v, want %+v", codespace, want) } - const methodName = "GetInfo" + const methodName = "GetCodespace" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.GetInfo(ctx, "codespace_1") + got, resp, err := client.Codespaces.GetCodespace(ctx, "codespace_1") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -639,7 +639,7 @@ func TestCodespacesService_Update(t *testing.T) { }) } -func TestCodespacesService_TriggerExport(t *testing.T) { +func TestCodespacesService_ExportCodespace(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -654,9 +654,9 @@ func TestCodespacesService_TriggerExport(t *testing.T) { }) ctx := t.Context() - export, _, err := client.Codespaces.TriggerExport(ctx, "codespace_1") + export, _, err := client.Codespaces.ExportCodespace(ctx, "codespace_1") if err != nil { - t.Fatalf("Codespaces.TriggerExport returned error: %v", err) + t.Fatalf("Codespaces.ExportCodespace returned error: %v", err) } want := &CodespaceExport{ @@ -667,12 +667,12 @@ func TestCodespacesService_TriggerExport(t *testing.T) { } if !cmp.Equal(export, want) { - t.Errorf("Codespaces.TriggerExport returned %+v, want %+v", export, want) + t.Errorf("Codespaces.ExportCodespace returned %+v, want %+v", export, want) } - const methodName = "TriggerExport" + const methodName = "ExportCodespace" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.TriggerExport(ctx, "codespace_1") + got, resp, err := client.Codespaces.ExportCodespace(ctx, "codespace_1") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -680,7 +680,7 @@ func TestCodespacesService_TriggerExport(t *testing.T) { }) } -func TestCodespacesService_GetLatestExport(t *testing.T) { +func TestCodespacesService_GetLatestCodespaceExport(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -695,9 +695,9 @@ func TestCodespacesService_GetLatestExport(t *testing.T) { }) ctx := t.Context() - export, _, err := client.Codespaces.GetLatestExport(ctx, "codespace_1") + export, _, err := client.Codespaces.GetLatestCodespaceExport(ctx, "codespace_1") if err != nil { - t.Fatalf("Codespaces.GetLatestExport returned error: %v", err) + t.Fatalf("Codespaces.GetLatestCodespaceExport returned error: %v", err) } want := &CodespaceExport{ @@ -708,12 +708,12 @@ func TestCodespacesService_GetLatestExport(t *testing.T) { } if !cmp.Equal(export, want) { - t.Errorf("Codespaces.GetLatestExport returned %+v, want %+v", export, want) + t.Errorf("Codespaces.GetLatestCodespaceExport returned %+v, want %+v", export, want) } - const methodName = "GetLatestExport" + const methodName = "GetLatestCodespaceExport" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.GetLatestExport(ctx, "codespace_1") + got, resp, err := client.Codespaces.GetLatestCodespaceExport(ctx, "codespace_1") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From 4fb491a8811078e841eb75ca44a3d7fa5aabd85d Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Fri, 19 Dec 2025 11:36:51 +0000 Subject: [PATCH 6/7] rename method --- github/codespaces.go | 12 ++++++------ github/codespaces_test.go | 36 ++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/github/codespaces.go b/github/codespaces.go index 9f7e36dc15e..f87022f3c55 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -460,14 +460,14 @@ func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, re return codespace, resp, nil } -// CreateCodespace creates a new codespace, owned by the authenticated user. +// Create creates a new codespace, owned by the authenticated user. // // This method requires either RepositoryId OR a PullRequest but not both. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-for-the-authenticated-user // //meta:operation POST /user/codespaces -func (s *CodespacesService) CreateCodespace(ctx context.Context, opts *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) Create(ctx context.Context, opts *CodespaceCreateForUserOptions) (*Codespace, *Response, error) { u := "user/codespaces" req, err := s.client.NewRequest("POST", u, opts) if err != nil { @@ -483,12 +483,12 @@ func (s *CodespacesService) CreateCodespace(ctx context.Context, opts *Codespace return codespace, resp, nil } -// GetCodespace gets information about a user's codespace. +// Get gets information about a user's codespace. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#get-a-codespace-for-the-authenticated-user // //meta:operation GET /user/codespaces/{codespace_name} -func (s *CodespacesService) GetCodespace(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { +func (s *CodespacesService) Get(ctx context.Context, codespaceName string) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v", codespaceName) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -569,12 +569,12 @@ func (s *CodespacesService) GetLatestCodespaceExport(ctx context.Context, codesp return codespace, resp, nil } -// PublishCodespace publishes an unpublished codespace, creating a new repository and assigning it to the codespace. +// Publish publishes an unpublished codespace, creating a new repository and assigning it to the codespace. // // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-repository-from-an-unpublished-codespace // //meta:operation POST /user/codespaces/{codespace_name}/publish -func (s *CodespacesService) PublishCodespace(ctx context.Context, codespaceName string, opts *PublishCodespaceOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) Publish(ctx context.Context, codespaceName string, opts *PublishCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("user/codespaces/%v/publish", codespaceName) req, err := s.client.NewRequest("POST", u, opts) if err != nil { diff --git a/github/codespaces_test.go b/github/codespaces_test.go index efd090df3a3..9bffbf1a1ca 100644 --- a/github/codespaces_test.go +++ b/github/codespaces_test.go @@ -490,7 +490,7 @@ func TestCodespacesService_CreateFromPullRequest(t *testing.T) { }) } -func TestCodespacesService_CreateCodespace(t *testing.T) { +func TestCodespacesService_Create(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -514,12 +514,12 @@ func TestCodespacesService_CreateCodespace(t *testing.T) { } ctx := t.Context() - codespace, _, err := client.Codespaces.CreateCodespace( + codespace, _, err := client.Codespaces.Create( ctx, opt, ) if err != nil { - t.Fatalf("Codespaces.CreateCodespace returned error: %v", err) + t.Fatalf("Codespaces.Create returned error: %v", err) } want := &Codespace{ @@ -530,12 +530,12 @@ func TestCodespacesService_CreateCodespace(t *testing.T) { } if !cmp.Equal(codespace, want) { - t.Errorf("Codespaces.CreateCodespace returned %+v, want %+v", codespace, want) + t.Errorf("Codespaces.Create returned %+v, want %+v", codespace, want) } - const methodName = "CreateCodespace" + const methodName = "Create" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.CreateCodespace( + got, resp, err := client.Codespaces.Create( ctx, opt, ) @@ -546,7 +546,7 @@ func TestCodespacesService_CreateCodespace(t *testing.T) { }) } -func TestCodespacesService_GetCodespace(t *testing.T) { +func TestCodespacesService_Get(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -556,9 +556,9 @@ func TestCodespacesService_GetCodespace(t *testing.T) { }) ctx := t.Context() - codespace, _, err := client.Codespaces.GetCodespace(ctx, "codespace_1") + codespace, _, err := client.Codespaces.Get(ctx, "codespace_1") if err != nil { - t.Fatalf("Codespaces.GetCodespace returned error: %v", err) + t.Fatalf("Codespaces.Get returned error: %v", err) } want := &Codespace{ @@ -569,12 +569,12 @@ func TestCodespacesService_GetCodespace(t *testing.T) { } if !cmp.Equal(codespace, want) { - t.Errorf("Codespaces.GetCodespace returned %+v, want %+v", codespace, want) + t.Errorf("Codespaces.Get returned %+v, want %+v", codespace, want) } - const methodName = "GetCodespace" + const methodName = "Get" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.GetCodespace(ctx, "codespace_1") + got, resp, err := client.Codespaces.Get(ctx, "codespace_1") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -721,7 +721,7 @@ func TestCodespacesService_GetLatestCodespaceExport(t *testing.T) { }) } -func TestCodespacesService_PublishCodespace(t *testing.T) { +func TestCodespacesService_Publish(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -741,13 +741,13 @@ func TestCodespacesService_PublishCodespace(t *testing.T) { } ctx := t.Context() - repo, _, err := client.Codespaces.PublishCodespace( + repo, _, err := client.Codespaces.Publish( ctx, "codespace_1", opt, ) if err != nil { - t.Fatalf("Codespaces.PublishCodespace returned error: %v", err) + t.Fatalf("Codespaces.Publish returned error: %v", err) } want := &Codespace{ @@ -757,12 +757,12 @@ func TestCodespacesService_PublishCodespace(t *testing.T) { }, } if !cmp.Equal(repo, want) { - t.Errorf("Codespaces.PublishCodespace returned %+v, want %+v", repo, want) + t.Errorf("Codespaces.Publish returned %+v, want %+v", repo, want) } - const methodName = "PublishCodespace" + const methodName = "Publish" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Codespaces.PublishCodespace( + got, resp, err := client.Codespaces.Publish( ctx, "codespace_1", opt, From 1b244af907d35ed6689a3f67f5c071be81b7b7c7 Mon Sep 17 00:00:00 2001 From: Dhananjay Mishra Date: Fri, 19 Dec 2025 11:40:54 +0000 Subject: [PATCH 7/7] change opts to request and haspermissions to permissions --- github/codespaces.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/github/codespaces.go b/github/codespaces.go index f87022f3c55..bc8d617f34e 100644 --- a/github/codespaces.go +++ b/github/codespaces.go @@ -430,13 +430,13 @@ func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, r return nil, nil, err } - var hasPermission *CodespacePermissions - resp, err := s.client.Do(ctx, req, &hasPermission) + var permissions *CodespacePermissions + resp, err := s.client.Do(ctx, req, &permissions) if err != nil { return nil, resp, err } - return hasPermission, resp, nil + return permissions, resp, nil } // CreateFromPullRequest creates a codespace owned by the authenticated user for the specified pull request. @@ -444,9 +444,9 @@ func (s *CodespacesService) CheckPermissions(ctx context.Context, owner, repo, r // GitHub API docs: https://docs.github.com/rest/codespaces/codespaces#create-a-codespace-from-a-pull-request // //meta:operation POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces -func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, opts *CreateCodespaceOptions) (*Codespace, *Response, error) { +func (s *CodespacesService) CreateFromPullRequest(ctx context.Context, owner, repo string, pullNumber int, request *CreateCodespaceOptions) (*Codespace, *Response, error) { u := fmt.Sprintf("repos/%v/%v/pulls/%v/codespaces", owner, repo, pullNumber) - req, err := s.client.NewRequest("POST", u, opts) + req, err := s.client.NewRequest("POST", u, request) if err != nil { return nil, nil, err }